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"
21 // look for constraints like cexrp = cexrp + 1
22 static bool incVar (constraint c)
29 if (! isInc (c->expr ) )
32 llassert (c->expr->kind == binaryexpr);
33 t1 = constraintExprData_binaryExprGetExpr1 (c->expr->data);
34 if (constraintExpr_similar (c->lexpr, t1) )
41 static bool increments (constraint c,
44 llassert (incVar (c));
45 if (constraintExpr_similar (c->lexpr, var) )
51 static bool canGetForTimes ( exprNode forPred, exprNode forBody)
54 exprNode init, test, inc, t1, t2;
57 init = exprData_getTripleInit (forPred->edata);
58 test = exprData_getTripleTest (forPred->edata);
59 inc = exprData_getTripleInc (forPred->edata);
62 if (test->kind != XPR_PREOP)
65 tok = (exprData_getUopTok (test->edata));
66 if (!lltok_isMult (tok) )
71 //should check preop too
72 if (inc->kind != XPR_POSTOP)
77 tok = (exprData_getUopTok (inc->edata));
78 if (lltok_isInc_Op (tok) )
80 t1 = exprData_getUopNode (test->edata);
81 t2 = exprData_getUopNode (inc->edata);
82 if (sRef_sameName (t1->sref, t2->sref) )
90 static constraintList getLessThanConstraints (constraintList c)
94 ret = constraintList_new();
95 constraintList_elements (c, el)
97 if (el->ar == LT || el->ar == LTE)
99 ret = constraintList_add (ret, el);
102 end_constraintList_elements;
107 static constraintList getIncConstraints (constraintList c)
111 ret = constraintList_new();
112 constraintList_elements (c, el)
116 ret = constraintList_add (ret, el);
119 end_constraintList_elements;
124 constraintExpr getForTimes ( exprNode forPred, exprNode forBody)
127 exprNode init, test, inc, t1, t2;
128 constraintList ltCon;
129 constraintList incCon;
133 init = exprData_getTripleInit (forPred->edata);
134 test = exprData_getTripleTest (forPred->edata);
135 inc = exprData_getTripleInc (forPred->edata);
140 ltCon = getLessThanConstraints (test->trueEnsuresConstraints);
141 incCon = getIncConstraints (inc->ensuresConstraints);
143 DPRINTF(( message ("getForTimes: ltCon: %s from %s", constraintList_print(ltCon), constraintList_print(test->trueEnsuresConstraints) ) ));
145 DPRINTF(( message ("getForTimes: incCon: %s from %s", constraintList_print(incCon), constraintList_print(inc->ensuresConstraints) ) ));
147 constraintList_elements (ltCon, el)
149 constraintList_elements(incCon, el2)
151 if ( increments(el2, el->lexpr) )
153 DPRINTF(( message ("getForTimes: %s increments %s", constraint_print(el2), constraint_print(el) ) ));
154 return constraintExpr_copy (el->expr);
158 DPRINTF(( message ("getForTimes: %s doesn't increment %s", constraint_print(el2), constraint_print(el) ) ));
160 end_constraintList_elements;
163 end_constraintList_elements;
165 DPRINTF (( message ("getForTimes: %s %s resorting to ugly hack", exprNode_unparse(forPred), exprNode_unparse(forBody) ) ));
166 if (! canGetForTimes (forPred, forBody) )
172 if (test->kind != XPR_PREOP)
175 tok = (exprData_getUopTok (test->edata));
176 if (!lltok_isMult (tok) )
181 //should check preop too
182 if (inc->kind != XPR_POSTOP)
187 tok = (exprData_getUopTok (inc->edata));
188 if (lltok_isInc_Op (tok) )
190 t1 = exprData_getUopNode (test->edata);
191 t2 = exprData_getUopNode (inc->edata);
192 if (sRef_sameName (t1->sref, t2->sref) )
194 return (constraintExpr_makeMaxSetExpr (t1) );
202 static bool isInc (constraintExpr c)
205 if (c->kind == binaryexpr )
207 constraintExprBinaryOpKind binOP;
208 constraintExpr t1, t2;
209 t1 = constraintExprData_binaryExprGetExpr1 (c->data);
210 t2 = constraintExprData_binaryExprGetExpr2 (c->data);
212 binOP = constraintExprData_binaryExprGetOp (c->data);
214 if (constraintExpr_isLit (t2) && constraintExpr_getValue (t2) == 1 )
223 constraintExpr constraintExpr_searchAndAdd (constraintExpr c, constraintExpr find, constraintExpr add)
225 constraintExprKind kind;
228 DPRINTF(( message ("Doing constraintExpr_searchAndAdd %s %s %s ",
229 constraintExpr_unparse(c), constraintExpr_unparse(find), constraintExpr_unparse(add) ) ) );
231 if ( constraintExpr_similar (c, find) )
237 new = constraintExpr_makeAddConstraintExpr (c, add);
239 DPRINTF((message ("Replacing %s with %s",
240 constraintExpr_unparse(c), constraintExpr_unparse(new)
252 temp = constraintExprData_unaryExprGetExpr (c->data);
253 temp = constraintExpr_searchAndAdd (temp, find, add);
254 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
258 temp = constraintExprData_binaryExprGetExpr1 (c->data);
259 temp = constraintExpr_searchAndAdd (temp, find, add);
260 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
262 temp = constraintExprData_binaryExprGetExpr2 (c->data);
263 temp = constraintExpr_searchAndAdd (temp, find, add);
264 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
273 constraint constraint_searchAndAdd (constraint c, constraintExpr find, constraintExpr add)
276 llassert (constraint_search (c, find) );
277 DPRINTF(( message ("Doing constraint_searchAndAdd %s %s %s ",
278 constraint_print(c), constraintExpr_unparse(find), constraintExpr_unparse(add) ) ) );
280 c->lexpr = constraintExpr_searchAndAdd (c->lexpr, find, add);
281 c->expr = constraintExpr_searchAndAdd (c->expr, find, add);
283 c = constraint_simplify (c);
284 c = constraint_simplify (c);
290 constraintList constraintList_searchAndAdd (constraintList list,
291 constraintExpr find, constraintExpr add)
293 constraintList newConstraints;
296 newConstraints = constraintList_new();
298 constraintList_elements (list, el)
300 if (constraint_search (el, find) )
303 new = constraint_copy (el);
305 new = constraint_searchAndAdd (new, find, add);
306 newConstraints = constraintList_add (newConstraints, new);
307 DPRINTF (( (message ("Adding constraint %s ", constraint_print (new)) ) ));
311 end_constraintList_elements;
313 ret = constraintList_addList (list, newConstraints);
317 void doAdjust(exprNode e, exprNode forPred, exprNode forBody, constraintExpr iterations)
320 constraintList_elements (forBody->ensuresConstraints, el)
322 // look fro var = var + 1
325 DPRINTF((message ("Found inc variable constraint : %s", constraint_print (el) ) ));
326 forBody->requiresConstraints = constraintList_searchAndAdd(forBody->requiresConstraints, el->lexpr, iterations);
329 end_constraintList_elements;
332 void forLoopHeuristics( exprNode e, exprNode forPred, exprNode forBody)
334 exprNode init, test, inc, t1, t2, t3 ,t4;
336 constraintExpr iterations;
338 init = exprData_getTripleInit (forPred->edata);
339 test = exprData_getTripleTest (forPred->edata);
340 inc = exprData_getTripleInc (forPred->edata);
342 if (exprNode_isError (test) || exprNode_isError (inc) )
345 iterations = getForTimes (forPred, forBody );
349 doAdjust ( e, forPred, forBody, iterations);
357 /* DPRINTF (("Can't get for time ")); */
360 /* if (exprNode_isError(init) ) */
365 /* if (init->kind == XPR_ASSIGN) */
367 /* t1 = exprData_getOpA (init->edata); */
368 /* t2 = exprData_getOpB (init->edata); */
370 /* if (! (t1->kind == XPR_VAR) ) */
376 /* if (test->kind == XPR_FETCH) */
378 /* t3 = exprData_getPairA (test->edata); */
379 /* t4 = exprData_getPairB (test->edata); */
381 /* if (sRef_sameName(t1->sref, t4->sref) ) */
383 /* DPRINTF((message ("Found a for loop matching heuristic:%s", exprNode_unparse (forPred) ) )); */
384 /* con = constraint_makeEnsureLteMaxRead(t1, t3); */
385 /* forPred->ensuresConstraints = constraintList_add(forPred->ensuresConstraints, con); */
389 /* DPRINTF((message ("Didn't Find a for loop matching heuristic:%s %s and %s differ", exprNode_unparse (forPred), exprNode_unparse(t1), exprNode_unparse(t3) ) )); */