6 # include <ctype.h> /* for isdigit */
7 # include "lclintMacros.nf"
10 # include "cgrammar_tokens.h"
12 # include "exprChecks.h"
13 # include "aliasChecks.h"
14 # include "exprNodeSList.h"
15 # include "exprData.i"
18 int constraintExpr_getValue (constraintExpr expr)
20 if (expr->expr != NULL)
22 TPRINTF( ( "Not Implemented" ));
25 return (constraintTerm_getValue (expr->term) );
28 // returns 1 0 -1 like strcopy
29 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
33 value1 = constraintExpr_getValue(expr1);
34 value2 = constraintExpr_getValue(expr2);
46 bool constraintExpr_canCompare (constraintExpr expr1, constraintExpr expr2)
48 if (expr1->expr != NULL)
53 if (expr2->expr != NULL)
61 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2)
68 /*irst constraint is > only > => or == cosntraint can satify it */
69 if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
71 if (! constraintExpr_canCompare (expr1, expr2) )
74 if (constraintExpr_compare (expr2, expr1) >= 0)
80 TPRINTF(("case not handled"));
85 /*returns true if cosntraint post satifies cosntriant pre */
86 bool satifies (constraint pre, constraint post)
88 if (!constraintTerm_same(pre->lexpr->term, post->lexpr->term) )
92 if (post->expr == NULL)
95 return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
98 constraintExpr constraintExpr_simplify (constraintExpr expr)
101 expr->term = constraintTerm_simplify (expr->term);
102 if (expr->expr == NULL)
104 if ( (expr->term->kind == CONSTRAINTEXPR) && (expr->term->constrType == VALUE) )
106 expr->op = expr->term->value.constrExpr->op;
107 expr->expr = expr->term->value.constrExpr->expr;
108 expr->term = expr->term->value.constrExpr->term;
114 expr->expr = constraintExpr_simplify (expr->expr);
118 if ( (expr->term->kind == INTLITERAL) && (expr->expr->term->kind == INTLITERAL) )
120 DPRINTF( ("INTLITERAL MERGE " ));
122 DPRINTF ( (message ("Expression is %s ", constraintExpr_print (expr) ) ) );
124 if (expr->op == PLUS )
126 DPRINTF( (message ("Adding %d and %d ", expr->term->value.intlit,
127 expr->expr->term->value.intlit) ) );
128 expr->term->value.intlit += expr->expr->term->value.intlit;
130 else if (expr->op == MINUS )
132 expr->term->value.intlit -= expr->expr->term->value.intlit;
134 expr->op = expr->expr->op;
136 expr->expr = expr->expr->expr;
143 constraintExpr constraintExpr_add (constraintExpr e, constraintTerm term, constraintExprOp op)
148 while (p->expr != NULL)
154 p->expr = constraintExpr_alloc();
155 p->expr->term = term;
160 constraintExpr termMove (constraintExpr dst, constraintExpr src)
163 llassert (src->expr != NULL);
164 term = src->expr->term;
166 dst = constraintExpr_add (dst, term, MINUS);
168 if (src->op == MINUS)
169 dst = constraintExpr_add (dst, term, PLUS);
174 constraint solveforterm (constraint c)
178 while (p->expr != NULL)
180 DPRINTF( (message("Moving %s", constraintExpr_print (c->expr) ) ) );
181 c->expr = termMove(c->expr, p);
185 p->expr = p->expr->expr;
190 constraint solveforOther (constraint c)
194 while (p->expr != NULL)
196 TPRINTF( (message("Moving %s", constraintExpr_print (c->expr) ) ) );
197 c->lexpr = termMove(c->lexpr, p);
201 p->expr = p->expr->expr;
206 constraint constraint_simplify (constraint c)
208 c = solveforterm (c);
209 c->lexpr = constraintExpr_simplify (c->lexpr);
210 c->expr = constraintExpr_simplify (c->expr);
214 bool resolve (constraint c, constraintList p)
216 constraintList_elements (p, el)
218 if ( satifies (c, el) )
220 DPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
224 end_constraintList_elements;
225 DPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
230 constraintTerm constraintTerm_substituteTerm (constraintTerm term, constraintTerm oldterm, constraintExpr replacement)
232 if ( constraintTerm_similar (term, oldterm) )
234 // do the substitution
235 term->kind = CONSTRAINTEXPR;
236 term->value.constrExpr = constraintExpr_copy (replacement);
241 constraintExpr constraintExpr_substituteTerm (constraintExpr expr, constraintTerm oldterm, constraintExpr replacement)
243 expr->term = constraintTerm_substituteTerm (expr->term, oldterm, replacement);
244 if (expr->expr != NULL)
245 expr->expr = constraintExpr_substituteTerm (expr->expr, oldterm, replacement);
250 /* returns true if fileloc for term2 is closer to file for term1 than is term3*/
252 bool fileloc_closer (constraintTerm term1, constraintTerm term2, constraintTerm term3)
254 if ( fileloc_lessthan (term1->loc, term2->loc) )
256 if (fileloc_lessthan (term2->loc, term3->loc) )
258 llassert (fileloc_lessthan (term1->loc, term3->loc) );
267 if ( ! (fileloc_lessthan (term1->loc, term2->loc) ) )
269 if (!fileloc_lessthan (term2->loc, term3->loc) )
271 llassert (fileloc_lessthan (term3->loc, term1->loc) );
285 constraint constraint_substituteTerm (constraint c, constraint subs)
287 constraintTerm oldterm;
288 constraintExpr replacement;
290 llassert(subs->lexpr->expr == NULL);
293 oldterm = subs->lexpr->term;
294 replacement = subs->expr;
296 // Chessy hack assumes that subs always has the form g:1 = g:2 + expr
300 /*find out which value to substitute*/
301 TPRINTF((message ("doing substitute for %s and %s", constraint_print (c), constraint_print(subs) ) ) );
302 if ( constraintExpr_containsTerm (subs->expr, subs->lexpr->term) )
304 TPRINTF(("doing new stuff"));
305 if (fileloc_closer (c->lexpr->term, subs->expr->term, subs->lexpr->term) )
307 // use the other term
309 new = constraint_copy (subs);
310 new = solveforOther(new);
311 oldterm = new->expr->term;
312 replacement = new->lexpr;
316 c->lexpr = constraintExpr_substituteTerm (c->lexpr, oldterm, replacement);
317 c->expr = constraintExpr_substituteTerm (c->expr, oldterm, replacement);
321 constraint substitute (constraint c, constraintList p)
323 constraintList_elements (p, el)
326 if (constraint_hasTerm (c, el->lexpr->term) )
328 llassert(el->lexpr->expr == NULL);
329 DPRINTF((message ("doing substitute for %s", constraint_print (c) ) ) );
331 c = constraint_substituteTerm (c, el);
332 DPRINTF((message ("substituted constraint is now %s", constraint_print (c) ) ) );
333 // c->lexpr = constraintExpr_copy (el->expr);
334 c = constraint_simplify(c);
335 c = constraint_simplify(c);
336 c = constraint_simplify(c);
340 end_constraintList_elements;
342 c = constraint_simplify(c);
347 constraintList reflectChanges (constraintList pre2, constraintList post1)
352 ret = constraintList_new();
353 constraintList_elements (pre2, el)
355 if (!resolve (el, post1) )
357 temp = substitute (el, post1);
358 ret = constraintList_add (ret, temp);
360 } end_constraintList_elements;
365 bool constraintExpr_containsTerm (constraintExpr p, constraintTerm term)
367 TPRINTF(("constraintExpr_containsTerm"));
371 if (constraintTerm_similar (p->term, term) )
377 message ("constraintExpr_hasTerm returned fallse for %s %S",
378 constraint_print(c), constraintTerm_print(term)
385 /*check if rvalue side has term*/
386 bool constraintExpr_hasTerm (constraint c, constraintTerm term)
392 if (constraintTerm_same (p->term, term) )
398 message ("constraintExpr_hasTerm returned fallse for %s %S",
399 constraint_print(c), constraintTerm_print(term)
405 constraintExpr solveEq (constraint c, constraintTerm t)
408 c = constraint_copy (c);
409 DPRINTF(("\ndoing solveEq\n"));
410 if (! constraintTerm_same (c->expr->term, t) )
412 DPRINTF ( (message ("\n\nconstraintTerms: %s %s not same ", constraintTerm_print(c->expr->term),
413 constraintTerm_print(t) )
419 while (p->expr != NULL)
421 DPRINTF( (message("\n\nMoving %s", constraintExpr_print (c->expr) ) ) );
422 c->lexpr = termMove(c->lexpr, p);
423 p->expr = p->expr->expr;
430 constraint updateConstraint (constraint c, constraintList p)
432 TPRINTF(("start updateConstraints"));
433 constraintList_elements (p, el)
436 if (constraintTerm_same(c->lexpr->term, el->lexpr->term) )
443 if (constraintExpr_hasTerm (el, c->lexpr->term) )
445 constraintExpr solve;
447 solve = solveEq (el, c->lexpr->term);
450 c->lexpr = constraintExpr_copy (solve);
451 c = constraint_simplify(c);
458 end_constraintList_elements;
459 c = constraint_simplify(c);
461 DPRINTF(("end updateConstraints"));
466 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1)
470 ret = constraintList_new();
471 constraintList_elements (pre2, el)
473 if (!resolve (el, post1) )
475 temp = substitute (el, post1);
477 ret = constraintList_add (ret, temp);
479 } end_constraintList_elements;
484 void mergeResolve (exprNode parent, exprNode child1, exprNode child2)
487 DPRINTF( (message ("magically merging constraint into parent:%s for children: %s and %s", exprNode_unparse (parent), exprNode_unparse (child1), exprNode_unparse(child2) )
489 if (exprNode_isError (child1) || exprNode_isError(child2) )
491 if (exprNode_isError (child1) && !exprNode_isError(child2) )
493 parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
494 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
495 DPRINTF((message ("Copied child constraints: pre: %s and post: %s",
496 constraintList_print( child2->requiresConstraints),
497 constraintList_print (child2->ensuresConstraints)
504 llassert(exprNode_isError(child2) );
505 parent->requiresConstraints = constraintList_new();
506 parent->ensuresConstraints = constraintList_new();
511 llassert(!exprNode_isError (child1) && ! exprNode_isError(child2) );
513 DPRINTF( (message ("Child constraints are %s %s and %s %s",
514 constraintList_print (child1->requiresConstraints),
515 constraintList_print (child1->ensuresConstraints),
516 constraintList_print (child2->requiresConstraints),
517 constraintList_print (child2->ensuresConstraints)
520 parent->requiresConstraints = constraintList_new();
521 parent->ensuresConstraints = constraintList_new();
523 parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
525 temp = reflectChanges (child2->requiresConstraints, child1->ensuresConstraints);
526 parent->requiresConstraints = constraintList_addList (parent->requiresConstraints, temp);
529 temp = reflectChangesEnsures (child1->ensuresConstraints, child2->ensuresConstraints);
530 // temp = constraintList_copy (child1->ensuresConstraints);
533 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
534 parent->ensuresConstraints = constraintList_addList (parent->ensuresConstraints, temp);
536 DPRINTF( (message ("Parent constraints are %s and %s ",
537 constraintList_print (parent->requiresConstraints),
538 constraintList_print (parent->ensuresConstraints)