PIPS
eval.c
Go to the documentation of this file.
1 /*
2 
3  $Id: eval.c 23065 2016-03-02 09:05:50Z coelho $
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 
28 #ifndef lint
29 char vcid_syntax_eval[] = "%A% ($Date: 1998/04/14 21:28:15 $, ) version $Revision: 16236 $, got on %D%, %T% [%P%].\n Copyright (c) École des Mines de Paris Proprietary.";
30 #endif /* lint */
31 
32 /* This file contains a set of functions to evaluate integer constant
33 expressions. The algorithm is built on a recursive analysis of the
34 expression structure. Lower level functions are called until basic atoms
35 are reached. The succes of basic atom evaluation depend on the atom
36 type:
37 
38 reference: right now, the evaluation fails because we do not compute
39 predicates on variables.
40 
41 call: a call to a user function is not evaluated. a call to an intrinsic
42 function is successfully evaluated if arguments can be evaluated. a call
43 to a constant function is evaluated if its basic type is integer.
44 
45 range: a range is not evaluated. */
46 
47 #include "genC.h"
48 #include "linear.h"
49 #include "ri.h"
50 #include "parser_private.h"
51 #include "syntax.h"
52 #include "toklex.h"
53 
54 
56 expression e;
57 {
58  return(EvalSyntax(expression_syntax(e)));
59 }
60 
61 
62 
64 syntax s;
65 {
66  value v;
67 
68  switch (syntax_tag(s)) {
70  case is_syntax_range:
71  v = make_value_unknown();
72  break;
73  case is_syntax_call:
74  v = EvalCall((syntax_call(s)));
75  break;
76  case is_syntax_cast:
80  case is_syntax_va_arg:
81  v = make_value_unknown();
82  break;
83  default:
84  ParserError("EvalExpression", "cas default\n");
85  }
86 
87  return(v);
88 }
89 
90 
91 
92 /* only calls to constant, symbolic or intrinsic functions might be
93 evaluated. recall that intrinsic functions are not known. */
94 
96 call c;
97 {
98  value vout, vin;
99  entity f;
100 
101  f = call_function(c);
102  vin = entity_initial(f);
103 
104  switch (value_tag(vin)) {
105  case is_value_intrinsic:
106  vout = EvalIntrinsic(f, call_arguments(c));
107  break;
108  case is_value_constant:
109  vout = EvalConstant((value_constant(vin)));
110  break;
111  case is_value_symbolic:
113  break;
114  case is_value_unknown:
115  /* it might be an intrinsic function */
116  vout = EvalIntrinsic(f, call_arguments(c));
117  break;
118  case is_value_code:
119  vout = make_value_unknown();
120  break;
121  default:
122  ParserError("EvalCall", "case default\n");
123  }
124 
125  return(vout);
126 }
127 
128 
129 
131 constant c;
132 {
133  return((constant_int_p(c)) ?
135  constant_int(c))) :
137 }
138 
139 
140 
141 /* this function tries to evaluate a call to an intrinsic function.
142 right now, we only try to evaluate unary and binary intrinsic functions,
143 ie. fortran operators.
144 
145 e is the intrinsic function.
146 
147 la is the list of arguments.
148 */
149 
151 entity e;
152 cons *la;
153 {
154  value v;
155  int token;
156 
157  if ((token = IsUnaryOperator(e)) > 0)
158  v = EvalUnaryOp(token, la);
159  else if ((token = IsBinaryOperator(e)) > 0)
160  v = EvalBinaryOp(token, la);
161  else
162  v = make_value_unknown();
163 
164  return(v);
165 }
166 
167 
168 
170 int t;
171 cons *la;
172 {
173  value vout, v;
174  int arg;
175 
176  pips_assert("EvalUnaryOpt", la != NIL);
177  v = EvalExpression(EXPRESSION(CAR(la)));
179  arg = constant_int(value_constant(v));
180  else
181  return(v);
182 
183  if (t == TK_MINUS) {
184  constant_int(value_constant(v)) = -arg;
185  vout = v;
186  }
187  else {
188  gen_free(v);
189  vout = make_value_unknown();
190  }
191 
192  return(vout);
193 }
194 
196 int t;
197 cons *la;
198 {
199  value v;
200  int argl, argr;
201 
202  pips_assert("EvalBinaryOpt", la != NIL);
203  v = EvalExpression(EXPRESSION(CAR(la)));
205  argl = constant_int(value_constant(v));
206  gen_free(v);
207  }
208  else
209  return(v);
210 
211  la = CDR(la);
212  pips_assert("EvalBinaryOpt", la != NIL);
213  v = EvalExpression(EXPRESSION(CAR(la)));
215  argr = constant_int(value_constant(v));
216  }
217  else
218  return(v);
219 
220  switch (t) {
221  case TK_MINUS:
222  constant_int(value_constant(v)) = argl-argr;
223  break;
224  case TK_PLUS:
225  constant_int(value_constant(v)) = argl+argr;
226  break;
227  case TK_STAR:
228  constant_int(value_constant(v)) = argl*argr;
229  break;
230  case TK_SLASH:
231  if (argr != 0)
232  constant_int(value_constant(v)) = argl/argr;
233  else
234  FatalError("EvalBinaryOp", "zero divide\n");
235  break;
236  case TK_POWER:
237  if (argr >= 0)
238  constant_int(value_constant(v)) = ipow(argl,argr);
239  else {
240  gen_free(v);
241  v = make_value_unknown();
242  }
243  break;
244  default:
245  debug(9, "EvalBinaryOp", "pas encore d'evaluation\n");
246  gen_free(v);
247  v = make_value_unknown();
248  }
249 
250  return(v);
251 }
252 
253 
254 
256 entity e;
257 {
258  int token;
259 
260  if (strcmp(entity_local_name(e), "--") == 0)
261  token = TK_MINUS;
262  else if (strcmp(entity_local_name(e), ".NOT.") == 0)
263  token = TK_NOT;
264  else
265  token = -1;
266 
267  return(token);
268 }
269 
270 
271 
273 entity e;
274 {
275  int token;
276 
277  if (strcmp(entity_local_name(e), "-") == 0)
278  token = TK_MINUS;
279  else if (strcmp(entity_local_name(e), "+") == 0)
280  token = TK_PLUS;
281  else if (strcmp(entity_local_name(e), "*") == 0)
282  token = TK_STAR;
283  else if (strcmp(entity_local_name(e), "/") == 0)
284  token = TK_SLASH;
285  else if (strcmp(entity_local_name(e), "**") == 0)
286  token = TK_POWER;
287  else if (strcmp(entity_local_name(e), ".EQ.") == 0)
288  token = TK_EQ;
289  else if (strcmp(entity_local_name(e), ".NE.") == 0)
290  token = TK_NE;
291  else if (strcmp(entity_local_name(e), ".EQV") == 0)
292  token = TK_EQV;
293  else if (strcmp(entity_local_name(e), ".NEQV") == 0)
294  token = TK_NEQV;
295  else if (strcmp(entity_local_name(e), ".GT.") == 0)
296  token = TK_GT;
297  else if (strcmp(entity_local_name(e), ".LT.") == 0)
298  token = TK_LT;
299  else if (strcmp(entity_local_name(e), ".GE.") == 0)
300  token = TK_GE;
301  else if (strcmp(entity_local_name(e), ".LE.") == 0)
302  token = TK_LE;
303  else if (strcmp(entity_local_name(e), ".OR.") == 0)
304  token = TK_OR;
305  else if (strcmp(entity_local_name(e), ".AND.") == 0)
306  token = TK_AND;
307  else
308  token = -1;
309 
310  return(token);
311 }
312 
313 
314 
315 int ipow(vg, vd)
316 int vg, vd;
317 {
318  /* FI: see arithmetique library */
319  int i = 1;
320 
321  pips_assert("ipow", vd >= 0);
322 
323  while (vd-- > 0)
324  i *= vg;
325 
326  return(i);
327 }
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
value make_value_unknown(void)
Definition: ri.c:2847
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
value MakeValueLitteral()
Definition: bootstrap.c:5680
void gen_free(gen_chunk *obj)
version without shared_pointers.
Definition: genClib.c:992
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
int IsUnaryOperator(entity e)
Definition: eval.c:632
value EvalBinaryOp(int t, list la)
t defines the operator and la is a list to two sub-expressions.
Definition: eval.c:385
value EvalConstant(constant c)
Constant c is returned as field of value v.
Definition: eval.c:235
value EvalCall(call c)
only calls to constant, symbolic or intrinsic functions might be evaluated.
Definition: eval.c:170
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
value EvalIntrinsic(entity e, list la)
This function tries to evaluate a call to an intrinsic function.
Definition: eval.c:290
value EvalSyntax(syntax s)
Definition: eval.c:113
value EvalUnaryOp(int t, list la)
Definition: eval.c:349
int IsBinaryOperator(entity e)
FI: These string constants are defined in ri-util.h and the tokens in ri-util/operator....
Definition: eval.c:660
int ipow(int vg, int vd)
FI: such a function should exist in Linear/arithmetique.
Definition: eval.c:769
#define value_tag(x)
Definition: ri.h:3064
#define value_constant(x)
Definition: ri.h:3073
#define syntax_tag(x)
Definition: ri.h:2727
#define call_function(x)
Definition: ri.h:709
#define symbolic_constant(x)
Definition: ri.h:2599
#define constant_int(x)
Definition: ri.h:850
@ is_constant_int
Definition: ri.h:817
@ is_value_intrinsic
Definition: ri.h:3034
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
@ 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 value_constant_p(x)
Definition: ri.h:3071
#define value_symbolic(x)
Definition: ri.h:3070
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define constant_int_p(x)
Definition: ri.h:848
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
#define entity_initial(x)
Definition: ri.h:2796
#define TK_STAR
Definition: splitc.c:812
#define TK_SLASH
Definition: splitc.c:813
#define TK_PLUS
Definition: splitc.c:810
#define TK_EQ
Definition: splitc.c:791
#define TK_MINUS
Definition: splitc.c:811
#define TK_AND
Definition: splitc.c:816
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define TK_GT
Definition: syn_yacc.c:345
#define TK_NOT
Definition: syn_yacc.c:350
#define TK_POWER
Definition: syn_yacc.c:363
#define TK_EQV
Definition: syn_yacc.c:343
#define TK_NEQV
Definition: syn_yacc.c:349
#define TK_GE
Definition: syn_yacc.c:344
#define TK_LT
Definition: syn_yacc.c:347
#define TK_LE
Definition: syn_yacc.c:346
#define TK_NE
Definition: syn_yacc.c:348
#define TK_OR
Definition: syn_yacc.c:351
#define FatalError(f, m)
Definition: syntax-local.h:56
char vcid_syntax_eval[]
Definition: eval.c:29
bool ParserError(const char *f, const char *m)
Definition: parser.c:116