7 # include <ctype.h> /* for isdigit */
8 # include "lclintMacros.nf"
10 # include "cgrammar.h"
11 # include "cgrammar_tokens.h"
13 # include "exprChecks.h"
14 # include "aliasChecks.h"
15 # include "exprNodeSList.h"
17 # include "exprDataQuite.i"
19 /*@access constraint, exprNode @*/
21 /*@access constraintExpr @*/
23 static bool isInc (/*@observer@*/ constraintExpr c) /*@*/
26 llassert(constraintExpr_isDefined(c) );
27 if (c->kind == binaryexpr )
29 constraintExprBinaryOpKind binOP;
30 constraintExpr t1, t2;
31 t1 = constraintExprData_binaryExprGetExpr1 (c->data);
32 t2 = constraintExprData_binaryExprGetExpr2 (c->data);
34 binOP = constraintExprData_binaryExprGetOp (c->data);
36 if (constraintExpr_isLit (t2) && constraintExpr_getValue (t2) == 1 )
47 // look for constraints like cexrp = cexrp + 1
48 static bool incVar (/*@notnull@*/ constraint c) /*@*/
55 if (! isInc (c->expr ) )
58 llassert (constraintExpr_isDefined(c->expr) );
59 llassert (c->expr->kind == binaryexpr);
61 t1 = constraintExprData_binaryExprGetExpr1 (c->expr->data);
62 if (constraintExpr_similar (c->lexpr, t1) )
67 /*@noaccess constraintExpr @*/
70 static bool increments (/*@observer@*/ constraint c,
71 /*@observer@*/ constraintExpr var)
73 llassert(constraint_isDefined(c) );
75 if (constraint_isUndefined(c) )
80 llassert (incVar (c));
81 if (constraintExpr_similar (c->lexpr, var) )
87 static bool canGetForTimes (/*@notnull@*/ exprNode forPred, /*@notnull@*/ exprNode forBody)
90 exprNode init, test, inc, t1, t2;
93 llassert(exprNode_isDefined (forPred) );
94 llassert(exprNode_isDefined (forBody) );
96 init = exprData_getTripleInit (forPred->edata);
97 test = exprData_getTripleTest (forPred->edata);
98 inc = exprData_getTripleInc (forPred->edata);
100 llassert(exprNode_isDefined(test) );
102 if (exprNode_isUndefined(test) )
107 llassert(exprNode_isDefined(inc) );
109 if (exprNode_isUndefined(inc) )
114 if (test->kind != XPR_PREOP)
117 tok = (exprData_getUopTok (test->edata));
118 if (!lltok_isMult (tok) )
123 //should check preop too
124 if (inc->kind != XPR_POSTOP)
129 tok = (exprData_getUopTok (inc->edata));
130 if (lltok_isInc_Op (tok) )
132 t1 = exprData_getUopNode (test->edata);
133 t2 = exprData_getUopNode (inc->edata);
134 llassert(exprNode_isDefined(t2) && exprNode_isDefined(t2) );
136 if (exprNode_isUndefined(t1) || exprNode_isUndefined(t2) )
141 if (sRef_sameName (t1->sref, t2->sref) )
149 static /*@only@*/ constraintList getLessThanConstraints (/*@observer@*/ constraintList c)
153 ret = constraintList_makeNew();
154 constraintList_elements (c, el)
156 llassert(constraint_isDefined(el));
157 if ( constraint_isUndefined(el) )
160 if (el->ar == LT || el->ar == LTE)
163 temp = constraint_copy(el);
165 ret = constraintList_add (ret, temp);
168 end_constraintList_elements;
173 static /*@only@*/ constraintList getIncConstraints (/*@observer@*/ constraintList c)
177 ret = constraintList_makeNew();
178 constraintList_elements (c, el)
183 temp = constraint_copy(el);
184 ret = constraintList_add (ret, temp);
187 end_constraintList_elements;
192 static /*@only@*/ constraintExpr getForTimes (/*@notnull@*/ exprNode forPred, /*@notnull@*/ exprNode forBody)
195 exprNode init, test, inc, t1, t2;
196 constraintList ltCon;
197 constraintList incCon;
202 init = exprData_getTripleInit (forPred->edata);
203 test = exprData_getTripleTest (forPred->edata);
204 inc = exprData_getTripleInc (forPred->edata);
206 llassert(exprNode_isDefined(test) );
207 llassert(exprNode_isDefined(inc) );
209 ltCon = getLessThanConstraints (test->trueEnsuresConstraints);
210 incCon = getIncConstraints (inc->ensuresConstraints);
212 DPRINTF(( message ("getForTimes: ltCon: %s from %s", constraintList_print(ltCon), constraintList_print(test->trueEnsuresConstraints) ) ));
214 DPRINTF(( message ("getForTimes: incCon: %s from %s", constraintList_print(incCon), constraintList_print(inc->ensuresConstraints) ) ));
216 constraintList_elements (ltCon, el)
218 constraintList_elements(incCon, el2)
220 if ( increments(el2, el->lexpr) )
222 DPRINTF(( message ("getForTimes: %s increments %s", constraint_print(el2), constraint_print(el) ) ));
223 ret = constraintExpr_copy (el->expr);
224 constraintList_free(ltCon);
225 constraintList_free(incCon);
230 DPRINTF(( message ("getForTimes: %s doesn't increment %s", constraint_print(el2), constraint_print(el) ) ));
232 end_constraintList_elements;
235 end_constraintList_elements;
237 constraintList_free(ltCon);
238 constraintList_free(incCon);
240 DPRINTF (( message ("getForTimes: %s %s resorting to ugly hack", exprNode_unparse(forPred), exprNode_unparse(forBody) ) ));
241 if (! canGetForTimes (forPred, forBody) )
247 if (test->kind != XPR_PREOP)
250 tok = (exprData_getUopTok (test->edata));
251 if (!lltok_isMult (tok) )
256 //should check preop too
257 if (inc->kind != XPR_POSTOP)
262 tok = (exprData_getUopTok (inc->edata));
263 if (lltok_isInc_Op (tok) )
265 t1 = exprData_getUopNode (test->edata);
266 t2 = exprData_getUopNode (inc->edata);
267 if (sRef_sameName (t1->sref, t2->sref) )
269 return (constraintExpr_makeMaxSetExpr (t1) );
276 /*@access constraintExpr @*/
278 static /*@only@*/ constraintExpr constraintExpr_searchAndAdd (/*@only@*/ constraintExpr c, /*@observer@*/ constraintExpr find, /*@observer@*/ constraintExpr add)
280 constraintExprKind kind;
283 DPRINTF(( message ("Doing constraintExpr_searchAndAdd %s %s %s ",
284 constraintExpr_unparse(c), constraintExpr_unparse(find), constraintExpr_unparse(add) ) ) );
286 if ( constraintExpr_similar (c, find) )
294 cPrint = constraintExpr_unparse(c);
297 new = constraintExpr_makeAddExpr (c, constraintExpr_copy(add) );
299 DPRINTF((message ("Replacing %q with %q",
300 cPrint, constraintExpr_unparse(new)
312 temp = constraintExprData_unaryExprGetExpr (c->data);
313 temp = constraintExpr_searchAndAdd (constraintExpr_copy(temp), find, add);
314 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
318 temp = constraintExprData_binaryExprGetExpr1 (c->data);
319 temp = constraintExpr_searchAndAdd (constraintExpr_copy(temp), find, add);
320 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
322 temp = constraintExprData_binaryExprGetExpr2 (c->data);
323 temp = constraintExpr_searchAndAdd (constraintExpr_copy(temp), find, add);
324 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
333 /*@noaccess constraintExpr @*/
335 static constraint constraint_searchAndAdd (/*@returned@*/ constraint c, /*@observer@*/ constraintExpr find, /*@observer@*/ constraintExpr add)
338 llassert (constraint_search (c, find) );
339 DPRINTF(( message ("Doing constraint_searchAndAdd %s %s %s ",
340 constraint_print(c), constraintExpr_unparse(find), constraintExpr_unparse(add) ) ) );
342 c->lexpr = constraintExpr_searchAndAdd (c->lexpr, find, add);
343 c->expr = constraintExpr_searchAndAdd (c->expr, find, add);
345 c = constraint_simplify (c);
346 c = constraint_simplify (c);
352 /*@only@*/ static constraintList constraintList_searchAndAdd (/*@returned@*/ constraintList list,
353 /*@observer@*/ constraintExpr find, /*@observer@*/ constraintExpr add)
355 constraintList newConstraints;
358 newConstraints = constraintList_makeNew();
360 constraintList_elements (list, el)
362 if (constraint_search (el, find) )
365 new = constraint_copy (el);
367 new = constraint_searchAndAdd (new, find, add);
368 DPRINTF (( (message ("Adding constraint %s ", constraint_print (new)) ) ));
369 newConstraints = constraintList_add (newConstraints, new);
373 end_constraintList_elements;
375 ret = constraintList_addListFree (list, newConstraints);
379 static void doAdjust(/*@unused@*/ exprNode e, /*@unused@*/ exprNode forPred, /*@observer@*/ exprNode forBody, /*@observer@*/ constraintExpr iterations)
382 constraintList_elements (forBody->ensuresConstraints, el)
384 // look for var = var + 1
387 DPRINTF((message ("Found inc variable constraint : %s", constraint_print (el) ) ));
388 forBody->requiresConstraints = constraintList_searchAndAdd(forBody->requiresConstraints, el->lexpr, iterations);
391 end_constraintList_elements;
394 void forLoopHeuristics( exprNode e, exprNode forPred, exprNode forBody)
396 exprNode init, test, inc;
398 constraintExpr iterations;
400 init = exprData_getTripleInit (forPred->edata);
401 test = exprData_getTripleTest (forPred->edata);
402 inc = exprData_getTripleInc (forPred->edata);
404 if (exprNode_isError (test) || exprNode_isError (inc) )
407 iterations = getForTimes (forPred, forBody );
409 if (iterations != NULL)
411 doAdjust ( e, forPred, forBody, iterations);
412 constraintExpr_free(iterations);
419 /* DPRINTF (("Can't get for time ")); */
422 /* if (exprNode_isError(init) ) */
427 /* if (init->kind == XPR_ASSIGN) */
429 /* t1 = exprData_getOpA (init->edata); */
430 /* t2 = exprData_getOpB (init->edata); */
432 /* if (! (t1->kind == XPR_VAR) ) */
438 /* if (test->kind == XPR_FETCH) */
440 /* t3 = exprData_getPairA (test->edata); */
441 /* t4 = exprData_getPairB (test->edata); */
443 /* if (sRef_sameName(t1->sref, t4->sref) ) */
445 /* DPRINTF((message ("Found a for loop matching heuristic:%s", exprNode_unparse (forPred) ) )); */
446 /* con = constraint_makeEnsureLteMaxRead(t1, t3); */
447 /* forPred->ensuresConstraints = constraintList_add(forPred->ensuresConstraints, con); */
451 /* DPRINTF((message ("Didn't Find a for loop matching heuristic:%s %s and %s differ", exprNode_unparse (forPred), exprNode_unparse(t1), exprNode_unparse(t3) ) )); */