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 "exprData.i"
18 # include "exprDataQuite.i"
20 /*@access constraint, exprNode @*/
22 /*@access constraintExpr @*/
24 static bool isInc (constraintExpr c) /*@*/
27 llassert(constraintExpr_isDefined(c) );
28 if (c->kind == binaryexpr )
30 constraintExprBinaryOpKind binOP;
31 constraintExpr t1, t2;
32 t1 = constraintExprData_binaryExprGetExpr1 (c->data);
33 t2 = constraintExprData_binaryExprGetExpr2 (c->data);
35 binOP = constraintExprData_binaryExprGetOp (c->data);
37 if (constraintExpr_isLit (t2) && constraintExpr_getValue (t2) == 1 )
48 // look for constraints like cexrp = cexrp + 1
49 static bool incVar (/*@notnull@*/ constraint c) /*@*/
56 if (! isInc (c->expr ) )
59 llassert (constraintExpr_isDefined(c->expr) );
60 llassert (c->expr->kind == binaryexpr);
62 t1 = constraintExprData_binaryExprGetExpr1 (c->expr->data);
63 if (constraintExpr_similar (c->lexpr, t1) )
68 /*@noaccess constraintExpr @*/
71 static bool increments (constraint c,
74 llassert(constraint_isDefined(c) );
76 if (constraint_isUndefined(c) )
81 llassert (incVar (c));
82 if (constraintExpr_similar (c->lexpr, var) )
88 static bool canGetForTimes (/*@notnull@*/ exprNode forPred, /*@notnull@*/ exprNode forBody)
91 exprNode init, test, inc, t1, t2;
94 llassert(exprNode_isDefined (forPred) );
95 llassert(exprNode_isDefined (forBody) );
97 init = exprData_getTripleInit (forPred->edata);
98 test = exprData_getTripleTest (forPred->edata);
99 inc = exprData_getTripleInc (forPred->edata);
101 llassert(exprNode_isDefined(test) );
103 if (exprNode_isUndefined(test) )
108 llassert(exprNode_isDefined(inc) );
110 if (exprNode_isUndefined(inc) )
115 if (test->kind != XPR_PREOP)
118 tok = (exprData_getUopTok (test->edata));
119 if (!lltok_isMult (tok) )
124 //should check preop too
125 if (inc->kind != XPR_POSTOP)
130 tok = (exprData_getUopTok (inc->edata));
131 if (lltok_isInc_Op (tok) )
133 t1 = exprData_getUopNode (test->edata);
134 t2 = exprData_getUopNode (inc->edata);
135 llassert(exprNode_isDefined(t2) && exprNode_isDefined(t2) );
137 if (exprNode_isUndefined(t1) || exprNode_isUndefined(t2) )
142 if (sRef_sameName (t1->sref, t2->sref) )
150 static constraintList getLessThanConstraints (constraintList c)
154 ret = constraintList_makeNew();
155 constraintList_elements (c, el)
157 llassert(constraint_isDefined(el));
158 if ( constraint_isUndefined(el) )
161 if (el->ar == LT || el->ar == LTE)
163 ret = constraintList_add (ret, el);
166 end_constraintList_elements;
171 static constraintList getIncConstraints (constraintList c)
175 ret = constraintList_makeNew();
176 constraintList_elements (c, el)
180 ret = constraintList_add (ret, el);
183 end_constraintList_elements;
188 constraintExpr getForTimes (/*@notnull@*/ exprNode forPred, /*@notnull@*/ exprNode forBody)
191 exprNode init, test, inc, t1, t2;
192 constraintList ltCon;
193 constraintList incCon;
197 init = exprData_getTripleInit (forPred->edata);
198 test = exprData_getTripleTest (forPred->edata);
199 inc = exprData_getTripleInc (forPred->edata);
201 llassert(exprNode_isDefined(test) );
202 llassert(exprNode_isDefined(inc) );
204 ltCon = getLessThanConstraints (test->trueEnsuresConstraints);
205 incCon = getIncConstraints (inc->ensuresConstraints);
207 DPRINTF(( message ("getForTimes: ltCon: %s from %s", constraintList_print(ltCon), constraintList_print(test->trueEnsuresConstraints) ) ));
209 DPRINTF(( message ("getForTimes: incCon: %s from %s", constraintList_print(incCon), constraintList_print(inc->ensuresConstraints) ) ));
211 constraintList_elements (ltCon, el)
213 constraintList_elements(incCon, el2)
215 if ( increments(el2, el->lexpr) )
217 DPRINTF(( message ("getForTimes: %s increments %s", constraint_print(el2), constraint_print(el) ) ));
218 return constraintExpr_copy (el->expr);
222 DPRINTF(( message ("getForTimes: %s doesn't increment %s", constraint_print(el2), constraint_print(el) ) ));
224 end_constraintList_elements;
227 end_constraintList_elements;
229 DPRINTF (( message ("getForTimes: %s %s resorting to ugly hack", exprNode_unparse(forPred), exprNode_unparse(forBody) ) ));
230 if (! canGetForTimes (forPred, forBody) )
236 if (test->kind != XPR_PREOP)
239 tok = (exprData_getUopTok (test->edata));
240 if (!lltok_isMult (tok) )
245 //should check preop too
246 if (inc->kind != XPR_POSTOP)
251 tok = (exprData_getUopTok (inc->edata));
252 if (lltok_isInc_Op (tok) )
254 t1 = exprData_getUopNode (test->edata);
255 t2 = exprData_getUopNode (inc->edata);
256 if (sRef_sameName (t1->sref, t2->sref) )
258 return (constraintExpr_makeMaxSetExpr (t1) );
265 /*@access constraintExpr @*/
267 constraintExpr constraintExpr_searchAndAdd (constraintExpr c, constraintExpr find, constraintExpr add)
269 constraintExprKind kind;
272 DPRINTF(( message ("Doing constraintExpr_searchAndAdd %s %s %s ",
273 constraintExpr_unparse(c), constraintExpr_unparse(find), constraintExpr_unparse(add) ) ) );
275 if ( constraintExpr_similar (c, find) )
281 new = constraintExpr_makeAddConstraintExpr (c, add);
283 DPRINTF((message ("Replacing %s with %s",
284 constraintExpr_unparse(c), constraintExpr_unparse(new)
296 temp = constraintExprData_unaryExprGetExpr (c->data);
297 temp = constraintExpr_searchAndAdd (temp, find, add);
298 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
302 temp = constraintExprData_binaryExprGetExpr1 (c->data);
303 temp = constraintExpr_searchAndAdd (temp, find, add);
304 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
306 temp = constraintExprData_binaryExprGetExpr2 (c->data);
307 temp = constraintExpr_searchAndAdd (temp, find, add);
308 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
317 /*@noaccess constraintExpr @*/
319 constraint constraint_searchAndAdd (constraint c, constraintExpr find, constraintExpr add)
322 llassert (constraint_search (c, find) );
323 DPRINTF(( message ("Doing constraint_searchAndAdd %s %s %s ",
324 constraint_print(c), constraintExpr_unparse(find), constraintExpr_unparse(add) ) ) );
326 c->lexpr = constraintExpr_searchAndAdd (c->lexpr, find, add);
327 c->expr = constraintExpr_searchAndAdd (c->expr, find, add);
329 c = constraint_simplify (c);
330 c = constraint_simplify (c);
336 constraintList constraintList_searchAndAdd (constraintList list,
337 constraintExpr find, constraintExpr add)
339 constraintList newConstraints;
342 newConstraints = constraintList_makeNew();
344 constraintList_elements (list, el)
346 if (constraint_search (el, find) )
349 new = constraint_copy (el);
351 new = constraint_searchAndAdd (new, find, add);
352 DPRINTF (( (message ("Adding constraint %s ", constraint_print (new)) ) ));
353 newConstraints = constraintList_add (newConstraints, new);
357 end_constraintList_elements;
359 ret = constraintList_addList (list, newConstraints);
363 static void doAdjust(/*@unused@*/ exprNode e, /*@unused@*/ exprNode forPred, exprNode forBody, constraintExpr iterations)
366 constraintList_elements (forBody->ensuresConstraints, el)
368 // look for var = var + 1
371 DPRINTF((message ("Found inc variable constraint : %s", constraint_print (el) ) ));
372 forBody->requiresConstraints = constraintList_searchAndAdd(forBody->requiresConstraints, el->lexpr, iterations);
375 end_constraintList_elements;
378 void forLoopHeuristics( exprNode e, exprNode forPred, exprNode forBody)
380 exprNode init, test, inc;
382 constraintExpr iterations;
384 init = exprData_getTripleInit (forPred->edata);
385 test = exprData_getTripleTest (forPred->edata);
386 inc = exprData_getTripleInc (forPred->edata);
388 if (exprNode_isError (test) || exprNode_isError (inc) )
391 iterations = getForTimes (forPred, forBody );
395 doAdjust ( e, forPred, forBody, iterations);
403 /* DPRINTF (("Can't get for time ")); */
406 /* if (exprNode_isError(init) ) */
411 /* if (init->kind == XPR_ASSIGN) */
413 /* t1 = exprData_getOpA (init->edata); */
414 /* t2 = exprData_getOpB (init->edata); */
416 /* if (! (t1->kind == XPR_VAR) ) */
422 /* if (test->kind == XPR_FETCH) */
424 /* t3 = exprData_getPairA (test->edata); */
425 /* t4 = exprData_getPairB (test->edata); */
427 /* if (sRef_sameName(t1->sref, t4->sref) ) */
429 /* DPRINTF((message ("Found a for loop matching heuristic:%s", exprNode_unparse (forPred) ) )); */
430 /* con = constraint_makeEnsureLteMaxRead(t1, t3); */
431 /* forPred->ensuresConstraints = constraintList_add(forPred->ensuresConstraints, con); */
435 /* DPRINTF((message ("Didn't Find a for loop matching heuristic:%s %s and %s differ", exprNode_unparse (forPred), exprNode_unparse(t1), exprNode_unparse(t3) ) )); */