]> andersk Git - splint.git/blame - src/constraintExpr.c
Added support for or constraints.
[splint.git] / src / constraintExpr.c
CommitLineData
3aaedf88 1/*
2** constraintExpr.c
3*/
4
5//#define DEBUGPRINT 1
6
7# include "lclintMacros.nf"
8# include "basic.h"
9# include "cgrammar.h"
10# include "cgrammar_tokens.h"
11
12# include "exprChecks.h"
13# include "aliasChecks.h"
14# include "exprNodeSList.h"
15
16
17# include "exprData.i"
18# include "exprDataQuite.i"
19
20
21/*@-czechfcns@*/
22
23#include "constraintExpr.h"
24
25
26
3aaedf88 27constraintExpr constraintExpr_makeMaxSetConstraintExpr (constraintExpr c);
28
29bool constraintExpr_isLit (constraintExpr expr)
30{
dc92450f 31 llassert (expr != NULL);
3aaedf88 32
33 if (expr->kind == term)
34 {
35 constraintTerm term = constraintExprData_termGetTerm (expr->data);
36 if (constraintTerm_isIntLiteral (term) )
37 {
38 return TRUE;
39 }
40
41 }
42 return FALSE;
43}
44
45
46constraintExpr constraintExpr_propagateConstants (constraintExpr expr,
47 /*@out@*/ bool * propagate,
48 /*@out@*/ int *literal)
49{
50 constraintExpr expr1;
51 constraintExpr expr2;
52 bool propagate1, propagate2;
53 int literal1, literal2;
54
55 propagate1 = FALSE;
56 propagate2 = FALSE;
57
58 literal1 = 0;
59 literal2 = 0;
60
61 *propagate = FALSE;
62 *literal = 0;
63
dc92450f 64 llassert (expr != NULL);
3aaedf88 65
66 // we simplify unaryExpr else where
67 if (expr->kind == unaryExpr)
68 return expr;
69
70 if (expr->kind == term)
71 return expr;
72
73 if (constraintExpr_isLit (expr) )
74 return expr;
75
76 BPRINTF( (message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr) ) ) );
77
78 expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
79 expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
80
81 expr1 = constraintExpr_propagateConstants (expr1, &propagate1, &literal1);
82 expr2 = constraintExpr_propagateConstants (expr2, &propagate2, &literal2);
83
84 expr->data = constraintExprData_binaryExprSetExpr1 (expr->data, expr1);
85 expr->data = constraintExprData_binaryExprSetExpr2 (expr->data, expr2);
86
87 *propagate = propagate1 || propagate2;
88 *literal = literal1 + literal2;
89
90 if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
91 {
92 int t1, t2;
93 t1 = constraintExpr_getValue (expr1);
94 t2 = constraintExpr_getValue (expr2);
95 *propagate = FALSE;
96 if (constraintExprData_binaryExprGetOp (expr->data) == PLUS )
97 return (constraintExpr_makeIntLiteral ( (t1+t2) ));
98 else if (constraintExprData_binaryExprGetOp (expr->data) == MINUS)
99 return (constraintExpr_makeIntLiteral ( (t1-t2) ));
100 else
101 llassert(FALSE);
102 }
103
104 if (constraintExpr_isLit (expr1) )
105 {
106 /*@i334*/
107 /*handle MINUS case right */
108 *propagate = TRUE;
109 *literal += constraintExpr_getValue (expr1);
110 return expr2;
111 }
112
113
114 if (constraintExpr_isLit (expr2) )
115 {
116 *propagate = TRUE;
117
118 if (constraintExprData_binaryExprGetOp (expr->data) == PLUS )
119 *literal += constraintExpr_getValue (expr2);
120 else
121 *literal -= constraintExpr_getValue (expr2);
122 return expr1;
123 }
124
125
126
127 BPRINTF( (message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr) ) ) );
128
129 return expr;
130}
131
132constraintExpr constraintExpr_combineConstants (constraintExpr expr )
133{
134 bool propagate;
135 int literal;
136
137 BPRINTF ( (message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
138 expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
139
140
141 if (propagate)
142 {
143 constraintExpr ret;
144
145 if (literal != 0)
146 {
147 ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
148 expr = ret;
149 }
150 }
151 BPRINTF ( (message ("After combine %s", constraintExpr_unparse(expr) ) ) );
152 return expr;
153}
dc92450f 154/*@special@*/
155constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
3aaedf88 156{
157 constraintExpr ret;
158 ret = dmalloc (sizeof (*ret) );
159 ret->kind = term;
160 ret->data = NULL;
161 return ret;
162}
163
164
165constraintExpr constraintExpr_copy (constraintExpr expr)
166{
167 constraintExpr ret;
168 ret = constraintExpr_alloc();
169 ret->kind = expr->kind;
170 ret->data = constraintExprData_copy (expr->data, expr->kind);
171 return ret;
172}
173
174
175constraintExpr oldconstraintExpr_makeTermExprNode (exprNode e)
176{
177 constraintExpr ret;
178 constraintTerm t;
179 ret = constraintExpr_alloc();
180 ret->kind = term;
181 ret->data = dmalloc (sizeof *(ret->data) );
182 t = constraintTerm_makeExprNode (e);
183 ret->data = constraintExprData_termSetTerm (ret->data, t);
184 return ret;
185}
186
187constraintExpr constraintExpr_makeExprNode (exprNode e)
188{
189 sRef s;
190 constraintExpr ret, ce1, ce2;
191 exprData data;
192 exprNode t, t1, t2;
193 lltok tok;
194
195
dc92450f 196 llassert (e != NULL);
3aaedf88 197
198 data = e->edata;
199
200 switch (e->kind)
201 {
202 case XPR_SIZEOF:
203 t = exprData_getSingle (data);
204 s = exprNode_getSref (t);
205 if (sRef_isFixedArray(s) )
206 {
207 int size;
208
dc92450f 209 size = (int) sRef_getArraySize(s);
3aaedf88 210 ret = constraintExpr_makeIntLiteral (size);
211 }
212 else
213 {
214 BPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
215 ret = oldconstraintExpr_makeTermExprNode (e);
216 }
217 break;
218
219 case XPR_OP:
220 BPRINTF ((message ("Examining operation %s", exprNode_unparse (e) ) ) );
221 t1 = exprData_getOpA (data);
222 t2 = exprData_getOpB (data);
223 tok = exprData_getOpTok (data);
224
225 if (lltok_isPlus_Op (tok) || lltok_isMinus_Op (tok) )
226 {
227 ce1 = constraintExpr_makeExprNode (t1);
228 ce2 = constraintExpr_makeExprNode (t2);
229 ret = constraintExpr_parseMakeBinaryOp (ce1, tok, ce2);
230 }
231 else
232 {
233 ret = oldconstraintExpr_makeTermExprNode (e);
234 }
235 break;
236 case XPR_PARENS:
237 t = exprData_getUopNode (data);
238 ret = constraintExpr_makeExprNode (t);
239 break;
240
241 case XPR_PREOP:
242 t = exprData_getUopNode (data);
243 tok = exprData_getUopTok (data);
244 if (lltok_isInc_Op (tok) )
245 {
246 constraintExpr temp;
247 temp = constraintExpr_makeExprNode(t);
248 ret = constraintExpr_makeIncConstraintExpr(temp);
249 }
250 else if (lltok_isDec_Op (tok) )
251 {
252 constraintExpr temp;
253 temp = constraintExpr_makeExprNode(t);
254 ret = constraintExpr_makeDecConstraintExpr(temp);
255 }
256 else
257 ret = oldconstraintExpr_makeTermExprNode (e);
258 break;
259
260 case XPR_POSTOP:
261 t = exprData_getUopNode (data);
262 ret = constraintExpr_makeExprNode (t);
263 break;
470b7798 264 case XPR_CAST:
265 t = exprData_getCastNode (data);
266 ret = constraintExpr_makeExprNode (t);
267 break;
268 case XPR_COMMA:
269 t = exprData_getPairA(data);
270 ret = constraintExpr_makeExprNode(t);
3aaedf88 271 default:
272 ret = oldconstraintExpr_makeTermExprNode (e);
273
274 }
275 return ret;
276}
277
278
279constraintExpr constraintExpr_makeTermExprNode (exprNode e)
280{
281 return oldconstraintExpr_makeTermExprNode(e); //constraintExpr_makeExprNode (e);
282}
283
284
285constraintExpr constraintExpr_makeTermsRef (sRef s)
286{
287 constraintExpr ret;
288 constraintTerm t;
289 ret = constraintExpr_alloc();
290 ret->kind = term;
291 ret->data = dmalloc (sizeof *(ret->data) );
292 t = constraintTerm_makesRef (s);
293 ret->data = constraintExprData_termSetTerm (ret->data, t);
294 return ret;
295}
296
dc92450f 297constraintExpr constraintExpr_makeUnaryOp (void) /*@allocates result->data@*/
3aaedf88 298{
299 constraintExpr ret;
300 ret = constraintExpr_alloc();
301 ret->kind = unaryExpr;
302 ret->data = dmalloc ( sizeof *(ret->data) );
303 return ret;
304}
305
306constraintExpr constraintExpr_makeUnaryOpConstraintExpr (constraintExpr cexpr)
307{
308 constraintExpr ret;
309 ret = constraintExpr_makeUnaryOp();
310 ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
311 return ret;
312}
313
314constraintExpr constraintExpr_makeMaxSetConstraintExpr (constraintExpr c)
315{
316 constraintExpr ret;
317 ret = constraintExpr_makeUnaryOpConstraintExpr (c);
318 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
319 return ret;
320}
321
322constraintExpr constraintExpr_makeUnaryOpExprNode (exprNode expr)
323{
324 constraintExpr ret;
325 constraintExpr sub;
326 sub = constraintExpr_makeExprNode (expr);
327 ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
328 return ret;
329}
330
331
332
333constraintExpr constraintExpr_makeSRefUnaryOp (sRef s, constraintExprUnaryOpKind op)
334{
335 constraintExpr ret;
336 constraintExpr t;
337
338 t = constraintExpr_makeTermsRef (s);
339 ret = constraintExpr_makeUnaryOpConstraintExpr (t);
340 ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
341 return ret;
342}
343
470b7798 344constraintExpr constraintExpr_makeSRefMaxRead(sRef s)
345{
346 return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
347}
348
3aaedf88 349constraintExpr constraintExpr_makeSRefMaxset (sRef s)
350{
351 return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
352}
353
354constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
355{
356 constraintExpr ret;
357 ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
358
359 switch (op.tok)
360 {
361 case QMAXSET:
362 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
363 break;
364 case QMAXREAD:
365 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
366 break;
367 default:
dc92450f 368 llfatalbug(message("Unhandled Operation in Constraint") );
3aaedf88 369 }
370 return ret;
371}
372
373constraintExpr constraintExpr_makeMaxSetExpr (exprNode expr)
374{
375 constraintExpr ret;
376 ret = constraintExpr_makeExprNode (expr);
377
378 ret = constraintExpr_makeMaxSetConstraintExpr (ret);
379
dc92450f 380 llassert (ret != NULL);
3aaedf88 381 return ret;
382}
383
384constraintExpr constraintExpr_makeMaxReadExpr (exprNode expr)
385{
386 constraintExpr ret;
387 ret = constraintExpr_makeUnaryOpExprNode(expr);
388 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
389 return ret;
390}
391
392constraintExpr constraintExpr_makeMinSetExpr (exprNode expr)
393{
394 constraintExpr ret;
395 ret = constraintExpr_makeUnaryOpExprNode(expr);
396 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINSET);
397 return ret;
398}
399
400constraintExpr constraintExpr_makeMinReadExpr (exprNode expr)
401{
402 constraintExpr ret;
403 ret = constraintExpr_makeUnaryOpExprNode(expr);
404 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
405 return ret;
406}
407
408
409constraintExpr constraintExpr_makeValueExpr (exprNode expr)
410{
411 constraintExpr ret;
412 ret = constraintExpr_makeExprNode (expr);
413 return ret;
414}
415
416constraintExpr constraintExpr_makeIntLiteral (int i)
417{
418 constraintExpr ret;
419 constraintTerm t;
420 ret = constraintExpr_alloc();
421 ret->kind = term;
422 ret->data = dmalloc (sizeof *(ret->data) );
423 t = constraintTerm_makeIntLiteral (i);
424 ret->data = constraintExprData_termSetTerm (ret->data, t);
425 return ret;
426}
427
428
429constraintExpr constraintExpr_makeValueInt (int i)
430{
431 return constraintExpr_makeIntLiteral (i);
432}
433
434static constraintExpr constraintExpr_makeBinaryOp (void)
435{
436 constraintExpr ret;
437 ret = constraintExpr_alloc();
438 ret->kind = binaryexpr;
439 ret->data = dmalloc ( sizeof *(ret->data) );
440 ret->data = constraintExprData_binaryExprSetOp (ret->data, PLUS);
441 return ret;
442}
443
444
445constraintExpr constraintExpr_makeBinaryOpConstraintExpr (constraintExpr expr1,constraintExpr expr2)
446
447{
448 constraintExpr ret;
449 ret = constraintExpr_makeBinaryOp();
450 ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
451 ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
452 return ret;
453}
454
455constraintExpr constraintExpr_parseMakeBinaryOp (constraintExpr expr1, lltok op, constraintExpr expr2)
456{
457 constraintExpr ret;
458 ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
459 if (op.tok == TPLUS)
460 ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
461 else if (op.tok == TMINUS)
462 ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
463 else
464 {
465 llassert(FALSE);
466 }
467 return ret;
468}
469
470constraintExpr constraintExpr_makeBinaryOpExprNode (exprNode expr1, exprNode expr2)
471{
472 constraintExpr ret;
473 constraintExpr sub1, sub2;
474 sub1 = constraintExpr_makeTermExprNode (expr1);
475 sub2 = constraintExpr_makeTermExprNode (expr2);
476 ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
477 return ret;
478}
479
480constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (constraintExpr expr, int literal)
481{
482 constraintExpr ret;
483 constraintExpr constExpr;
484
485 constExpr = constraintExpr_makeIntLiteral (literal);
486 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
487 ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
488 return ret;
489}
490
491constraintExpr constraintExpr_makeDecConstraintExpr (constraintExpr expr)
492{
493 constraintExpr ret;
494 constraintExpr inc;
495
496 inc = constraintExpr_makeIntLiteral (1);
497 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
498 ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
499 return ret;
500}
501
502constraintExpr constraintExpr_makeAddConstraintExpr (constraintExpr expr, constraintExpr add)
503{
504 constraintExpr ret;
505
506 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, add);
507
508 ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
509
510 return ret;
511}
512
513constraintExpr constraintExpr_makeIncConstraintExpr (constraintExpr expr)
514{
515 constraintExpr ret;
516 constraintExpr inc;
517
518 inc = constraintExpr_makeIntLiteral (1);
519 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
520 ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
521 return ret;
522}
523
524cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
525{
526 switch (op)
527 {
528 case MAXSET:
529 return message("MAXSET");
530 case MINSET:
531 return message("MINSET");
532 case MAXREAD:
533 return message("MAXREAD");
534 case MINREAD:
535 return message("MINREAD");
536 default:
537 llassert(FALSE);
538 return message ("<(Unary OP OTHER>");
539 }
540}
541
542
543cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
544{
545
546 switch (op)
547 {
548 case PLUS:
549 return message("+");
550 case MINUS:
551 return message("-");
dc92450f 552
553 default:
554 llassert(FALSE);
555 return message ("<binary OP Unknown>");
3aaedf88 556 }
3aaedf88 557}
558
559bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
560{
561 constraintExprKind kind;
562
563 llassert (expr1 != NULL);
564 llassert (expr2 != NULL);
565 if (expr1->kind != expr2->kind)
566 return FALSE;
567
568 kind = expr1->kind;
569
570 switch (kind)
571 {
572 case term:
573 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
574 constraintExprData_termGetTerm(expr2->data) );
dc92450f 575 /*@noreached@*/ break;
3aaedf88 576
577 case unaryExpr:
578 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
579 return FALSE;
580
581 return (constraintExpr_similar (
582 constraintExprData_unaryExprGetExpr (expr1->data),
583 constraintExprData_unaryExprGetExpr (expr2->data)
584 ));
585
586 case binaryexpr:
587 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
588 return FALSE;
589
590 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
591 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
592 return FALSE;
593
594 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
595 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
596 return FALSE;
597 else
598 return TRUE;
599 /*@notreached@*/
600 break;
601
602 default:
603 llassert(FALSE);
604 return FALSE;
605 }
606 /*@notreached@*/
607 return FALSE;
608}
609
610bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
611{
612 constraintExprKind kind;
613
614 llassert (expr1 != NULL);
615 llassert (expr2 != NULL);
616 if (expr1->kind != expr2->kind)
617 return FALSE;
618
619 kind = expr1->kind;
620
621 switch (kind)
622 {
623 case term:
624 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
625 constraintExprData_termGetTerm(expr2->data) );
dc92450f 626 /*@notreached@*/ break;
3aaedf88 627
628 case unaryExpr:
629 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
630 return FALSE;
631
632 return (constraintExpr_same (
633 constraintExprData_unaryExprGetExpr (expr1->data),
634 constraintExprData_unaryExprGetExpr (expr2->data)
635 ));
636
637
638 case binaryexpr:
639 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
640 return FALSE;
641
642 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
643 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
644 return FALSE;
645
646 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
647 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
648 return FALSE;
649 else
650 return TRUE;
dc92450f 651 /*@notreached@*/ break;
3aaedf88 652
653 default:
654 llassert(FALSE);
655 return FALSE;
656 }
657
658 /*@notreached@*/
659 BADEXIT;
660}
661
662bool constraintExpr_search (constraintExpr c, constraintExpr old)
663{
664 bool ret = FALSE;
665 constraintExprKind kind;
666 constraintExpr temp;
667
668 if ( constraintExpr_similar (c, old) )
669 {
670 #warning mem leak
671 DPRINTF((message ("Found %s",
672 constraintExpr_unparse(old)
673 )));
674 return TRUE;
675 }
676
677 kind = c->kind;
678
679 switch (kind)
680 {
681 case term:
682 break;
683 case unaryExpr:
684 temp = constraintExprData_unaryExprGetExpr (c->data);
685 ret = ret || constraintExpr_search (temp, old);
686 break;
687 case binaryexpr:
688
689 temp = constraintExprData_binaryExprGetExpr1 (c->data);
690 ret = ret || constraintExpr_search(temp, old);
691
692 temp = constraintExprData_binaryExprGetExpr2 (c->data);
693 ret = ret || constraintExpr_search(temp, old);
694 break;
695 default:
696 llassert(FALSE);
697 }
698 return ret;
699
700}
701
702
703constraintExpr constraintExpr_searchandreplace (constraintExpr c, constraintExpr old, constraintExpr new )
704{
705 constraintExprKind kind;
706 constraintExpr temp;
707
708 if ( constraintExpr_similar (c, old) )
709 {
710 #warning mem leak
470b7798 711 DPRINTF((message ("Replacing %s with %s",
3aaedf88 712 constraintExpr_unparse(old), constraintExpr_unparse(new)
713 )));
714 return constraintExpr_copy (new);
715 }
716
717 kind = c->kind;
718
719 switch (kind)
720 {
721 case term:
722 break;
723 case unaryExpr:
724 temp = constraintExprData_unaryExprGetExpr (c->data);
725 temp = constraintExpr_searchandreplace (temp, old, new);
726 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
727 break;
728 case binaryexpr:
729
730 temp = constraintExprData_binaryExprGetExpr1 (c->data);
731 temp = constraintExpr_searchandreplace (temp, old, new);
732 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
733
734 temp = constraintExprData_binaryExprGetExpr2 (c->data);
735 temp = constraintExpr_searchandreplace (temp, old, new);
736 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
737 break;
738 default:
739 llassert(FALSE);
740 }
741 return c;
742
743}
744
745constraintExpr constraintExpr_simplifyChildren (constraintExpr c)
746{
747 constraintExprKind kind;
748 constraintExpr temp;
749
750 kind = c->kind;
751
752 switch (kind)
753 {
754 case term:
755 break;
756 case unaryExpr:
757 temp = constraintExprData_unaryExprGetExpr (c->data);
758 temp = constraintExpr_simplify (temp);
759 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
760 break;
761 case binaryexpr:
762 BPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
763 temp = constraintExprData_binaryExprGetExpr1 (c->data);
764 temp = constraintExpr_simplify (temp);
765
766 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
767
768 temp = constraintExprData_binaryExprGetExpr2 (c->data);
769 temp = constraintExpr_simplify (temp);
770
771 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
772 break;
773 default:
774 llassert(FALSE);
775 }
776 return c;
777
778}
779
780
781constraintExpr constraintExpr_setFileloc (constraintExpr c, fileloc loc)
782{
783 constraintTerm t;
784 constraintExpr temp;
785
dc92450f 786 llassert(c != NULL);
3aaedf88 787
788 switch (c->kind)
789 {
790 case term:
791 t = constraintExprData_termGetTerm (c->data);
792 t = constraintTerm_setFileloc (t, loc);
793 c->data = constraintExprData_termSetTerm (c->data, t);
794 break;
795 case binaryexpr:
796
797 temp = constraintExprData_binaryExprGetExpr1 (c->data);
798 temp = constraintExpr_setFileloc (temp, loc);
799 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
800
801 temp = constraintExprData_binaryExprGetExpr2 (c->data);
802 temp = constraintExpr_setFileloc (temp, loc);
803 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
804 break;
805 case unaryExpr:
806 temp = constraintExprData_unaryExprGetExpr (c->data);
807 temp = constraintExpr_setFileloc (temp, loc);
808 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
809 break;
810 }
811 return c;
812}
813
814constraintExpr constraintExpr_simplifybinaryExpr (constraintExpr c)
815{
816 constraintExpr e1, e2;
817
818 e1 = constraintExprData_binaryExprGetExpr1 (c->data);
819 e2 = constraintExprData_binaryExprGetExpr2 (c->data);
820
821 if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
822 {
823 int i;
824
825 i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
826
827 c = constraintExpr_makeIntLiteral (i);
828
829 }
830 return c;
831}
832
833
834constraintExpr constraintExpr_subtractExpr (constraintExpr expr, constraintExpr addent)
835{
836 constraintExpr new;
837
838 BPRINTF ( (message ("Doing subtraceTerm simplification") ) );
839
840 new = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
841 new->data = constraintExprData_binaryExprSetOp (new->data, MINUS);
842 return new;
843}
844
845constraintExpr constraintExpr_addExpr (constraintExpr expr, constraintExpr addent)
846{
847 constraintExpr new;
848
849 BPRINTF ( (message ("Doing addTerm simplification") ) );
850
851 new = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
852 new->data = constraintExprData_binaryExprSetOp (new->data, PLUS);
853 return new;
854}
855
856constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, constraintExpr expr)
857{
858 constraintExpr expr1, expr2;
859 constraintExprBinaryOpKind op;
860
861 if (lexpr->kind != binaryexpr)
862 return expr;
863
864 expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
865 expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
866 op = constraintExprData_binaryExprGetOp (lexpr->data);
867
868
869 // if (constraintExpr_canGetValue (expr2) )
870 {
871 #warning make sure this works
872
873 lexpr->kind = expr1->kind;
874 lexpr->data = constraintExprData_copy (expr1->data, expr1->kind);
875
876
877 if (op == PLUS)
878 expr = constraintExpr_subtractExpr (expr, expr2);
879 else
880 expr = constraintExpr_addExpr (expr, expr2);
881
882 return expr;
883 }
884 expr = constraintExpr_solveBinaryExpr (expr1, expr);
885
886 expr = constraintExpr_solveBinaryExpr (expr2, expr);
887 return expr;
888}
889
890constraintExpr constraintExpr_simplifyunaryExpr (constraintExpr c)
891{
892 constraintExpr exp;
893
894 llassert (c->kind == unaryExpr);
895
896 BPRINTF ( (message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
897
898 if ( (constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
899 (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
900 {
901 return c;
902 }
903 // pattern mxr ( var + const) = mxr(var) - const
904
905 exp = constraintExprData_unaryExprGetExpr (c->data);
906
907 if (exp->kind == term)
908 {
909 constraintTerm cterm;
910
911 cterm = constraintExprData_termGetTerm (exp->data);
912
913 if (constraintTerm_isStringLiteral(cterm) )
914 {
915 cstring val;
916 val = constraintTerm_getStringLiteral (cterm);
917 if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
918 {
919 return constraintExpr_makeIntLiteral (strlen (val) );
920 }
921 if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
922 {
923 return constraintExpr_makeIntLiteral (strlen (val) );
924 }
925 BADEXIT;
926 }
927 return c;
928 }
929
930 if (exp->kind != binaryexpr)
931 return c;
932
933 if (constraintExprData_binaryExprGetOp (exp->data) == PLUS )
934 {
935
936 // if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) )
937 {
938
939 constraintExpr temp, temp2, new;
940
941 DPRINTF ( (message ("Doing fancy simplification") ) );
942
943 temp = constraintExprData_binaryExprGetExpr2 (exp->data);
944
945 temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
946 c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
947
948
949
950 new = constraintExpr_subtractExpr (c, temp);
951
952 DPRINTF ( (message ("Done fancy simplification:%s", constraintExpr_unparse (new) ) ) );
953
954 c = new;
955 }
956 }
957
958 DPRINTF ( (message ("Done simplification:%s", constraintExpr_unparse (c) ) ) );
959 return c;
960}
961
962
963constraintExpr constraintExpr_simplify (constraintExpr c)
964{
965 constraintExprKind kind;
966 constraintTerm t;
967
968
969 BPRINTF ( (message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );
970
971 c = constraintExpr_simplifyChildren (c);
972 c = constraintExpr_combineConstants (c);
973 c = constraintExpr_simplifyChildren (c);
974
975 kind = c->kind;
976
977 switch (kind)
978 {
979 case term:
980 t = constraintExprData_termGetTerm (c->data);
981 t = constraintTerm_simplify (t);
982 c->data = constraintExprData_termSetTerm (c->data, t);
983 break;
984 case unaryExpr:
985 c = constraintExpr_simplifyunaryExpr (c);
986 break;
987 case binaryexpr:
988 c = constraintExpr_simplifybinaryExpr (c);
989 break;
990 default:
991 llassert(FALSE);
992 }
993 return c;
994
995}
996
997cstring constraintExpr_unparse (constraintExpr ex)
998{
999 cstring st;
1000 constraintExprKind kind;
1001
1002 llassert (ex != NULL);
1003
1004 kind = ex->kind;
1005
1006 switch (kind)
1007 {
1008 case term:
1009 st = message ("(%s) ", constraintTerm_print (constraintExprData_termGetTerm(ex->data) ) );
1010 break;
1011 case unaryExpr:
1012 st = message ("%s (%s)",
1013 constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data)
1014 ),
1015 constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1016 );
1017 break;
1018 case binaryexpr:
1019 st = message ("(%s) %s (%s)",
1020 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1021 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1022 ),
1023 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1024 );
1025 break;
1026 default:
1027 llassert(FALSE);
1028 st = message ("error");
1029
1030 }
1031
1032 DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1033 return st;
1034}
1035
1036constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/ constraintExpr expr, exprNodeList arglist)
1037{
1038 constraintTerm Term;
1039 constraintExprKind kind;
1040 constraintExpr expr1, expr2;
1041 constraintExprData data;
1042 llassert (expr != NULL);
1043
1044 data = expr->data;
1045
1046 kind = expr->kind;
1047
1048 switch (kind)
1049 {
1050 case term:
1051 Term = constraintExprData_termGetTerm(data);
1052 Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1053 data = constraintExprData_termSetTerm(data, Term);
1054 break;
1055 case unaryExpr:
1056 expr1 = constraintExprData_unaryExprGetExpr (data);
1057 expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1058 data = constraintExprData_unaryExprSetExpr (data, expr1);
1059 break;
1060 case binaryexpr:
1061 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1062 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1063
1064 expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1065 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1066 expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1067 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1068
1069 break;
1070 default:
1071 llassert(FALSE);
1072 data = NULL;
1073 }
1074 return expr;
1075}
1076
1077constraintExpr constraintExpr_doSRefFixConstraintParam (/*@returned@*/ constraintExpr expr, exprNodeList arglist)
1078{
1079 constraintExprKind kind;
1080 constraintExpr expr1, expr2;
1081 constraintExprData data;
1082 llassert (expr != NULL);
1083
1084 data = expr->data;
1085
1086 kind = expr->kind;
1087
1088 switch (kind)
1089 {
1090 case term:
1091 expr = constraintTerm_doSRefFixConstraintParam (expr, arglist);
1092 break;
1093 case unaryExpr:
1094 expr1 = constraintExprData_unaryExprGetExpr (data);
1095 expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1096 data = constraintExprData_unaryExprSetExpr (data, expr1);
1097 break;
1098 case binaryexpr:
1099 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1100 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1101
1102 expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1103 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1104 expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1105 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1106
1107 break;
1108 default:
1109 llassert(FALSE);
1110 data = NULL;
1111 }
1112 return expr;
1113}
1114
1115constraintExpr constraintExpr_doFixResult (/*@returned@*/ constraintExpr expr, exprNode fcnCall)
1116{
1117 constraintExprKind kind;
1118 constraintExpr expr1, expr2;
1119 constraintExprData data;
1120 llassert (expr != NULL);
1121
1122 data = expr->data;
1123
1124 kind = expr->kind;
1125
1126 switch (kind)
1127 {
1128 case term:
1129 expr = constraintTerm_doFixResult (expr, fcnCall);
1130 break;
1131 case unaryExpr:
1132 expr1 = constraintExprData_unaryExprGetExpr (data);
1133 expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1134 data = constraintExprData_unaryExprSetExpr (data, expr1);
1135 break;
1136 case binaryexpr:
1137 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1138 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1139
1140 expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1141 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1142 expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1143 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1144
1145 break;
1146 default:
1147 llassert(FALSE);
1148 data = NULL;
1149 }
1150 return expr;
1151}
1152
dc92450f 1153cstring constraintExpr_print (constraintExpr expr) /*@*/
3aaedf88 1154{
1155 return constraintExpr_unparse(expr);
1156}
1157
dc92450f 1158bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
3aaedf88 1159{
1160 cstring t;
1161
1162 t = constraintExpr_unparse(expr);
1163
470b7798 1164 return ((bool)strstr (t, "MAXSET") );
3aaedf88 1165}
1166
1167
1168
1169 /*returns 1 0 -1 like strcmp
1170 1 => expr1 > expr2
1171 0 => expr1 == expr2
1172 -1 => expr1 < expr2
1173 */
1174int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1175{
1176 int value1, value2;
1177
1178 if (constraintExpr_similar (expr1, expr2) )
1179 {
1180 return 0;
1181 }
1182 value1 = constraintExpr_getValue(expr1);
1183 value2 = constraintExpr_getValue(expr2);
1184
1185 if (value1 > value2)
1186 return 1;
1187
1188 if (value1 == value2)
1189 return 0;
1190
1191 else
1192 return -1;
1193}
1194
1195int constraintExpr_getValue (constraintExpr expr)
1196{
1197 llassert (expr->kind == term);
1198 return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data) ) );
1199}
1200
1201bool constraintExpr_canGetValue (constraintExpr expr)
1202{
1203 switch (expr->kind)
1204 {
1205 case term:
1206 return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1207 default:
1208 return FALSE;
1209
1210 }
1211 llassert(FALSE);
1212}
1213
1214bool constraintExpr_canCompare (constraintExpr expr1, constraintExpr expr2)
1215{
1216
1217 llassert(expr1 && expr2);
1218 return ( constraintExpr_canGetValue(expr1) &&
1219 constraintExpr_canGetValue(expr2)
1220 );
1221}
1222
1223
1224fileloc constraintExpr_getFileloc (constraintExpr expr)
1225{
1226 constraintExpr e;
1227constraintTerm t;
1228 constraintExprKind kind;
1229
1230 kind = expr->kind;
1231
1232 switch (kind)
1233 {
1234 case term:
1235 t = constraintExprData_termGetTerm (expr->data);
1236 return (constraintTerm_getFileloc (t) );
1237 break;
1238 case unaryExpr:
1239 e = constraintExprData_unaryExprGetExpr (expr->data);
1240 return (constraintExpr_getFileloc (e) );
1241 break;
1242 case binaryexpr:
1243 e = constraintExprData_binaryExprGetExpr1 (expr->data);
1244 return (constraintExpr_getFileloc (e) );
1245 }
1246 llassert (FALSE);
1247 // llfatalbug("Code should be reached");
1248 return (fileloc_undefined);
1249}
1250
1251
1252
1253/* bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term) */
1254/* { */
1255/* if (constraintTerm_hasTerm (expr->term, term) ) */
1256/* return TRUE; */
1257
1258/* if ( (expr->expr) != NULL) */
1259/* { */
1260/* return ( constraintExpr_includesTerm (expr->expr, term) ); */
1261/* } */
1262/* return FALSE; */
1263
1264/* } */
1265
1266
1267
1268
This page took 0.221664 seconds and 5 git commands to generate.