re PR tree-optimization/43833 (false warning: array subscript is above array bounds...
[gcc.git] / gcc / omega.c
1 /* Source code for an implementation of the Omega test, an integer
2 programming algorithm for dependence analysis, by William Pugh,
3 appeared in Supercomputing '91 and CACM Aug 92.
4
5 This code has no license restrictions, and is considered public
6 domain.
7
8 Changes copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
9 Inc.
10 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
11
12 This file is part of GCC.
13
14 GCC is free software; you can redistribute it and/or modify it under
15 the terms of the GNU General Public License as published by the Free
16 Software Foundation; either version 3, or (at your option) any later
17 version.
18
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING3. If not see
26 <http://www.gnu.org/licenses/>. */
27
28 /* For a detailed description, see "Constraint-Based Array Dependence
29 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
30 Wonnacott's thesis:
31 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
32 */
33
34 #include "config.h"
35 #include "system.h"
36 #include "coretypes.h"
37 #include "tm.h"
38 #include "ggc.h"
39 #include "tree.h"
40 #include "diagnostic.h"
41 #include "varray.h"
42 #include "tree-pass.h"
43 #include "omega.h"
44
45 /* When set to true, keep substitution variables. When set to false,
46 resurrect substitution variables (convert substitutions back to EQs). */
47 static bool omega_reduce_with_subs = true;
48
49 /* When set to true, omega_simplify_problem checks for problem with no
50 solutions, calling verify_omega_pb. */
51 static bool omega_verify_simplification = false;
52
53 /* When set to true, only produce a single simplified result. */
54 static bool omega_single_result = false;
55
56 /* Set return_single_result to 1 when omega_single_result is true. */
57 static int return_single_result = 0;
58
59 /* Hash table for equations generated by the solver. */
60 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
61 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
62 static eqn hash_master;
63 static int next_key;
64 static int hash_version = 0;
65
66 /* Set to true for making the solver enter in approximation mode. */
67 static bool in_approximate_mode = false;
68
69 /* When set to zero, the solver is allowed to add new equalities to
70 the problem to be solved. */
71 static int conservative = 0;
72
73 /* Set to omega_true when the problem was successfully reduced, set to
74 omega_unknown when the solver is unable to determine an answer. */
75 static enum omega_result omega_found_reduction;
76
77 /* Set to true when the solver is allowed to add omega_red equations. */
78 static bool create_color = false;
79
80 /* Set to nonzero when the problem to be solved can be reduced. */
81 static int may_be_red = 0;
82
83 /* When false, there should be no substitution equations in the
84 simplified problem. */
85 static int please_no_equalities_in_simplified_problems = 0;
86
87 /* Variables names for pretty printing. */
88 static char wild_name[200][40];
89
90 /* Pointer to the void problem. */
91 static omega_pb no_problem = (omega_pb) 0;
92
93 /* Pointer to the problem to be solved. */
94 static omega_pb original_problem = (omega_pb) 0;
95
96
97 /* Return the integer A divided by B. */
98
99 static inline int
100 int_div (int a, int b)
101 {
102 if (a > 0)
103 return a/b;
104 else
105 return -((-a + b - 1)/b);
106 }
107
108 /* Return the integer A modulo B. */
109
110 static inline int
111 int_mod (int a, int b)
112 {
113 return a - b * int_div (a, b);
114 }
115
116 /* For X and Y positive integers, return X multiplied by Y and check
117 that the result does not overflow. */
118
119 static inline int
120 check_pos_mul (int x, int y)
121 {
122 if (x != 0)
123 gcc_assert ((INT_MAX) / x > y);
124
125 return x * y;
126 }
127
128 /* Return X multiplied by Y and check that the result does not
129 overflow. */
130
131 static inline int
132 check_mul (int x, int y)
133 {
134 if (x >= 0)
135 {
136 if (y >= 0)
137 return check_pos_mul (x, y);
138 else
139 return -check_pos_mul (x, -y);
140 }
141 else if (y >= 0)
142 return -check_pos_mul (-x, y);
143 else
144 return check_pos_mul (-x, -y);
145 }
146
147 /* Test whether equation E is red. */
148
149 static inline bool
150 omega_eqn_is_red (eqn e, int desired_res)
151 {
152 return (desired_res == omega_simplify && e->color == omega_red);
153 }
154
155 /* Return a string for VARIABLE. */
156
157 static inline char *
158 omega_var_to_str (int variable)
159 {
160 if (0 <= variable && variable <= 20)
161 return wild_name[variable];
162
163 if (-20 < variable && variable < 0)
164 return wild_name[40 + variable];
165
166 /* Collapse all the entries that would have overflowed. */
167 return wild_name[21];
168 }
169
170 /* Return a string for variable I in problem PB. */
171
172 static inline char *
173 omega_variable_to_str (omega_pb pb, int i)
174 {
175 return omega_var_to_str (pb->var[i]);
176 }
177
178 /* Do nothing function: used for default initializations. */
179
180 void
181 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
182 {
183 }
184
185 void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
186
187 /* Compute the greatest common divisor of A and B. */
188
189 static inline int
190 gcd (int b, int a)
191 {
192 if (b == 1)
193 return 1;
194
195 while (b != 0)
196 {
197 int t = b;
198 b = a % b;
199 a = t;
200 }
201
202 return a;
203 }
204
205 /* Print to FILE from PB equation E with all its coefficients
206 multiplied by C. */
207
208 static void
209 omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
210 {
211 int i;
212 bool first = true;
213 int n = pb->num_vars;
214 int went_first = -1;
215
216 for (i = 1; i <= n; i++)
217 if (c * e->coef[i] > 0)
218 {
219 first = false;
220 went_first = i;
221
222 if (c * e->coef[i] == 1)
223 fprintf (file, "%s", omega_variable_to_str (pb, i));
224 else
225 fprintf (file, "%d * %s", c * e->coef[i],
226 omega_variable_to_str (pb, i));
227 break;
228 }
229
230 for (i = 1; i <= n; i++)
231 if (i != went_first && c * e->coef[i] != 0)
232 {
233 if (!first && c * e->coef[i] > 0)
234 fprintf (file, " + ");
235
236 first = false;
237
238 if (c * e->coef[i] == 1)
239 fprintf (file, "%s", omega_variable_to_str (pb, i));
240 else if (c * e->coef[i] == -1)
241 fprintf (file, " - %s", omega_variable_to_str (pb, i));
242 else
243 fprintf (file, "%d * %s", c * e->coef[i],
244 omega_variable_to_str (pb, i));
245 }
246
247 if (!first && c * e->coef[0] > 0)
248 fprintf (file, " + ");
249
250 if (first || c * e->coef[0] != 0)
251 fprintf (file, "%d", c * e->coef[0]);
252 }
253
254 /* Print to FILE the equation E of problem PB. */
255
256 void
257 omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
258 {
259 int i;
260 int n = pb->num_vars + extra;
261 bool is_lt = test && e->coef[0] == -1;
262 bool first;
263
264 if (test)
265 {
266 if (e->touched)
267 fprintf (file, "!");
268
269 else if (e->key != 0)
270 fprintf (file, "%d: ", e->key);
271 }
272
273 if (e->color == omega_red)
274 fprintf (file, "[");
275
276 first = true;
277
278 for (i = is_lt ? 1 : 0; i <= n; i++)
279 if (e->coef[i] < 0)
280 {
281 if (!first)
282 fprintf (file, " + ");
283 else
284 first = false;
285
286 if (i == 0)
287 fprintf (file, "%d", -e->coef[i]);
288 else if (e->coef[i] == -1)
289 fprintf (file, "%s", omega_variable_to_str (pb, i));
290 else
291 fprintf (file, "%d * %s", -e->coef[i],
292 omega_variable_to_str (pb, i));
293 }
294
295 if (first)
296 {
297 if (is_lt)
298 {
299 fprintf (file, "1");
300 is_lt = false;
301 }
302 else
303 fprintf (file, "0");
304 }
305
306 if (test == 0)
307 fprintf (file, " = ");
308 else if (is_lt)
309 fprintf (file, " < ");
310 else
311 fprintf (file, " <= ");
312
313 first = true;
314
315 for (i = 0; i <= n; i++)
316 if (e->coef[i] > 0)
317 {
318 if (!first)
319 fprintf (file, " + ");
320 else
321 first = false;
322
323 if (i == 0)
324 fprintf (file, "%d", e->coef[i]);
325 else if (e->coef[i] == 1)
326 fprintf (file, "%s", omega_variable_to_str (pb, i));
327 else
328 fprintf (file, "%d * %s", e->coef[i],
329 omega_variable_to_str (pb, i));
330 }
331
332 if (first)
333 fprintf (file, "0");
334
335 if (e->color == omega_red)
336 fprintf (file, "]");
337 }
338
339 /* Print to FILE all the variables of problem PB. */
340
341 static void
342 omega_print_vars (FILE *file, omega_pb pb)
343 {
344 int i;
345
346 fprintf (file, "variables = ");
347
348 if (pb->safe_vars > 0)
349 fprintf (file, "protected (");
350
351 for (i = 1; i <= pb->num_vars; i++)
352 {
353 fprintf (file, "%s", omega_variable_to_str (pb, i));
354
355 if (i == pb->safe_vars)
356 fprintf (file, ")");
357
358 if (i < pb->num_vars)
359 fprintf (file, ", ");
360 }
361
362 fprintf (file, "\n");
363 }
364
365 /* Debug problem PB. */
366
367 void
368 debug_omega_problem (omega_pb pb)
369 {
370 omega_print_problem (stderr, pb);
371 }
372
373 /* Print to FILE problem PB. */
374
375 void
376 omega_print_problem (FILE *file, omega_pb pb)
377 {
378 int e;
379
380 if (!pb->variables_initialized)
381 omega_initialize_variables (pb);
382
383 omega_print_vars (file, pb);
384
385 for (e = 0; e < pb->num_eqs; e++)
386 {
387 omega_print_eq (file, pb, &pb->eqs[e]);
388 fprintf (file, "\n");
389 }
390
391 fprintf (file, "Done with EQ\n");
392
393 for (e = 0; e < pb->num_geqs; e++)
394 {
395 omega_print_geq (file, pb, &pb->geqs[e]);
396 fprintf (file, "\n");
397 }
398
399 fprintf (file, "Done with GEQ\n");
400
401 for (e = 0; e < pb->num_subs; e++)
402 {
403 eqn eq = &pb->subs[e];
404
405 if (eq->color == omega_red)
406 fprintf (file, "[");
407
408 if (eq->key > 0)
409 fprintf (file, "%s := ", omega_var_to_str (eq->key));
410 else
411 fprintf (file, "#%d := ", eq->key);
412
413 omega_print_term (file, pb, eq, 1);
414
415 if (eq->color == omega_red)
416 fprintf (file, "]");
417
418 fprintf (file, "\n");
419 }
420 }
421
422 /* Return the number of equations in PB tagged omega_red. */
423
424 int
425 omega_count_red_equations (omega_pb pb)
426 {
427 int e, i;
428 int result = 0;
429
430 for (e = 0; e < pb->num_eqs; e++)
431 if (pb->eqs[e].color == omega_red)
432 {
433 for (i = pb->num_vars; i > 0; i--)
434 if (pb->geqs[e].coef[i])
435 break;
436
437 if (i == 0 && pb->geqs[e].coef[0] == 1)
438 return 0;
439 else
440 result += 2;
441 }
442
443 for (e = 0; e < pb->num_geqs; e++)
444 if (pb->geqs[e].color == omega_red)
445 result += 1;
446
447 for (e = 0; e < pb->num_subs; e++)
448 if (pb->subs[e].color == omega_red)
449 result += 2;
450
451 return result;
452 }
453
454 /* Print to FILE all the equations in PB that are tagged omega_red. */
455
456 void
457 omega_print_red_equations (FILE *file, omega_pb pb)
458 {
459 int e;
460
461 if (!pb->variables_initialized)
462 omega_initialize_variables (pb);
463
464 omega_print_vars (file, pb);
465
466 for (e = 0; e < pb->num_eqs; e++)
467 if (pb->eqs[e].color == omega_red)
468 {
469 omega_print_eq (file, pb, &pb->eqs[e]);
470 fprintf (file, "\n");
471 }
472
473 for (e = 0; e < pb->num_geqs; e++)
474 if (pb->geqs[e].color == omega_red)
475 {
476 omega_print_geq (file, pb, &pb->geqs[e]);
477 fprintf (file, "\n");
478 }
479
480 for (e = 0; e < pb->num_subs; e++)
481 if (pb->subs[e].color == omega_red)
482 {
483 eqn eq = &pb->subs[e];
484 fprintf (file, "[");
485
486 if (eq->key > 0)
487 fprintf (file, "%s := ", omega_var_to_str (eq->key));
488 else
489 fprintf (file, "#%d := ", eq->key);
490
491 omega_print_term (file, pb, eq, 1);
492 fprintf (file, "]\n");
493 }
494 }
495
496 /* Pretty print PB to FILE. */
497
498 void
499 omega_pretty_print_problem (FILE *file, omega_pb pb)
500 {
501 int e, v, v1, v2, v3, t;
502 bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
503 int stuffPrinted = 0;
504 bool change;
505
506 typedef enum {
507 none, le, lt
508 } partial_order_type;
509
510 partial_order_type **po = XNEWVEC (partial_order_type *,
511 OMEGA_MAX_VARS * OMEGA_MAX_VARS);
512 int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
513 int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
514 int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
515 int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
516 int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
517 int i, m;
518 bool multiprint;
519
520 if (!pb->variables_initialized)
521 omega_initialize_variables (pb);
522
523 if (pb->num_vars > 0)
524 {
525 omega_eliminate_redundant (pb, false);
526
527 for (e = 0; e < pb->num_eqs; e++)
528 {
529 if (stuffPrinted)
530 fprintf (file, "; ");
531
532 stuffPrinted = 1;
533 omega_print_eq (file, pb, &pb->eqs[e]);
534 }
535
536 for (e = 0; e < pb->num_geqs; e++)
537 live[e] = true;
538
539 while (1)
540 {
541 for (v = 1; v <= pb->num_vars; v++)
542 {
543 last_links[v] = first_links[v] = 0;
544 chain_length[v] = 0;
545
546 for (v2 = 1; v2 <= pb->num_vars; v2++)
547 po[v][v2] = none;
548 }
549
550 for (e = 0; e < pb->num_geqs; e++)
551 if (live[e])
552 {
553 for (v = 1; v <= pb->num_vars; v++)
554 if (pb->geqs[e].coef[v] == 1)
555 first_links[v]++;
556 else if (pb->geqs[e].coef[v] == -1)
557 last_links[v]++;
558
559 v1 = pb->num_vars;
560
561 while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
562 v1--;
563
564 v2 = v1 - 1;
565
566 while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
567 v2--;
568
569 v3 = v2 - 1;
570
571 while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
572 v3--;
573
574 if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
575 || v2 <= 0 || v3 > 0
576 || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
577 {
578 /* Not a partial order relation. */
579 }
580 else
581 {
582 if (pb->geqs[e].coef[v1] == 1)
583 {
584 v3 = v2;
585 v2 = v1;
586 v1 = v3;
587 }
588
589 /* Relation is v1 <= v2 or v1 < v2. */
590 po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
591 po_eq[v1][v2] = e;
592 }
593 }
594 for (v = 1; v <= pb->num_vars; v++)
595 chain_length[v] = last_links[v];
596
597 /* Just in case pb->num_vars <= 0. */
598 change = false;
599 for (t = 0; t < pb->num_vars; t++)
600 {
601 change = false;
602
603 for (v1 = 1; v1 <= pb->num_vars; v1++)
604 for (v2 = 1; v2 <= pb->num_vars; v2++)
605 if (po[v1][v2] != none &&
606 chain_length[v1] <= chain_length[v2])
607 {
608 chain_length[v1] = chain_length[v2] + 1;
609 change = true;
610 }
611 }
612
613 /* Caught in cycle. */
614 gcc_assert (!change);
615
616 for (v1 = 1; v1 <= pb->num_vars; v1++)
617 if (chain_length[v1] == 0)
618 first_links[v1] = 0;
619
620 v = 1;
621
622 for (v1 = 2; v1 <= pb->num_vars; v1++)
623 if (chain_length[v1] + first_links[v1] >
624 chain_length[v] + first_links[v])
625 v = v1;
626
627 if (chain_length[v] + first_links[v] == 0)
628 break;
629
630 if (stuffPrinted)
631 fprintf (file, "; ");
632
633 stuffPrinted = 1;
634
635 /* Chain starts at v. */
636 {
637 int tmp;
638 bool first = true;
639
640 for (e = 0; e < pb->num_geqs; e++)
641 if (live[e] && pb->geqs[e].coef[v] == 1)
642 {
643 if (!first)
644 fprintf (file, ", ");
645
646 tmp = pb->geqs[e].coef[v];
647 pb->geqs[e].coef[v] = 0;
648 omega_print_term (file, pb, &pb->geqs[e], -1);
649 pb->geqs[e].coef[v] = tmp;
650 live[e] = false;
651 first = false;
652 }
653
654 if (!first)
655 fprintf (file, " <= ");
656 }
657
658 /* Find chain. */
659 chain[0] = v;
660 m = 1;
661 while (1)
662 {
663 /* Print chain. */
664 for (v2 = 1; v2 <= pb->num_vars; v2++)
665 if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
666 break;
667
668 if (v2 > pb->num_vars)
669 break;
670
671 chain[m++] = v2;
672 v = v2;
673 }
674
675 fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
676
677 for (multiprint = false, i = 1; i < m; i++)
678 {
679 v = chain[i - 1];
680 v2 = chain[i];
681
682 if (po[v][v2] == le)
683 fprintf (file, " <= ");
684 else
685 fprintf (file, " < ");
686
687 fprintf (file, "%s", omega_variable_to_str (pb, v2));
688 live[po_eq[v][v2]] = false;
689
690 if (!multiprint && i < m - 1)
691 for (v3 = 1; v3 <= pb->num_vars; v3++)
692 {
693 if (v == v3 || v2 == v3
694 || po[v][v2] != po[v][v3]
695 || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
696 continue;
697
698 fprintf (file, ",%s", omega_variable_to_str (pb, v3));
699 live[po_eq[v][v3]] = false;
700 live[po_eq[v3][chain[i + 1]]] = false;
701 multiprint = true;
702 }
703 else
704 multiprint = false;
705 }
706
707 v = chain[m - 1];
708 /* Print last_links. */
709 {
710 int tmp;
711 bool first = true;
712
713 for (e = 0; e < pb->num_geqs; e++)
714 if (live[e] && pb->geqs[e].coef[v] == -1)
715 {
716 if (!first)
717 fprintf (file, ", ");
718 else
719 fprintf (file, " <= ");
720
721 tmp = pb->geqs[e].coef[v];
722 pb->geqs[e].coef[v] = 0;
723 omega_print_term (file, pb, &pb->geqs[e], 1);
724 pb->geqs[e].coef[v] = tmp;
725 live[e] = false;
726 first = false;
727 }
728 }
729 }
730
731 for (e = 0; e < pb->num_geqs; e++)
732 if (live[e])
733 {
734 if (stuffPrinted)
735 fprintf (file, "; ");
736 stuffPrinted = 1;
737 omega_print_geq (file, pb, &pb->geqs[e]);
738 }
739
740 for (e = 0; e < pb->num_subs; e++)
741 {
742 eqn eq = &pb->subs[e];
743
744 if (stuffPrinted)
745 fprintf (file, "; ");
746
747 stuffPrinted = 1;
748
749 if (eq->key > 0)
750 fprintf (file, "%s := ", omega_var_to_str (eq->key));
751 else
752 fprintf (file, "#%d := ", eq->key);
753
754 omega_print_term (file, pb, eq, 1);
755 }
756 }
757
758 free (live);
759 free (po);
760 free (po_eq);
761 free (last_links);
762 free (first_links);
763 free (chain_length);
764 free (chain);
765 }
766
767 /* Assign to variable I in PB the next wildcard name. The name of a
768 wildcard is a negative number. */
769 static int next_wild_card = 0;
770
771 static void
772 omega_name_wild_card (omega_pb pb, int i)
773 {
774 --next_wild_card;
775 if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
776 next_wild_card = -1;
777 pb->var[i] = next_wild_card;
778 }
779
780 /* Return the index of the last protected (or safe) variable in PB,
781 after having added a new wildcard variable. */
782
783 static int
784 omega_add_new_wild_card (omega_pb pb)
785 {
786 int e;
787 int i = ++pb->safe_vars;
788 pb->num_vars++;
789
790 /* Make a free place in the protected (safe) variables, by moving
791 the non protected variable pointed by "I" at the end, ie. at
792 offset pb->num_vars. */
793 if (pb->num_vars != i)
794 {
795 /* Move "I" for all the inequalities. */
796 for (e = pb->num_geqs - 1; e >= 0; e--)
797 {
798 if (pb->geqs[e].coef[i])
799 pb->geqs[e].touched = 1;
800
801 pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
802 }
803
804 /* Move "I" for all the equalities. */
805 for (e = pb->num_eqs - 1; e >= 0; e--)
806 pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
807
808 /* Move "I" for all the substitutions. */
809 for (e = pb->num_subs - 1; e >= 0; e--)
810 pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
811
812 /* Move the identifier. */
813 pb->var[pb->num_vars] = pb->var[i];
814 }
815
816 /* Initialize at zero all the coefficients */
817 for (e = pb->num_geqs - 1; e >= 0; e--)
818 pb->geqs[e].coef[i] = 0;
819
820 for (e = pb->num_eqs - 1; e >= 0; e--)
821 pb->eqs[e].coef[i] = 0;
822
823 for (e = pb->num_subs - 1; e >= 0; e--)
824 pb->subs[e].coef[i] = 0;
825
826 /* And give it a name. */
827 omega_name_wild_card (pb, i);
828 return i;
829 }
830
831 /* Delete inequality E from problem PB that has N_VARS variables. */
832
833 static void
834 omega_delete_geq (omega_pb pb, int e, int n_vars)
835 {
836 if (dump_file && (dump_flags & TDF_DETAILS))
837 {
838 fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
839 omega_print_geq (dump_file, pb, &pb->geqs[e]);
840 fprintf (dump_file, "\n");
841 }
842
843 if (e < pb->num_geqs - 1)
844 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
845
846 pb->num_geqs--;
847 }
848
849 /* Delete extra inequality E from problem PB that has N_VARS
850 variables. */
851
852 static void
853 omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
854 {
855 if (dump_file && (dump_flags & TDF_DETAILS))
856 {
857 fprintf (dump_file, "Deleting %d: ",e);
858 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
859 fprintf (dump_file, "\n");
860 }
861
862 if (e < pb->num_geqs - 1)
863 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
864
865 pb->num_geqs--;
866 }
867
868
869 /* Remove variable I from problem PB. */
870
871 static void
872 omega_delete_variable (omega_pb pb, int i)
873 {
874 int n_vars = pb->num_vars;
875 int e;
876
877 if (omega_safe_var_p (pb, i))
878 {
879 int j = pb->safe_vars;
880
881 for (e = pb->num_geqs - 1; e >= 0; e--)
882 {
883 pb->geqs[e].touched = 1;
884 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
885 pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
886 }
887
888 for (e = pb->num_eqs - 1; e >= 0; e--)
889 {
890 pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
891 pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
892 }
893
894 for (e = pb->num_subs - 1; e >= 0; e--)
895 {
896 pb->subs[e].coef[i] = pb->subs[e].coef[j];
897 pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
898 }
899
900 pb->var[i] = pb->var[j];
901 pb->var[j] = pb->var[n_vars];
902 }
903 else if (i < n_vars)
904 {
905 for (e = pb->num_geqs - 1; e >= 0; e--)
906 if (pb->geqs[e].coef[n_vars])
907 {
908 pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
909 pb->geqs[e].touched = 1;
910 }
911
912 for (e = pb->num_eqs - 1; e >= 0; e--)
913 pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
914
915 for (e = pb->num_subs - 1; e >= 0; e--)
916 pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
917
918 pb->var[i] = pb->var[n_vars];
919 }
920
921 if (omega_safe_var_p (pb, i))
922 pb->safe_vars--;
923
924 pb->num_vars--;
925 }
926
927 /* Because the coefficients of an equation are sparse, PACKING records
928 indices for non null coefficients. */
929 static int *packing;
930
931 /* Set up the coefficients of PACKING, following the coefficients of
932 equation EQN that has NUM_VARS variables. */
933
934 static inline int
935 setup_packing (eqn eqn, int num_vars)
936 {
937 int k;
938 int n = 0;
939
940 for (k = num_vars; k >= 0; k--)
941 if (eqn->coef[k])
942 packing[n++] = k;
943
944 return n;
945 }
946
947 /* Computes a linear combination of EQ and SUB at VAR with coefficient
948 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
949 non null indices of SUB stored in PACKING. */
950
951 static inline void
952 omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
953 int top_var)
954 {
955 if (eq->coef[var] != 0)
956 {
957 if (eq->color == omega_black)
958 *found_black = true;
959 else
960 {
961 int j, k = eq->coef[var];
962
963 eq->coef[var] = 0;
964
965 for (j = top_var; j >= 0; j--)
966 eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
967 }
968 }
969 }
970
971 /* Substitute in PB variable VAR with "C * SUB". */
972
973 static void
974 omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
975 {
976 int e, top_var = setup_packing (sub, pb->num_vars);
977
978 *found_black = false;
979
980 if (dump_file && (dump_flags & TDF_DETAILS))
981 {
982 if (sub->color == omega_red)
983 fprintf (dump_file, "[");
984
985 fprintf (dump_file, "substituting using %s := ",
986 omega_variable_to_str (pb, var));
987 omega_print_term (dump_file, pb, sub, -c);
988
989 if (sub->color == omega_red)
990 fprintf (dump_file, "]");
991
992 fprintf (dump_file, "\n");
993 omega_print_vars (dump_file, pb);
994 }
995
996 for (e = pb->num_eqs - 1; e >= 0; e--)
997 {
998 eqn eqn = &(pb->eqs[e]);
999
1000 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
1001
1002 if (dump_file && (dump_flags & TDF_DETAILS))
1003 {
1004 omega_print_eq (dump_file, pb, eqn);
1005 fprintf (dump_file, "\n");
1006 }
1007 }
1008
1009 for (e = pb->num_geqs - 1; e >= 0; e--)
1010 {
1011 eqn eqn = &(pb->geqs[e]);
1012
1013 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
1014
1015 if (eqn->coef[var] && eqn->color == omega_red)
1016 eqn->touched = 1;
1017
1018 if (dump_file && (dump_flags & TDF_DETAILS))
1019 {
1020 omega_print_geq (dump_file, pb, eqn);
1021 fprintf (dump_file, "\n");
1022 }
1023 }
1024
1025 for (e = pb->num_subs - 1; e >= 0; e--)
1026 {
1027 eqn eqn = &(pb->subs[e]);
1028
1029 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
1030
1031 if (dump_file && (dump_flags & TDF_DETAILS))
1032 {
1033 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1034 omega_print_term (dump_file, pb, eqn, 1);
1035 fprintf (dump_file, "\n");
1036 }
1037 }
1038
1039 if (dump_file && (dump_flags & TDF_DETAILS))
1040 fprintf (dump_file, "---\n\n");
1041
1042 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1043 *found_black = true;
1044 }
1045
1046 /* Substitute in PB variable VAR with "C * SUB". */
1047
1048 static void
1049 omega_substitute (omega_pb pb, eqn sub, int var, int c)
1050 {
1051 int e, j, j0;
1052 int top_var = setup_packing (sub, pb->num_vars);
1053
1054 if (dump_file && (dump_flags & TDF_DETAILS))
1055 {
1056 fprintf (dump_file, "substituting using %s := ",
1057 omega_variable_to_str (pb, var));
1058 omega_print_term (dump_file, pb, sub, -c);
1059 fprintf (dump_file, "\n");
1060 omega_print_vars (dump_file, pb);
1061 }
1062
1063 if (top_var < 0)
1064 {
1065 for (e = pb->num_eqs - 1; e >= 0; e--)
1066 pb->eqs[e].coef[var] = 0;
1067
1068 for (e = pb->num_geqs - 1; e >= 0; e--)
1069 if (pb->geqs[e].coef[var] != 0)
1070 {
1071 pb->geqs[e].touched = 1;
1072 pb->geqs[e].coef[var] = 0;
1073 }
1074
1075 for (e = pb->num_subs - 1; e >= 0; e--)
1076 pb->subs[e].coef[var] = 0;
1077
1078 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1079 {
1080 int k;
1081 eqn eqn = &(pb->subs[pb->num_subs++]);
1082
1083 for (k = pb->num_vars; k >= 0; k--)
1084 eqn->coef[k] = 0;
1085
1086 eqn->key = pb->var[var];
1087 eqn->color = omega_black;
1088 }
1089 }
1090 else if (top_var == 0 && packing[0] == 0)
1091 {
1092 c = -sub->coef[0] * c;
1093
1094 for (e = pb->num_eqs - 1; e >= 0; e--)
1095 {
1096 pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
1097 pb->eqs[e].coef[var] = 0;
1098 }
1099
1100 for (e = pb->num_geqs - 1; e >= 0; e--)
1101 if (pb->geqs[e].coef[var] != 0)
1102 {
1103 pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
1104 pb->geqs[e].coef[var] = 0;
1105 pb->geqs[e].touched = 1;
1106 }
1107
1108 for (e = pb->num_subs - 1; e >= 0; e--)
1109 {
1110 pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
1111 pb->subs[e].coef[var] = 0;
1112 }
1113
1114 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1115 {
1116 int k;
1117 eqn eqn = &(pb->subs[pb->num_subs++]);
1118
1119 for (k = pb->num_vars; k >= 1; k--)
1120 eqn->coef[k] = 0;
1121
1122 eqn->coef[0] = c;
1123 eqn->key = pb->var[var];
1124 eqn->color = omega_black;
1125 }
1126
1127 if (dump_file && (dump_flags & TDF_DETAILS))
1128 {
1129 fprintf (dump_file, "---\n\n");
1130 omega_print_problem (dump_file, pb);
1131 fprintf (dump_file, "===\n\n");
1132 }
1133 }
1134 else
1135 {
1136 for (e = pb->num_eqs - 1; e >= 0; e--)
1137 {
1138 eqn eqn = &(pb->eqs[e]);
1139 int k = eqn->coef[var];
1140
1141 if (k != 0)
1142 {
1143 k = c * k;
1144 eqn->coef[var] = 0;
1145
1146 for (j = top_var; j >= 0; j--)
1147 {
1148 j0 = packing[j];
1149 eqn->coef[j0] -= sub->coef[j0] * k;
1150 }
1151 }
1152
1153 if (dump_file && (dump_flags & TDF_DETAILS))
1154 {
1155 omega_print_eq (dump_file, pb, eqn);
1156 fprintf (dump_file, "\n");
1157 }
1158 }
1159
1160 for (e = pb->num_geqs - 1; e >= 0; e--)
1161 {
1162 eqn eqn = &(pb->geqs[e]);
1163 int k = eqn->coef[var];
1164
1165 if (k != 0)
1166 {
1167 k = c * k;
1168 eqn->touched = 1;
1169 eqn->coef[var] = 0;
1170
1171 for (j = top_var; j >= 0; j--)
1172 {
1173 j0 = packing[j];
1174 eqn->coef[j0] -= sub->coef[j0] * k;
1175 }
1176 }
1177
1178 if (dump_file && (dump_flags & TDF_DETAILS))
1179 {
1180 omega_print_geq (dump_file, pb, eqn);
1181 fprintf (dump_file, "\n");
1182 }
1183 }
1184
1185 for (e = pb->num_subs - 1; e >= 0; e--)
1186 {
1187 eqn eqn = &(pb->subs[e]);
1188 int k = eqn->coef[var];
1189
1190 if (k != 0)
1191 {
1192 k = c * k;
1193 eqn->coef[var] = 0;
1194
1195 for (j = top_var; j >= 0; j--)
1196 {
1197 j0 = packing[j];
1198 eqn->coef[j0] -= sub->coef[j0] * k;
1199 }
1200 }
1201
1202 if (dump_file && (dump_flags & TDF_DETAILS))
1203 {
1204 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1205 omega_print_term (dump_file, pb, eqn, 1);
1206 fprintf (dump_file, "\n");
1207 }
1208 }
1209
1210 if (dump_file && (dump_flags & TDF_DETAILS))
1211 {
1212 fprintf (dump_file, "---\n\n");
1213 omega_print_problem (dump_file, pb);
1214 fprintf (dump_file, "===\n\n");
1215 }
1216
1217 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1218 {
1219 int k;
1220 eqn eqn = &(pb->subs[pb->num_subs++]);
1221 c = -c;
1222
1223 for (k = pb->num_vars; k >= 0; k--)
1224 eqn->coef[k] = c * (sub->coef[k]);
1225
1226 eqn->key = pb->var[var];
1227 eqn->color = sub->color;
1228 }
1229 }
1230 }
1231
1232 /* Solve e = factor alpha for x_j and substitute. */
1233
1234 static void
1235 omega_do_mod (omega_pb pb, int factor, int e, int j)
1236 {
1237 int k, i;
1238 eqn eq = omega_alloc_eqns (0, 1);
1239 int nfactor;
1240 bool kill_j = false;
1241
1242 omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
1243
1244 for (k = pb->num_vars; k >= 0; k--)
1245 {
1246 eq->coef[k] = int_mod (eq->coef[k], factor);
1247
1248 if (2 * eq->coef[k] >= factor)
1249 eq->coef[k] -= factor;
1250 }
1251
1252 nfactor = eq->coef[j];
1253
1254 if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
1255 {
1256 i = omega_add_new_wild_card (pb);
1257 eq->coef[pb->num_vars] = eq->coef[i];
1258 eq->coef[j] = 0;
1259 eq->coef[i] = -factor;
1260 kill_j = true;
1261 }
1262 else
1263 {
1264 eq->coef[j] = -factor;
1265 if (!omega_wildcard_p (pb, j))
1266 omega_name_wild_card (pb, j);
1267 }
1268
1269 omega_substitute (pb, eq, j, nfactor);
1270
1271 for (k = pb->num_vars; k >= 0; k--)
1272 pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
1273
1274 if (kill_j)
1275 omega_delete_variable (pb, j);
1276
1277 if (dump_file && (dump_flags & TDF_DETAILS))
1278 {
1279 fprintf (dump_file, "Mod-ing and normalizing produces:\n");
1280 omega_print_problem (dump_file, pb);
1281 }
1282
1283 omega_free_eqns (eq, 1);
1284 }
1285
1286 /* Multiplies by -1 inequality E. */
1287
1288 void
1289 omega_negate_geq (omega_pb pb, int e)
1290 {
1291 int i;
1292
1293 for (i = pb->num_vars; i >= 0; i--)
1294 pb->geqs[e].coef[i] *= -1;
1295
1296 pb->geqs[e].coef[0]--;
1297 pb->geqs[e].touched = 1;
1298 }
1299
1300 /* Returns OMEGA_TRUE when problem PB has a solution. */
1301
1302 static enum omega_result
1303 verify_omega_pb (omega_pb pb)
1304 {
1305 enum omega_result result;
1306 int e;
1307 bool any_color = false;
1308 omega_pb tmp_problem = XNEW (struct omega_pb_d);
1309
1310 omega_copy_problem (tmp_problem, pb);
1311 tmp_problem->safe_vars = 0;
1312 tmp_problem->num_subs = 0;
1313
1314 for (e = pb->num_geqs - 1; e >= 0; e--)
1315 if (pb->geqs[e].color == omega_red)
1316 {
1317 any_color = true;
1318 break;
1319 }
1320
1321 if (please_no_equalities_in_simplified_problems)
1322 any_color = true;
1323
1324 if (any_color)
1325 original_problem = no_problem;
1326 else
1327 original_problem = pb;
1328
1329 if (dump_file && (dump_flags & TDF_DETAILS))
1330 {
1331 fprintf (dump_file, "verifying problem");
1332
1333 if (any_color)
1334 fprintf (dump_file, " (color mode)");
1335
1336 fprintf (dump_file, " :\n");
1337 omega_print_problem (dump_file, pb);
1338 }
1339
1340 result = omega_solve_problem (tmp_problem, omega_unknown);
1341 original_problem = no_problem;
1342 free (tmp_problem);
1343
1344 if (dump_file && (dump_flags & TDF_DETAILS))
1345 {
1346 if (result != omega_false)
1347 fprintf (dump_file, "verified problem\n");
1348 else
1349 fprintf (dump_file, "disproved problem\n");
1350 omega_print_problem (dump_file, pb);
1351 }
1352
1353 return result;
1354 }
1355
1356 /* Add a new equality to problem PB at last position E. */
1357
1358 static void
1359 adding_equality_constraint (omega_pb pb, int e)
1360 {
1361 if (original_problem != no_problem
1362 && original_problem != pb
1363 && !conservative)
1364 {
1365 int i, j;
1366 int e2 = original_problem->num_eqs++;
1367
1368 if (dump_file && (dump_flags & TDF_DETAILS))
1369 fprintf (dump_file,
1370 "adding equality constraint %d to outer problem\n", e2);
1371 omega_init_eqn_zero (&original_problem->eqs[e2],
1372 original_problem->num_vars);
1373
1374 for (i = pb->num_vars; i >= 1; i--)
1375 {
1376 for (j = original_problem->num_vars; j >= 1; j--)
1377 if (original_problem->var[j] == pb->var[i])
1378 break;
1379
1380 if (j <= 0)
1381 {
1382 if (dump_file && (dump_flags & TDF_DETAILS))
1383 fprintf (dump_file, "retracting\n");
1384 original_problem->num_eqs--;
1385 return;
1386 }
1387 original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
1388 }
1389
1390 original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
1391
1392 if (dump_file && (dump_flags & TDF_DETAILS))
1393 omega_print_problem (dump_file, original_problem);
1394 }
1395 }
1396
1397 static int *fast_lookup;
1398 static int *fast_lookup_red;
1399
1400 typedef enum {
1401 normalize_false,
1402 normalize_uncoupled,
1403 normalize_coupled
1404 } normalize_return_type;
1405
1406 /* Normalizes PB by removing redundant constraints. Returns
1407 normalize_false when the constraints system has no solution,
1408 otherwise returns normalize_coupled or normalize_uncoupled. */
1409
1410 static normalize_return_type
1411 normalize_omega_problem (omega_pb pb)
1412 {
1413 int e, i, j, k, n_vars;
1414 int coupled_subscripts = 0;
1415
1416 n_vars = pb->num_vars;
1417
1418 for (e = 0; e < pb->num_geqs; e++)
1419 {
1420 if (!pb->geqs[e].touched)
1421 {
1422 if (!single_var_geq (&pb->geqs[e], n_vars))
1423 coupled_subscripts = 1;
1424 }
1425 else
1426 {
1427 int g, top_var, i0, hashCode;
1428 int *p = &packing[0];
1429
1430 for (k = 1; k <= n_vars; k++)
1431 if (pb->geqs[e].coef[k])
1432 *(p++) = k;
1433
1434 top_var = (p - &packing[0]) - 1;
1435
1436 if (top_var == -1)
1437 {
1438 if (pb->geqs[e].coef[0] < 0)
1439 {
1440 if (dump_file && (dump_flags & TDF_DETAILS))
1441 {
1442 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1443 fprintf (dump_file, "\nequations have no solution \n");
1444 }
1445 return normalize_false;
1446 }
1447
1448 omega_delete_geq (pb, e, n_vars);
1449 e--;
1450 continue;
1451 }
1452 else if (top_var == 0)
1453 {
1454 int singlevar = packing[0];
1455
1456 g = pb->geqs[e].coef[singlevar];
1457
1458 if (g > 0)
1459 {
1460 pb->geqs[e].coef[singlevar] = 1;
1461 pb->geqs[e].key = singlevar;
1462 }
1463 else
1464 {
1465 g = -g;
1466 pb->geqs[e].coef[singlevar] = -1;
1467 pb->geqs[e].key = -singlevar;
1468 }
1469
1470 if (g > 1)
1471 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1472 }
1473 else
1474 {
1475 int g2;
1476 int hash_key_multiplier = 31;
1477
1478 coupled_subscripts = 1;
1479 i0 = top_var;
1480 i = packing[i0--];
1481 g = pb->geqs[e].coef[i];
1482 hashCode = g * (i + 3);
1483
1484 if (g < 0)
1485 g = -g;
1486
1487 for (; i0 >= 0; i0--)
1488 {
1489 int x;
1490
1491 i = packing[i0];
1492 x = pb->geqs[e].coef[i];
1493 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1494
1495 if (x < 0)
1496 x = -x;
1497
1498 if (x == 1)
1499 {
1500 g = 1;
1501 i0--;
1502 break;
1503 }
1504 else
1505 g = gcd (x, g);
1506 }
1507
1508 for (; i0 >= 0; i0--)
1509 {
1510 int x;
1511 i = packing[i0];
1512 x = pb->geqs[e].coef[i];
1513 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1514 }
1515
1516 if (g > 1)
1517 {
1518 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1519 i0 = top_var;
1520 i = packing[i0--];
1521 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1522 hashCode = pb->geqs[e].coef[i] * (i + 3);
1523
1524 for (; i0 >= 0; i0--)
1525 {
1526 i = packing[i0];
1527 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1528 hashCode = hashCode * hash_key_multiplier * (i + 3)
1529 + pb->geqs[e].coef[i];
1530 }
1531 }
1532
1533 g2 = abs (hashCode);
1534
1535 if (dump_file && (dump_flags & TDF_DETAILS))
1536 {
1537 fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
1538 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1539 fprintf (dump_file, "\n");
1540 }
1541
1542 j = g2 % HASH_TABLE_SIZE;
1543
1544 do {
1545 eqn proto = &(hash_master[j]);
1546
1547 if (proto->touched == g2)
1548 {
1549 if (proto->coef[0] == top_var)
1550 {
1551 if (hashCode >= 0)
1552 for (i0 = top_var; i0 >= 0; i0--)
1553 {
1554 i = packing[i0];
1555
1556 if (pb->geqs[e].coef[i] != proto->coef[i])
1557 break;
1558 }
1559 else
1560 for (i0 = top_var; i0 >= 0; i0--)
1561 {
1562 i = packing[i0];
1563
1564 if (pb->geqs[e].coef[i] != -proto->coef[i])
1565 break;
1566 }
1567
1568 if (i0 < 0)
1569 {
1570 if (hashCode >= 0)
1571 pb->geqs[e].key = proto->key;
1572 else
1573 pb->geqs[e].key = -proto->key;
1574 break;
1575 }
1576 }
1577 }
1578 else if (proto->touched < 0)
1579 {
1580 omega_init_eqn_zero (proto, pb->num_vars);
1581 if (hashCode >= 0)
1582 for (i0 = top_var; i0 >= 0; i0--)
1583 {
1584 i = packing[i0];
1585 proto->coef[i] = pb->geqs[e].coef[i];
1586 }
1587 else
1588 for (i0 = top_var; i0 >= 0; i0--)
1589 {
1590 i = packing[i0];
1591 proto->coef[i] = -pb->geqs[e].coef[i];
1592 }
1593
1594 proto->coef[0] = top_var;
1595 proto->touched = g2;
1596
1597 if (dump_file && (dump_flags & TDF_DETAILS))
1598 fprintf (dump_file, " constraint key = %d\n",
1599 next_key);
1600
1601 proto->key = next_key++;
1602
1603 /* Too many hash keys generated. */
1604 gcc_assert (proto->key <= MAX_KEYS);
1605
1606 if (hashCode >= 0)
1607 pb->geqs[e].key = proto->key;
1608 else
1609 pb->geqs[e].key = -proto->key;
1610
1611 break;
1612 }
1613
1614 j = (j + 1) % HASH_TABLE_SIZE;
1615 } while (1);
1616 }
1617
1618 pb->geqs[e].touched = 0;
1619 }
1620
1621 {
1622 int eKey = pb->geqs[e].key;
1623 int e2;
1624 if (e > 0)
1625 {
1626 int cTerm = pb->geqs[e].coef[0];
1627 e2 = fast_lookup[MAX_KEYS - eKey];
1628
1629 if (e2 < e && pb->geqs[e2].key == -eKey
1630 && pb->geqs[e2].color == omega_black)
1631 {
1632 if (pb->geqs[e2].coef[0] < -cTerm)
1633 {
1634 if (dump_file && (dump_flags & TDF_DETAILS))
1635 {
1636 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1637 fprintf (dump_file, "\n");
1638 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1639 fprintf (dump_file,
1640 "\nequations have no solution \n");
1641 }
1642 return normalize_false;
1643 }
1644
1645 if (pb->geqs[e2].coef[0] == -cTerm
1646 && (create_color
1647 || pb->geqs[e].color == omega_black))
1648 {
1649 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1650 pb->num_vars);
1651 if (pb->geqs[e].color == omega_black)
1652 adding_equality_constraint (pb, pb->num_eqs);
1653 pb->num_eqs++;
1654 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1655 }
1656 }
1657
1658 e2 = fast_lookup_red[MAX_KEYS - eKey];
1659
1660 if (e2 < e && pb->geqs[e2].key == -eKey
1661 && pb->geqs[e2].color == omega_red)
1662 {
1663 if (pb->geqs[e2].coef[0] < -cTerm)
1664 {
1665 if (dump_file && (dump_flags & TDF_DETAILS))
1666 {
1667 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1668 fprintf (dump_file, "\n");
1669 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1670 fprintf (dump_file,
1671 "\nequations have no solution \n");
1672 }
1673 return normalize_false;
1674 }
1675
1676 if (pb->geqs[e2].coef[0] == -cTerm && create_color)
1677 {
1678 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1679 pb->num_vars);
1680 pb->eqs[pb->num_eqs].color = omega_red;
1681 pb->num_eqs++;
1682 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1683 }
1684 }
1685
1686 e2 = fast_lookup[MAX_KEYS + eKey];
1687
1688 if (e2 < e && pb->geqs[e2].key == eKey
1689 && pb->geqs[e2].color == omega_black)
1690 {
1691 if (pb->geqs[e2].coef[0] > cTerm)
1692 {
1693 if (pb->geqs[e].color == omega_black)
1694 {
1695 if (dump_file && (dump_flags & TDF_DETAILS))
1696 {
1697 fprintf (dump_file,
1698 "Removing Redundant Equation: ");
1699 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1700 fprintf (dump_file, "\n");
1701 fprintf (dump_file,
1702 "[a] Made Redundant by: ");
1703 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1704 fprintf (dump_file, "\n");
1705 }
1706 pb->geqs[e2].coef[0] = cTerm;
1707 omega_delete_geq (pb, e, n_vars);
1708 e--;
1709 continue;
1710 }
1711 }
1712 else
1713 {
1714 if (dump_file && (dump_flags & TDF_DETAILS))
1715 {
1716 fprintf (dump_file, "Removing Redundant Equation: ");
1717 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1718 fprintf (dump_file, "\n");
1719 fprintf (dump_file, "[b] Made Redundant by: ");
1720 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1721 fprintf (dump_file, "\n");
1722 }
1723 omega_delete_geq (pb, e, n_vars);
1724 e--;
1725 continue;
1726 }
1727 }
1728
1729 e2 = fast_lookup_red[MAX_KEYS + eKey];
1730
1731 if (e2 < e && pb->geqs[e2].key == eKey
1732 && pb->geqs[e2].color == omega_red)
1733 {
1734 if (pb->geqs[e2].coef[0] >= cTerm)
1735 {
1736 if (dump_file && (dump_flags & TDF_DETAILS))
1737 {
1738 fprintf (dump_file, "Removing Redundant Equation: ");
1739 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1740 fprintf (dump_file, "\n");
1741 fprintf (dump_file, "[c] Made Redundant by: ");
1742 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1743 fprintf (dump_file, "\n");
1744 }
1745 pb->geqs[e2].coef[0] = cTerm;
1746 pb->geqs[e2].color = pb->geqs[e].color;
1747 }
1748 else if (pb->geqs[e].color == omega_red)
1749 {
1750 if (dump_file && (dump_flags & TDF_DETAILS))
1751 {
1752 fprintf (dump_file, "Removing Redundant Equation: ");
1753 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1754 fprintf (dump_file, "\n");
1755 fprintf (dump_file, "[d] Made Redundant by: ");
1756 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1757 fprintf (dump_file, "\n");
1758 }
1759 }
1760 omega_delete_geq (pb, e, n_vars);
1761 e--;
1762 continue;
1763
1764 }
1765 }
1766
1767 if (pb->geqs[e].color == omega_red)
1768 fast_lookup_red[MAX_KEYS + eKey] = e;
1769 else
1770 fast_lookup[MAX_KEYS + eKey] = e;
1771 }
1772 }
1773
1774 create_color = false;
1775 return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
1776 }
1777
1778 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1779 of variables in EQN. */
1780
1781 static inline void
1782 divide_eqn_by_gcd (eqn eqn, int n_vars)
1783 {
1784 int var, g = 0;
1785
1786 for (var = n_vars; var >= 0; var--)
1787 g = gcd (abs (eqn->coef[var]), g);
1788
1789 if (g)
1790 for (var = n_vars; var >= 0; var--)
1791 eqn->coef[var] = eqn->coef[var] / g;
1792 }
1793
1794 /* Rewrite some non-safe variables in function of protected
1795 wildcard variables. */
1796
1797 static void
1798 cleanout_wildcards (omega_pb pb)
1799 {
1800 int e, i, j;
1801 int n_vars = pb->num_vars;
1802 bool renormalize = false;
1803
1804 for (e = pb->num_eqs - 1; e >= 0; e--)
1805 for (i = n_vars; !omega_safe_var_p (pb, i); i--)
1806 if (pb->eqs[e].coef[i] != 0)
1807 {
1808 /* i is the last nonzero non-safe variable. */
1809
1810 for (j = i - 1; !omega_safe_var_p (pb, j); j--)
1811 if (pb->eqs[e].coef[j] != 0)
1812 break;
1813
1814 /* j is the next nonzero non-safe variable, or points
1815 to a safe variable: it is then a wildcard variable. */
1816
1817 /* Clean it out. */
1818 if (omega_safe_var_p (pb, j))
1819 {
1820 eqn sub = &(pb->eqs[e]);
1821 int c = pb->eqs[e].coef[i];
1822 int a = abs (c);
1823 int e2;
1824
1825 if (dump_file && (dump_flags & TDF_DETAILS))
1826 {
1827 fprintf (dump_file,
1828 "Found a single wild card equality: ");
1829 omega_print_eq (dump_file, pb, &pb->eqs[e]);
1830 fprintf (dump_file, "\n");
1831 omega_print_problem (dump_file, pb);
1832 }
1833
1834 for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
1835 if (e != e2 && pb->eqs[e2].coef[i]
1836 && (pb->eqs[e2].color == omega_red
1837 || (pb->eqs[e2].color == omega_black
1838 && pb->eqs[e].color == omega_black)))
1839 {
1840 eqn eqn = &(pb->eqs[e2]);
1841 int var, k;
1842
1843 for (var = n_vars; var >= 0; var--)
1844 eqn->coef[var] *= a;
1845
1846 k = eqn->coef[i];
1847
1848 for (var = n_vars; var >= 0; var--)
1849 eqn->coef[var] -= sub->coef[var] * k / c;
1850
1851 eqn->coef[i] = 0;
1852 divide_eqn_by_gcd (eqn, n_vars);
1853 }
1854
1855 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
1856 if (pb->geqs[e2].coef[i]
1857 && (pb->geqs[e2].color == omega_red
1858 || (pb->eqs[e].color == omega_black
1859 && pb->geqs[e2].color == omega_black)))
1860 {
1861 eqn eqn = &(pb->geqs[e2]);
1862 int var, k;
1863
1864 for (var = n_vars; var >= 0; var--)
1865 eqn->coef[var] *= a;
1866
1867 k = eqn->coef[i];
1868
1869 for (var = n_vars; var >= 0; var--)
1870 eqn->coef[var] -= sub->coef[var] * k / c;
1871
1872 eqn->coef[i] = 0;
1873 eqn->touched = 1;
1874 renormalize = true;
1875 }
1876
1877 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
1878 if (pb->subs[e2].coef[i]
1879 && (pb->subs[e2].color == omega_red
1880 || (pb->subs[e2].color == omega_black
1881 && pb->eqs[e].color == omega_black)))
1882 {
1883 eqn eqn = &(pb->subs[e2]);
1884 int var, k;
1885
1886 for (var = n_vars; var >= 0; var--)
1887 eqn->coef[var] *= a;
1888
1889 k = eqn->coef[i];
1890
1891 for (var = n_vars; var >= 0; var--)
1892 eqn->coef[var] -= sub->coef[var] * k / c;
1893
1894 eqn->coef[i] = 0;
1895 divide_eqn_by_gcd (eqn, n_vars);
1896 }
1897
1898 if (dump_file && (dump_flags & TDF_DETAILS))
1899 {
1900 fprintf (dump_file, "cleaned-out wildcard: ");
1901 omega_print_problem (dump_file, pb);
1902 }
1903 break;
1904 }
1905 }
1906
1907 if (renormalize)
1908 normalize_omega_problem (pb);
1909 }
1910
1911 /* Swap values contained in I and J. */
1912
1913 static inline void
1914 swap (int *i, int *j)
1915 {
1916 int tmp;
1917 tmp = *i;
1918 *i = *j;
1919 *j = tmp;
1920 }
1921
1922 /* Swap values contained in I and J. */
1923
1924 static inline void
1925 bswap (bool *i, bool *j)
1926 {
1927 bool tmp;
1928 tmp = *i;
1929 *i = *j;
1930 *j = tmp;
1931 }
1932
1933 /* Make variable IDX unprotected in PB, by swapping its index at the
1934 PB->safe_vars rank. */
1935
1936 static inline void
1937 omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
1938 {
1939 /* If IDX is protected... */
1940 if (*idx < pb->safe_vars)
1941 {
1942 /* ... swap its index with the last non protected index. */
1943 int j = pb->safe_vars;
1944 int e;
1945
1946 for (e = pb->num_geqs - 1; e >= 0; e--)
1947 {
1948 pb->geqs[e].touched = 1;
1949 swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
1950 }
1951
1952 for (e = pb->num_eqs - 1; e >= 0; e--)
1953 swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
1954
1955 for (e = pb->num_subs - 1; e >= 0; e--)
1956 swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
1957
1958 if (unprotect)
1959 bswap (&unprotect[*idx], &unprotect[j]);
1960
1961 swap (&pb->var[*idx], &pb->var[j]);
1962 pb->forwarding_address[pb->var[*idx]] = *idx;
1963 pb->forwarding_address[pb->var[j]] = j;
1964 (*idx)--;
1965 }
1966
1967 /* The variable at pb->safe_vars is also unprotected now. */
1968 pb->safe_vars--;
1969 }
1970
1971 /* During the Fourier-Motzkin elimination some variables are
1972 substituted with other variables. This function resurrects the
1973 substituted variables in PB. */
1974
1975 static void
1976 resurrect_subs (omega_pb pb)
1977 {
1978 if (pb->num_subs > 0
1979 && please_no_equalities_in_simplified_problems == 0)
1980 {
1981 int i, e, m;
1982
1983 if (dump_file && (dump_flags & TDF_DETAILS))
1984 {
1985 fprintf (dump_file,
1986 "problem reduced, bringing variables back to life\n");
1987 omega_print_problem (dump_file, pb);
1988 }
1989
1990 for (i = 1; omega_safe_var_p (pb, i); i++)
1991 if (omega_wildcard_p (pb, i))
1992 omega_unprotect_1 (pb, &i, NULL);
1993
1994 m = pb->num_subs;
1995
1996 for (e = pb->num_geqs - 1; e >= 0; e--)
1997 if (single_var_geq (&pb->geqs[e], pb->num_vars))
1998 {
1999 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
2000 pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
2001 }
2002 else
2003 {
2004 pb->geqs[e].touched = 1;
2005 pb->geqs[e].key = 0;
2006 }
2007
2008 for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
2009 {
2010 pb->var[i + m] = pb->var[i];
2011
2012 for (e = pb->num_geqs - 1; e >= 0; e--)
2013 pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
2014
2015 for (e = pb->num_eqs - 1; e >= 0; e--)
2016 pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
2017
2018 for (e = pb->num_subs - 1; e >= 0; e--)
2019 pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
2020 }
2021
2022 for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
2023 {
2024 for (e = pb->num_geqs - 1; e >= 0; e--)
2025 pb->geqs[e].coef[i] = 0;
2026
2027 for (e = pb->num_eqs - 1; e >= 0; e--)
2028 pb->eqs[e].coef[i] = 0;
2029
2030 for (e = pb->num_subs - 1; e >= 0; e--)
2031 pb->subs[e].coef[i] = 0;
2032 }
2033
2034 pb->num_vars += m;
2035
2036 for (e = pb->num_subs - 1; e >= 0; e--)
2037 {
2038 pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
2039 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
2040 pb->num_vars);
2041 pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
2042 pb->eqs[pb->num_eqs].color = omega_black;
2043
2044 if (dump_file && (dump_flags & TDF_DETAILS))
2045 {
2046 fprintf (dump_file, "brought back: ");
2047 omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
2048 fprintf (dump_file, "\n");
2049 }
2050
2051 pb->num_eqs++;
2052 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2053 }
2054
2055 pb->safe_vars += m;
2056 pb->num_subs = 0;
2057
2058 if (dump_file && (dump_flags & TDF_DETAILS))
2059 {
2060 fprintf (dump_file, "variables brought back to life\n");
2061 omega_print_problem (dump_file, pb);
2062 }
2063
2064 cleanout_wildcards (pb);
2065 }
2066 }
2067
2068 static inline bool
2069 implies (unsigned int a, unsigned int b)
2070 {
2071 return (a == (a & b));
2072 }
2073
2074 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2075 extra step is performed. Returns omega_false when there exist no
2076 solution, omega_true otherwise. */
2077
2078 enum omega_result
2079 omega_eliminate_redundant (omega_pb pb, bool expensive)
2080 {
2081 int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
2082 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2083 omega_pb tmp_problem;
2084
2085 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2086 unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2087 unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2088 unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2089
2090 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2091 unsigned int pp, pz, pn;
2092
2093 if (dump_file && (dump_flags & TDF_DETAILS))
2094 {
2095 fprintf (dump_file, "in eliminate Redundant:\n");
2096 omega_print_problem (dump_file, pb);
2097 }
2098
2099 for (e = pb->num_geqs - 1; e >= 0; e--)
2100 {
2101 int tmp = 1;
2102
2103 is_dead[e] = false;
2104 peqs[e] = zeqs[e] = neqs[e] = 0;
2105
2106 for (i = pb->num_vars; i >= 1; i--)
2107 {
2108 if (pb->geqs[e].coef[i] > 0)
2109 peqs[e] |= tmp;
2110 else if (pb->geqs[e].coef[i] < 0)
2111 neqs[e] |= tmp;
2112 else
2113 zeqs[e] |= tmp;
2114
2115 tmp <<= 1;
2116 }
2117 }
2118
2119
2120 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2121 if (!is_dead[e1])
2122 for (e2 = e1 - 1; e2 >= 0; e2--)
2123 if (!is_dead[e2])
2124 {
2125 for (p = pb->num_vars; p > 1; p--)
2126 for (q = p - 1; q > 0; q--)
2127 if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
2128 - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
2129 goto foundPQ;
2130
2131 continue;
2132
2133 foundPQ:
2134 pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
2135 | (neqs[e1] & peqs[e2]));
2136 pp = peqs[e1] | peqs[e2];
2137 pn = neqs[e1] | neqs[e2];
2138
2139 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2140 if (e3 != e1 && e3 != e2)
2141 {
2142 if (!implies (zeqs[e3], pz))
2143 goto nextE3;
2144
2145 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2146 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2147 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2148 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2149 alpha3 = alpha;
2150
2151 if (alpha1 * alpha2 <= 0)
2152 goto nextE3;
2153
2154 if (alpha1 < 0)
2155 {
2156 alpha1 = -alpha1;
2157 alpha2 = -alpha2;
2158 alpha3 = -alpha3;
2159 }
2160
2161 if (alpha3 > 0)
2162 {
2163 /* Trying to prove e3 is redundant. */
2164 if (!implies (peqs[e3], pp)
2165 || !implies (neqs[e3], pn))
2166 goto nextE3;
2167
2168 if (pb->geqs[e3].color == omega_black
2169 && (pb->geqs[e1].color == omega_red
2170 || pb->geqs[e2].color == omega_red))
2171 goto nextE3;
2172
2173 for (k = pb->num_vars; k >= 1; k--)
2174 if (alpha3 * pb->geqs[e3].coef[k]
2175 != (alpha1 * pb->geqs[e1].coef[k]
2176 + alpha2 * pb->geqs[e2].coef[k]))
2177 goto nextE3;
2178
2179 c = (alpha1 * pb->geqs[e1].coef[0]
2180 + alpha2 * pb->geqs[e2].coef[0]);
2181
2182 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2183 {
2184 if (dump_file && (dump_flags & TDF_DETAILS))
2185 {
2186 fprintf (dump_file,
2187 "found redundant inequality\n");
2188 fprintf (dump_file,
2189 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2190 alpha1, alpha2, alpha3);
2191
2192 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2193 fprintf (dump_file, "\n");
2194 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2195 fprintf (dump_file, "\n=> ");
2196 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2197 fprintf (dump_file, "\n\n");
2198 }
2199
2200 is_dead[e3] = true;
2201 }
2202 }
2203 else
2204 {
2205 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2206 or trying to prove e3 < 0, and therefore the
2207 problem has no solutions. */
2208 if (!implies (peqs[e3], pn)
2209 || !implies (neqs[e3], pp))
2210 goto nextE3;
2211
2212 if (pb->geqs[e1].color == omega_red
2213 || pb->geqs[e2].color == omega_red
2214 || pb->geqs[e3].color == omega_red)
2215 goto nextE3;
2216
2217 alpha3 = alpha3;
2218 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2219 for (k = pb->num_vars; k >= 1; k--)
2220 if (alpha3 * pb->geqs[e3].coef[k]
2221 != (alpha1 * pb->geqs[e1].coef[k]
2222 + alpha2 * pb->geqs[e2].coef[k]))
2223 goto nextE3;
2224
2225 c = (alpha1 * pb->geqs[e1].coef[0]
2226 + alpha2 * pb->geqs[e2].coef[0]);
2227
2228 if (c < alpha3 * (pb->geqs[e3].coef[0]))
2229 {
2230 /* We just proved e3 < 0, so no solutions exist. */
2231 if (dump_file && (dump_flags & TDF_DETAILS))
2232 {
2233 fprintf (dump_file,
2234 "found implied over tight inequality\n");
2235 fprintf (dump_file,
2236 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2237 alpha1, alpha2, -alpha3);
2238 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2239 fprintf (dump_file, "\n");
2240 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2241 fprintf (dump_file, "\n=> not ");
2242 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2243 fprintf (dump_file, "\n\n");
2244 }
2245 free (is_dead);
2246 free (peqs);
2247 free (zeqs);
2248 free (neqs);
2249 return omega_false;
2250 }
2251 else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2252 {
2253 /* We just proved that e3 <=0, so e3 = 0. */
2254 if (dump_file && (dump_flags & TDF_DETAILS))
2255 {
2256 fprintf (dump_file,
2257 "found implied tight inequality\n");
2258 fprintf (dump_file,
2259 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2260 alpha1, alpha2, -alpha3);
2261 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2262 fprintf (dump_file, "\n");
2263 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2264 fprintf (dump_file, "\n=> inverse ");
2265 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2266 fprintf (dump_file, "\n\n");
2267 }
2268
2269 omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2270 &pb->geqs[e3], pb->num_vars);
2271 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2272 adding_equality_constraint (pb, pb->num_eqs - 1);
2273 is_dead[e3] = true;
2274 }
2275 }
2276 nextE3:;
2277 }
2278 }
2279
2280 /* Delete the inequalities that were marked as dead. */
2281 for (e = pb->num_geqs - 1; e >= 0; e--)
2282 if (is_dead[e])
2283 omega_delete_geq (pb, e, pb->num_vars);
2284
2285 if (!expensive)
2286 goto eliminate_redundant_done;
2287
2288 tmp_problem = XNEW (struct omega_pb_d);
2289 conservative++;
2290
2291 for (e = pb->num_geqs - 1; e >= 0; e--)
2292 {
2293 if (dump_file && (dump_flags & TDF_DETAILS))
2294 {
2295 fprintf (dump_file,
2296 "checking equation %d to see if it is redundant: ", e);
2297 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2298 fprintf (dump_file, "\n");
2299 }
2300
2301 omega_copy_problem (tmp_problem, pb);
2302 omega_negate_geq (tmp_problem, e);
2303 tmp_problem->safe_vars = 0;
2304 tmp_problem->variables_freed = false;
2305
2306 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2307 omega_delete_geq (pb, e, pb->num_vars);
2308 }
2309
2310 free (tmp_problem);
2311 conservative--;
2312
2313 if (!omega_reduce_with_subs)
2314 {
2315 resurrect_subs (pb);
2316 gcc_assert (please_no_equalities_in_simplified_problems
2317 || pb->num_subs == 0);
2318 }
2319
2320 eliminate_redundant_done:
2321 free (is_dead);
2322 free (peqs);
2323 free (zeqs);
2324 free (neqs);
2325 return omega_true;
2326 }
2327
2328 /* For each inequality that has coefficients bigger than 20, try to
2329 create a new constraint that cannot be derived from the original
2330 constraint and that has smaller coefficients. Add the new
2331 constraint at the end of geqs. Return the number of inequalities
2332 that have been added to PB. */
2333
2334 static int
2335 smooth_weird_equations (omega_pb pb)
2336 {
2337 int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2338 int c;
2339 int v;
2340 int result = 0;
2341
2342 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2343 if (pb->geqs[e1].color == omega_black)
2344 {
2345 int g = 999999;
2346
2347 for (v = pb->num_vars; v >= 1; v--)
2348 if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2349 g = abs (pb->geqs[e1].coef[v]);
2350
2351 /* Magic number. */
2352 if (g > 20)
2353 {
2354 e3 = pb->num_geqs;
2355
2356 for (v = pb->num_vars; v >= 1; v--)
2357 pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2358 g);
2359
2360 pb->geqs[e3].color = omega_black;
2361 pb->geqs[e3].touched = 1;
2362 /* Magic number. */
2363 pb->geqs[e3].coef[0] = 9997;
2364
2365 if (dump_file && (dump_flags & TDF_DETAILS))
2366 {
2367 fprintf (dump_file, "Checking to see if we can derive: ");
2368 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2369 fprintf (dump_file, "\n from: ");
2370 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2371 fprintf (dump_file, "\n");
2372 }
2373
2374 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2375 if (e1 != e2 && pb->geqs[e2].color == omega_black)
2376 {
2377 for (p = pb->num_vars; p > 1; p--)
2378 {
2379 for (q = p - 1; q > 0; q--)
2380 {
2381 alpha =
2382 (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2383 pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2384 if (alpha != 0)
2385 goto foundPQ;
2386 }
2387 }
2388 continue;
2389
2390 foundPQ:
2391
2392 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2393 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2394 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2395 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2396 alpha3 = alpha;
2397
2398 if (alpha1 * alpha2 <= 0)
2399 continue;
2400
2401 if (alpha1 < 0)
2402 {
2403 alpha1 = -alpha1;
2404 alpha2 = -alpha2;
2405 alpha3 = -alpha3;
2406 }
2407
2408 if (alpha3 > 0)
2409 {
2410 /* Try to prove e3 is redundant: verify
2411 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2412 for (k = pb->num_vars; k >= 1; k--)
2413 if (alpha3 * pb->geqs[e3].coef[k]
2414 != (alpha1 * pb->geqs[e1].coef[k]
2415 + alpha2 * pb->geqs[e2].coef[k]))
2416 goto nextE2;
2417
2418 c = alpha1 * pb->geqs[e1].coef[0]
2419 + alpha2 * pb->geqs[e2].coef[0];
2420
2421 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2422 pb->geqs[e3].coef[0] = int_div (c, alpha3);
2423 }
2424 nextE2:;
2425 }
2426
2427 if (pb->geqs[e3].coef[0] < 9997)
2428 {
2429 result++;
2430 pb->num_geqs++;
2431
2432 if (dump_file && (dump_flags & TDF_DETAILS))
2433 {
2434 fprintf (dump_file,
2435 "Smoothing weird equations; adding:\n");
2436 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2437 fprintf (dump_file, "\nto:\n");
2438 omega_print_problem (dump_file, pb);
2439 fprintf (dump_file, "\n\n");
2440 }
2441 }
2442 }
2443 }
2444 return result;
2445 }
2446
2447 /* Replace tuples of inequalities, that define upper and lower half
2448 spaces, with an equation. */
2449
2450 static void
2451 coalesce (omega_pb pb)
2452 {
2453 int e, e2;
2454 int colors = 0;
2455 bool *is_dead;
2456 int found_something = 0;
2457
2458 for (e = 0; e < pb->num_geqs; e++)
2459 if (pb->geqs[e].color == omega_red)
2460 colors++;
2461
2462 if (colors < 2)
2463 return;
2464
2465 is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2466
2467 for (e = 0; e < pb->num_geqs; e++)
2468 is_dead[e] = false;
2469
2470 for (e = 0; e < pb->num_geqs; e++)
2471 if (pb->geqs[e].color == omega_red
2472 && !pb->geqs[e].touched)
2473 for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2474 if (!pb->geqs[e2].touched
2475 && pb->geqs[e].key == -pb->geqs[e2].key
2476 && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2477 && pb->geqs[e2].color == omega_red)
2478 {
2479 omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2480 pb->num_vars);
2481 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2482 found_something++;
2483 is_dead[e] = true;
2484 is_dead[e2] = true;
2485 }
2486
2487 for (e = pb->num_geqs - 1; e >= 0; e--)
2488 if (is_dead[e])
2489 omega_delete_geq (pb, e, pb->num_vars);
2490
2491 if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2492 {
2493 fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2494 found_something);
2495 omega_print_problem (dump_file, pb);
2496 }
2497
2498 free (is_dead);
2499 }
2500
2501 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2502 true, continue to eliminate all the red inequalities. */
2503
2504 void
2505 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2506 {
2507 int e, e2, e3, i, j, k, a, alpha1, alpha2;
2508 int c = 0;
2509 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2510 int dead_count = 0;
2511 int red_found;
2512 omega_pb tmp_problem;
2513
2514 if (dump_file && (dump_flags & TDF_DETAILS))
2515 {
2516 fprintf (dump_file, "in eliminate RED:\n");
2517 omega_print_problem (dump_file, pb);
2518 }
2519
2520 if (pb->num_eqs > 0)
2521 omega_simplify_problem (pb);
2522
2523 for (e = pb->num_geqs - 1; e >= 0; e--)
2524 is_dead[e] = false;
2525
2526 for (e = pb->num_geqs - 1; e >= 0; e--)
2527 if (pb->geqs[e].color == omega_black && !is_dead[e])
2528 for (e2 = e - 1; e2 >= 0; e2--)
2529 if (pb->geqs[e2].color == omega_black
2530 && !is_dead[e2])
2531 {
2532 a = 0;
2533
2534 for (i = pb->num_vars; i > 1; i--)
2535 for (j = i - 1; j > 0; j--)
2536 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2537 - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2538 goto found_pair;
2539
2540 continue;
2541
2542 found_pair:
2543 if (dump_file && (dump_flags & TDF_DETAILS))
2544 {
2545 fprintf (dump_file,
2546 "found two equations to combine, i = %s, ",
2547 omega_variable_to_str (pb, i));
2548 fprintf (dump_file, "j = %s, alpha = %d\n",
2549 omega_variable_to_str (pb, j), a);
2550 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2551 fprintf (dump_file, "\n");
2552 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2553 fprintf (dump_file, "\n");
2554 }
2555
2556 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2557 if (pb->geqs[e3].color == omega_red)
2558 {
2559 alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2560 - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2561 alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2562 - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2563
2564 if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2565 || (a < 0 && alpha1 < 0 && alpha2 < 0))
2566 {
2567 if (dump_file && (dump_flags & TDF_DETAILS))
2568 {
2569 fprintf (dump_file,
2570 "alpha1 = %d, alpha2 = %d;"
2571 "comparing against: ",
2572 alpha1, alpha2);
2573 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2574 fprintf (dump_file, "\n");
2575 }
2576
2577 for (k = pb->num_vars; k >= 0; k--)
2578 {
2579 c = (alpha1 * pb->geqs[e].coef[k]
2580 + alpha2 * pb->geqs[e2].coef[k]);
2581
2582 if (c != a * pb->geqs[e3].coef[k])
2583 break;
2584
2585 if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2586 fprintf (dump_file, " %s: %d, %d\n",
2587 omega_variable_to_str (pb, k), c,
2588 a * pb->geqs[e3].coef[k]);
2589 }
2590
2591 if (k < 0
2592 || (k == 0 &&
2593 ((a > 0 && c < a * pb->geqs[e3].coef[k])
2594 || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2595 {
2596 if (dump_file && (dump_flags & TDF_DETAILS))
2597 {
2598 dead_count++;
2599 fprintf (dump_file,
2600 "red equation#%d is dead "
2601 "(%d dead so far, %d remain)\n",
2602 e3, dead_count,
2603 pb->num_geqs - dead_count);
2604 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2605 fprintf (dump_file, "\n");
2606 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2607 fprintf (dump_file, "\n");
2608 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2609 fprintf (dump_file, "\n");
2610 }
2611 is_dead[e3] = true;
2612 }
2613 }
2614 }
2615 }
2616
2617 for (e = pb->num_geqs - 1; e >= 0; e--)
2618 if (is_dead[e])
2619 omega_delete_geq (pb, e, pb->num_vars);
2620
2621 free (is_dead);
2622
2623 if (dump_file && (dump_flags & TDF_DETAILS))
2624 {
2625 fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2626 omega_print_problem (dump_file, pb);
2627 }
2628
2629 for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2630 if (pb->geqs[e].color == omega_red)
2631 red_found = 1;
2632
2633 if (!red_found)
2634 {
2635 if (dump_file && (dump_flags & TDF_DETAILS))
2636 fprintf (dump_file, "fast checks worked\n");
2637
2638 if (!omega_reduce_with_subs)
2639 gcc_assert (please_no_equalities_in_simplified_problems
2640 || pb->num_subs == 0);
2641
2642 return;
2643 }
2644
2645 if (!omega_verify_simplification
2646 && verify_omega_pb (pb) == omega_false)
2647 return;
2648
2649 conservative++;
2650 tmp_problem = XNEW (struct omega_pb_d);
2651
2652 for (e = pb->num_geqs - 1; e >= 0; e--)
2653 if (pb->geqs[e].color == omega_red)
2654 {
2655 if (dump_file && (dump_flags & TDF_DETAILS))
2656 {
2657 fprintf (dump_file,
2658 "checking equation %d to see if it is redundant: ", e);
2659 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2660 fprintf (dump_file, "\n");
2661 }
2662
2663 omega_copy_problem (tmp_problem, pb);
2664 omega_negate_geq (tmp_problem, e);
2665 tmp_problem->safe_vars = 0;
2666 tmp_problem->variables_freed = false;
2667 tmp_problem->num_subs = 0;
2668
2669 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2670 {
2671 if (dump_file && (dump_flags & TDF_DETAILS))
2672 fprintf (dump_file, "it is redundant\n");
2673 omega_delete_geq (pb, e, pb->num_vars);
2674 }
2675 else
2676 {
2677 if (dump_file && (dump_flags & TDF_DETAILS))
2678 fprintf (dump_file, "it is not redundant\n");
2679
2680 if (!eliminate_all)
2681 {
2682 if (dump_file && (dump_flags & TDF_DETAILS))
2683 fprintf (dump_file, "no need to check other red equations\n");
2684 break;
2685 }
2686 }
2687 }
2688
2689 conservative--;
2690 free (tmp_problem);
2691 /* omega_simplify_problem (pb); */
2692
2693 if (!omega_reduce_with_subs)
2694 gcc_assert (please_no_equalities_in_simplified_problems
2695 || pb->num_subs == 0);
2696 }
2697
2698 /* Transform some wildcard variables to non-safe variables. */
2699
2700 static void
2701 chain_unprotect (omega_pb pb)
2702 {
2703 int i, e;
2704 bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2705
2706 for (i = 1; omega_safe_var_p (pb, i); i++)
2707 {
2708 unprotect[i] = omega_wildcard_p (pb, i);
2709
2710 for (e = pb->num_subs - 1; e >= 0; e--)
2711 if (pb->subs[e].coef[i])
2712 unprotect[i] = false;
2713 }
2714
2715 if (dump_file && (dump_flags & TDF_DETAILS))
2716 {
2717 fprintf (dump_file, "Doing chain reaction unprotection\n");
2718 omega_print_problem (dump_file, pb);
2719
2720 for (i = 1; omega_safe_var_p (pb, i); i++)
2721 if (unprotect[i])
2722 fprintf (dump_file, "unprotecting %s\n",
2723 omega_variable_to_str (pb, i));
2724 }
2725
2726 for (i = 1; omega_safe_var_p (pb, i); i++)
2727 if (unprotect[i])
2728 omega_unprotect_1 (pb, &i, unprotect);
2729
2730 if (dump_file && (dump_flags & TDF_DETAILS))
2731 {
2732 fprintf (dump_file, "After chain reactions\n");
2733 omega_print_problem (dump_file, pb);
2734 }
2735
2736 free (unprotect);
2737 }
2738
2739 /* Reduce problem PB. */
2740
2741 static void
2742 omega_problem_reduced (omega_pb pb)
2743 {
2744 if (omega_verify_simplification
2745 && !in_approximate_mode
2746 && verify_omega_pb (pb) == omega_false)
2747 return;
2748
2749 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2750 && !omega_eliminate_redundant (pb, true))
2751 return;
2752
2753 omega_found_reduction = omega_true;
2754
2755 if (!please_no_equalities_in_simplified_problems)
2756 coalesce (pb);
2757
2758 if (omega_reduce_with_subs
2759 || please_no_equalities_in_simplified_problems)
2760 chain_unprotect (pb);
2761 else
2762 resurrect_subs (pb);
2763
2764 if (!return_single_result)
2765 {
2766 int i;
2767
2768 for (i = 1; omega_safe_var_p (pb, i); i++)
2769 pb->forwarding_address[pb->var[i]] = i;
2770
2771 for (i = 0; i < pb->num_subs; i++)
2772 pb->forwarding_address[pb->subs[i].key] = -i - 1;
2773
2774 (*omega_when_reduced) (pb);
2775 }
2776
2777 if (dump_file && (dump_flags & TDF_DETAILS))
2778 {
2779 fprintf (dump_file, "-------------------------------------------\n");
2780 fprintf (dump_file, "problem reduced:\n");
2781 omega_print_problem (dump_file, pb);
2782 fprintf (dump_file, "-------------------------------------------\n");
2783 }
2784 }
2785
2786 /* Eliminates all the free variables for problem PB, that is all the
2787 variables from FV to PB->NUM_VARS. */
2788
2789 static void
2790 omega_free_eliminations (omega_pb pb, int fv)
2791 {
2792 bool try_again = true;
2793 int i, e, e2;
2794 int n_vars = pb->num_vars;
2795
2796 while (try_again)
2797 {
2798 try_again = false;
2799
2800 for (i = n_vars; i > fv; i--)
2801 {
2802 for (e = pb->num_geqs - 1; e >= 0; e--)
2803 if (pb->geqs[e].coef[i])
2804 break;
2805
2806 if (e < 0)
2807 e2 = e;
2808 else if (pb->geqs[e].coef[i] > 0)
2809 {
2810 for (e2 = e - 1; e2 >= 0; e2--)
2811 if (pb->geqs[e2].coef[i] < 0)
2812 break;
2813 }
2814 else
2815 {
2816 for (e2 = e - 1; e2 >= 0; e2--)
2817 if (pb->geqs[e2].coef[i] > 0)
2818 break;
2819 }
2820
2821 if (e2 < 0)
2822 {
2823 int e3;
2824 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2825 if (pb->subs[e3].coef[i])
2826 break;
2827
2828 if (e3 >= 0)
2829 continue;
2830
2831 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2832 if (pb->eqs[e3].coef[i])
2833 break;
2834
2835 if (e3 >= 0)
2836 continue;
2837
2838 if (dump_file && (dump_flags & TDF_DETAILS))
2839 fprintf (dump_file, "a free elimination of %s\n",
2840 omega_variable_to_str (pb, i));
2841
2842 if (e >= 0)
2843 {
2844 omega_delete_geq (pb, e, n_vars);
2845
2846 for (e--; e >= 0; e--)
2847 if (pb->geqs[e].coef[i])
2848 omega_delete_geq (pb, e, n_vars);
2849
2850 try_again = (i < n_vars);
2851 }
2852
2853 omega_delete_variable (pb, i);
2854 n_vars = pb->num_vars;
2855 }
2856 }
2857 }
2858
2859 if (dump_file && (dump_flags & TDF_DETAILS))
2860 {
2861 fprintf (dump_file, "\nafter free eliminations:\n");
2862 omega_print_problem (dump_file, pb);
2863 fprintf (dump_file, "\n");
2864 }
2865 }
2866
2867 /* Do free red eliminations. */
2868
2869 static void
2870 free_red_eliminations (omega_pb pb)
2871 {
2872 bool try_again = true;
2873 int i, e, e2;
2874 int n_vars = pb->num_vars;
2875 bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2876 bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2877 bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2878
2879 for (i = n_vars; i > 0; i--)
2880 {
2881 is_red_var[i] = false;
2882 is_dead_var[i] = false;
2883 }
2884
2885 for (e = pb->num_geqs - 1; e >= 0; e--)
2886 {
2887 is_dead_geq[e] = false;
2888
2889 if (pb->geqs[e].color == omega_red)
2890 for (i = n_vars; i > 0; i--)
2891 if (pb->geqs[e].coef[i] != 0)
2892 is_red_var[i] = true;
2893 }
2894
2895 while (try_again)
2896 {
2897 try_again = false;
2898 for (i = n_vars; i > 0; i--)
2899 if (!is_red_var[i] && !is_dead_var[i])
2900 {
2901 for (e = pb->num_geqs - 1; e >= 0; e--)
2902 if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2903 break;
2904
2905 if (e < 0)
2906 e2 = e;
2907 else if (pb->geqs[e].coef[i] > 0)
2908 {
2909 for (e2 = e - 1; e2 >= 0; e2--)
2910 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2911 break;
2912 }
2913 else
2914 {
2915 for (e2 = e - 1; e2 >= 0; e2--)
2916 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2917 break;
2918 }
2919
2920 if (e2 < 0)
2921 {
2922 int e3;
2923 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2924 if (pb->subs[e3].coef[i])
2925 break;
2926
2927 if (e3 >= 0)
2928 continue;
2929
2930 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2931 if (pb->eqs[e3].coef[i])
2932 break;
2933
2934 if (e3 >= 0)
2935 continue;
2936
2937 if (dump_file && (dump_flags & TDF_DETAILS))
2938 fprintf (dump_file, "a free red elimination of %s\n",
2939 omega_variable_to_str (pb, i));
2940
2941 for (; e >= 0; e--)
2942 if (pb->geqs[e].coef[i])
2943 is_dead_geq[e] = true;
2944
2945 try_again = true;
2946 is_dead_var[i] = true;
2947 }
2948 }
2949 }
2950
2951 for (e = pb->num_geqs - 1; e >= 0; e--)
2952 if (is_dead_geq[e])
2953 omega_delete_geq (pb, e, n_vars);
2954
2955 for (i = n_vars; i > 0; i--)
2956 if (is_dead_var[i])
2957 omega_delete_variable (pb, i);
2958
2959 if (dump_file && (dump_flags & TDF_DETAILS))
2960 {
2961 fprintf (dump_file, "\nafter free red eliminations:\n");
2962 omega_print_problem (dump_file, pb);
2963 fprintf (dump_file, "\n");
2964 }
2965
2966 free (is_red_var);
2967 free (is_dead_var);
2968 free (is_dead_geq);
2969 }
2970
2971 /* For equation EQ of the form "0 = EQN", insert in PB two
2972 inequalities "0 <= EQN" and "0 <= -EQN". */
2973
2974 void
2975 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2976 {
2977 int i;
2978
2979 if (dump_file && (dump_flags & TDF_DETAILS))
2980 fprintf (dump_file, "Converting Eq to Geqs\n");
2981
2982 /* Insert "0 <= EQN". */
2983 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2984 pb->geqs[pb->num_geqs].touched = 1;
2985 pb->num_geqs++;
2986
2987 /* Insert "0 <= -EQN". */
2988 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2989 pb->geqs[pb->num_geqs].touched = 1;
2990
2991 for (i = 0; i <= pb->num_vars; i++)
2992 pb->geqs[pb->num_geqs].coef[i] *= -1;
2993
2994 pb->num_geqs++;
2995
2996 if (dump_file && (dump_flags & TDF_DETAILS))
2997 omega_print_problem (dump_file, pb);
2998 }
2999
3000 /* Eliminates variable I from PB. */
3001
3002 static void
3003 omega_do_elimination (omega_pb pb, int e, int i)
3004 {
3005 eqn sub = omega_alloc_eqns (0, 1);
3006 int c;
3007 int n_vars = pb->num_vars;
3008
3009 if (dump_file && (dump_flags & TDF_DETAILS))
3010 fprintf (dump_file, "eliminating variable %s\n",
3011 omega_variable_to_str (pb, i));
3012
3013 omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
3014 c = sub->coef[i];
3015 sub->coef[i] = 0;
3016 if (c == 1 || c == -1)
3017 {
3018 if (pb->eqs[e].color == omega_red)
3019 {
3020 bool fB;
3021 omega_substitute_red (pb, sub, i, c, &fB);
3022 if (fB)
3023 omega_convert_eq_to_geqs (pb, e);
3024 else
3025 omega_delete_variable (pb, i);
3026 }
3027 else
3028 {
3029 omega_substitute (pb, sub, i, c);
3030 omega_delete_variable (pb, i);
3031 }
3032 }
3033 else
3034 {
3035 int a = abs (c);
3036 int e2 = e;
3037
3038 if (dump_file && (dump_flags & TDF_DETAILS))
3039 fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
3040
3041 for (e = pb->num_eqs - 1; e >= 0; e--)
3042 if (pb->eqs[e].coef[i])
3043 {
3044 eqn eqn = &(pb->eqs[e]);
3045 int j, k;
3046 for (j = n_vars; j >= 0; j--)
3047 eqn->coef[j] *= a;
3048 k = eqn->coef[i];
3049 eqn->coef[i] = 0;
3050 if (sub->color == omega_red)
3051 eqn->color = omega_red;
3052 for (j = n_vars; j >= 0; j--)
3053 eqn->coef[j] -= sub->coef[j] * k / c;
3054 }
3055
3056 for (e = pb->num_geqs - 1; e >= 0; e--)
3057 if (pb->geqs[e].coef[i])
3058 {
3059 eqn eqn = &(pb->geqs[e]);
3060 int j, k;
3061
3062 if (sub->color == omega_red)
3063 eqn->color = omega_red;
3064
3065 for (j = n_vars; j >= 0; j--)
3066 eqn->coef[j] *= a;
3067
3068 eqn->touched = 1;
3069 k = eqn->coef[i];
3070 eqn->coef[i] = 0;
3071
3072 for (j = n_vars; j >= 0; j--)
3073 eqn->coef[j] -= sub->coef[j] * k / c;
3074
3075 }
3076
3077 for (e = pb->num_subs - 1; e >= 0; e--)
3078 if (pb->subs[e].coef[i])
3079 {
3080 eqn eqn = &(pb->subs[e]);
3081 int j, k;
3082 gcc_assert (0);
3083 gcc_assert (sub->color == omega_black);
3084 for (j = n_vars; j >= 0; j--)
3085 eqn->coef[j] *= a;
3086 k = eqn->coef[i];
3087 eqn->coef[i] = 0;
3088 for (j = n_vars; j >= 0; j--)
3089 eqn->coef[j] -= sub->coef[j] * k / c;
3090 }
3091
3092 if (in_approximate_mode)
3093 omega_delete_variable (pb, i);
3094 else
3095 omega_convert_eq_to_geqs (pb, e2);
3096 }
3097
3098 omega_free_eqns (sub, 1);
3099 }
3100
3101 /* Helper function for printing "sorry, no solution". */
3102
3103 static inline enum omega_result
3104 omega_problem_has_no_solution (void)
3105 {
3106 if (dump_file && (dump_flags & TDF_DETAILS))
3107 fprintf (dump_file, "\nequations have no solution \n");
3108
3109 return omega_false;
3110 }
3111
3112 /* Helper function: solve equations in PB one at a time, following the
3113 DESIRED_RES result. */
3114
3115 static enum omega_result
3116 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3117 {
3118 int i, j, e;
3119 int g, g2;
3120 g = 0;
3121
3122
3123 if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3124 {
3125 fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3126 desired_res, may_be_red);
3127 omega_print_problem (dump_file, pb);
3128 fprintf (dump_file, "\n");
3129 }
3130
3131 if (may_be_red)
3132 {
3133 i = 0;
3134 j = pb->num_eqs - 1;
3135
3136 while (1)
3137 {
3138 eqn eq;
3139
3140 while (i <= j && pb->eqs[i].color == omega_red)
3141 i++;
3142
3143 while (i <= j && pb->eqs[j].color == omega_black)
3144 j--;
3145
3146 if (i >= j)
3147 break;
3148
3149 eq = omega_alloc_eqns (0, 1);
3150 omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3151 omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3152 omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3153 omega_free_eqns (eq, 1);
3154 i++;
3155 j--;
3156 }
3157 }
3158
3159 /* Eliminate all EQ equations */
3160 for (e = pb->num_eqs - 1; e >= 0; e--)
3161 {
3162 eqn eqn = &(pb->eqs[e]);
3163 int sv;
3164
3165 if (dump_file && (dump_flags & TDF_DETAILS))
3166 fprintf (dump_file, "----\n");
3167
3168 for (i = pb->num_vars; i > 0; i--)
3169 if (eqn->coef[i])
3170 break;
3171
3172 g = eqn->coef[i];
3173
3174 for (j = i - 1; j > 0; j--)
3175 if (eqn->coef[j])
3176 break;
3177
3178 /* i is the position of last nonzero coefficient,
3179 g is the coefficient of i,
3180 j is the position of next nonzero coefficient. */
3181
3182 if (j == 0)
3183 {
3184 if (eqn->coef[0] % g != 0)
3185 return omega_problem_has_no_solution ();
3186
3187 eqn->coef[0] = eqn->coef[0] / g;
3188 eqn->coef[i] = 1;
3189 pb->num_eqs--;
3190 omega_do_elimination (pb, e, i);
3191 continue;
3192 }
3193
3194 else if (j == -1)
3195 {
3196 if (eqn->coef[0] != 0)
3197 return omega_problem_has_no_solution ();
3198
3199 pb->num_eqs--;
3200 continue;
3201 }
3202
3203 if (g < 0)
3204 g = -g;
3205
3206 if (g == 1)
3207 {
3208 pb->num_eqs--;
3209 omega_do_elimination (pb, e, i);
3210 }
3211
3212 else
3213 {
3214 int k = j;
3215 bool promotion_possible =
3216 (omega_safe_var_p (pb, j)
3217 && pb->safe_vars + 1 == i
3218 && !omega_eqn_is_red (eqn, desired_res)
3219 && !in_approximate_mode);
3220
3221 if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3222 fprintf (dump_file, " Promotion possible\n");
3223
3224 normalizeEQ:
3225 if (!omega_safe_var_p (pb, j))
3226 {
3227 for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3228 g = gcd (abs (eqn->coef[j]), g);
3229 g2 = g;
3230 }
3231 else if (!omega_safe_var_p (pb, i))
3232 g2 = g;
3233 else
3234 g2 = 0;
3235
3236 for (; g != 1 && j > 0; j--)
3237 g = gcd (abs (eqn->coef[j]), g);
3238
3239 if (g > 1)
3240 {
3241 if (eqn->coef[0] % g != 0)
3242 return omega_problem_has_no_solution ();
3243
3244 for (j = 0; j <= pb->num_vars; j++)
3245 eqn->coef[j] /= g;
3246
3247 g2 = g2 / g;
3248 }
3249
3250 if (g2 > 1)
3251 {
3252 int e2;
3253
3254 for (e2 = e - 1; e2 >= 0; e2--)
3255 if (pb->eqs[e2].coef[i])
3256 break;
3257
3258 if (e2 == -1)
3259 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3260 if (pb->geqs[e2].coef[i])
3261 break;
3262
3263 if (e2 == -1)
3264 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3265 if (pb->subs[e2].coef[i])
3266 break;
3267
3268 if (e2 == -1)
3269 {
3270 bool change = false;
3271
3272 if (dump_file && (dump_flags & TDF_DETAILS))
3273 {
3274 fprintf (dump_file, "Ha! We own it! \n");
3275 omega_print_eq (dump_file, pb, eqn);
3276 fprintf (dump_file, " \n");
3277 }
3278
3279 g = eqn->coef[i];
3280 g = abs (g);
3281
3282 for (j = i - 1; j >= 0; j--)
3283 {
3284 int t = int_mod (eqn->coef[j], g);
3285
3286 if (2 * t >= g)
3287 t -= g;
3288
3289 if (t != eqn->coef[j])
3290 {
3291 eqn->coef[j] = t;
3292 change = true;
3293 }
3294 }
3295
3296 if (!change)
3297 {
3298 if (dump_file && (dump_flags & TDF_DETAILS))
3299 fprintf (dump_file, "So what?\n");
3300 }
3301
3302 else
3303 {
3304 omega_name_wild_card (pb, i);
3305
3306 if (dump_file && (dump_flags & TDF_DETAILS))
3307 {
3308 omega_print_eq (dump_file, pb, eqn);
3309 fprintf (dump_file, " \n");
3310 }
3311
3312 e++;
3313 continue;
3314 }
3315 }
3316 }
3317
3318 if (promotion_possible)
3319 {
3320 if (dump_file && (dump_flags & TDF_DETAILS))
3321 {
3322 fprintf (dump_file, "promoting %s to safety\n",
3323 omega_variable_to_str (pb, i));
3324 omega_print_vars (dump_file, pb);
3325 }
3326
3327 pb->safe_vars++;
3328
3329 if (!omega_wildcard_p (pb, i))
3330 omega_name_wild_card (pb, i);
3331
3332 promotion_possible = false;
3333 j = k;
3334 goto normalizeEQ;
3335 }
3336
3337 if (g2 > 1 && !in_approximate_mode)
3338 {
3339 if (pb->eqs[e].color == omega_red)
3340 {
3341 if (dump_file && (dump_flags & TDF_DETAILS))
3342 fprintf (dump_file, "handling red equality\n");
3343
3344 pb->num_eqs--;
3345 omega_do_elimination (pb, e, i);
3346 continue;
3347 }
3348
3349 if (dump_file && (dump_flags & TDF_DETAILS))
3350 {
3351 fprintf (dump_file,
3352 "adding equation to handle safe variable \n");
3353 omega_print_eq (dump_file, pb, eqn);
3354 fprintf (dump_file, "\n----\n");
3355 omega_print_problem (dump_file, pb);
3356 fprintf (dump_file, "\n----\n");
3357 fprintf (dump_file, "\n----\n");
3358 }
3359
3360 i = omega_add_new_wild_card (pb);
3361 pb->num_eqs++;
3362 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3363 omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3364 omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3365
3366 for (j = pb->num_vars; j >= 0; j--)
3367 {
3368 pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3369
3370 if (2 * pb->eqs[e + 1].coef[j] >= g2)
3371 pb->eqs[e + 1].coef[j] -= g2;
3372 }
3373
3374 pb->eqs[e + 1].coef[i] = g2;
3375 e += 2;
3376
3377 if (dump_file && (dump_flags & TDF_DETAILS))
3378 omega_print_problem (dump_file, pb);
3379
3380 continue;
3381 }
3382
3383 sv = pb->safe_vars;
3384 if (g2 == 0)
3385 sv = 0;
3386
3387 /* Find variable to eliminate. */
3388 if (g2 > 1)
3389 {
3390 gcc_assert (in_approximate_mode);
3391
3392 if (dump_file && (dump_flags & TDF_DETAILS))
3393 {
3394 fprintf (dump_file, "non-exact elimination: ");
3395 omega_print_eq (dump_file, pb, eqn);
3396 fprintf (dump_file, "\n");
3397 omega_print_problem (dump_file, pb);
3398 }
3399
3400 for (i = pb->num_vars; i > sv; i--)
3401 if (pb->eqs[e].coef[i] != 0)
3402 break;
3403 }
3404 else
3405 for (i = pb->num_vars; i > sv; i--)
3406 if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3407 break;
3408
3409 if (i > sv)
3410 {
3411 pb->num_eqs--;
3412 omega_do_elimination (pb, e, i);
3413
3414 if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3415 {
3416 fprintf (dump_file, "result of non-exact elimination:\n");
3417 omega_print_problem (dump_file, pb);
3418 }
3419 }
3420 else
3421 {
3422 int factor = (INT_MAX);
3423 j = 0;
3424
3425 if (dump_file && (dump_flags & TDF_DETAILS))
3426 fprintf (dump_file, "doing moding\n");
3427
3428 for (i = pb->num_vars; i != sv; i--)
3429 if ((pb->eqs[e].coef[i] & 1) != 0)
3430 {
3431 j = i;
3432 i--;
3433
3434 for (; i != sv; i--)
3435 if ((pb->eqs[e].coef[i] & 1) != 0)
3436 break;
3437
3438 break;
3439 }
3440
3441 if (j != 0 && i == sv)
3442 {
3443 omega_do_mod (pb, 2, e, j);
3444 e++;
3445 continue;
3446 }
3447
3448 j = 0;
3449 for (i = pb->num_vars; i != sv; i--)
3450 if (pb->eqs[e].coef[i] != 0
3451 && factor > abs (pb->eqs[e].coef[i]) + 1)
3452 {
3453 factor = abs (pb->eqs[e].coef[i]) + 1;
3454 j = i;
3455 }
3456
3457 if (j == sv)
3458 {
3459 if (dump_file && (dump_flags & TDF_DETAILS))
3460 fprintf (dump_file, "should not have happened\n");
3461 gcc_assert (0);
3462 }
3463
3464 omega_do_mod (pb, factor, e, j);
3465 /* Go back and try this equation again. */
3466 e++;
3467 }
3468 }
3469 }
3470
3471 pb->num_eqs = 0;
3472 return omega_unknown;
3473 }
3474
3475 /* Transform an inequation E to an equality, then solve DIFF problems
3476 based on PB, and only differing by the constant part that is
3477 diminished by one, trying to figure out which of the constants
3478 satisfies PB. */
3479
3480 static enum omega_result
3481 parallel_splinter (omega_pb pb, int e, int diff,
3482 enum omega_result desired_res)
3483 {
3484 omega_pb tmp_problem;
3485 int i;
3486
3487 if (dump_file && (dump_flags & TDF_DETAILS))
3488 {
3489 fprintf (dump_file, "Using parallel splintering\n");
3490 omega_print_problem (dump_file, pb);
3491 }
3492
3493 tmp_problem = XNEW (struct omega_pb_d);
3494 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3495 pb->num_eqs = 1;
3496
3497 for (i = 0; i <= diff; i++)
3498 {
3499 omega_copy_problem (tmp_problem, pb);
3500
3501 if (dump_file && (dump_flags & TDF_DETAILS))
3502 {
3503 fprintf (dump_file, "Splinter # %i\n", i);
3504 omega_print_problem (dump_file, pb);
3505 }
3506
3507 if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3508 {
3509 free (tmp_problem);
3510 return omega_true;
3511 }
3512
3513 pb->eqs[0].coef[0]--;
3514 }
3515
3516 free (tmp_problem);
3517 return omega_false;
3518 }
3519
3520 /* Helper function: solve equations one at a time. */
3521
3522 static enum omega_result
3523 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3524 {
3525 int i, e;
3526 int n_vars, fv;
3527 enum omega_result result;
3528 bool coupled_subscripts = false;
3529 bool smoothed = false;
3530 bool eliminate_again;
3531 bool tried_eliminating_redundant = false;
3532
3533 if (desired_res != omega_simplify)
3534 {
3535 pb->num_subs = 0;
3536 pb->safe_vars = 0;
3537 }
3538
3539 solve_geq_start:
3540 do {
3541 gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3542
3543 /* Verify that there are not too many inequalities. */
3544 gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3545
3546 if (dump_file && (dump_flags & TDF_DETAILS))
3547 {
3548 fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3549 desired_res, please_no_equalities_in_simplified_problems);
3550 omega_print_problem (dump_file, pb);
3551 fprintf (dump_file, "\n");
3552 }
3553
3554 n_vars = pb->num_vars;
3555
3556 if (n_vars == 1)
3557 {
3558 enum omega_eqn_color u_color = omega_black;
3559 enum omega_eqn_color l_color = omega_black;
3560 int upper_bound = pos_infinity;
3561 int lower_bound = neg_infinity;
3562
3563 for (e = pb->num_geqs - 1; e >= 0; e--)
3564 {
3565 int a = pb->geqs[e].coef[1];
3566 int c = pb->geqs[e].coef[0];
3567
3568 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3569 if (a == 0)
3570 {
3571 if (c < 0)
3572 return omega_problem_has_no_solution ();
3573 }
3574 else if (a > 0)
3575 {
3576 if (a != 1)
3577 c = int_div (c, a);
3578
3579 if (lower_bound < -c
3580 || (lower_bound == -c
3581 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3582 {
3583 lower_bound = -c;
3584 l_color = pb->geqs[e].color;
3585 }
3586 }
3587 else
3588 {
3589 if (a != -1)
3590 c = int_div (c, -a);
3591
3592 if (upper_bound > c
3593 || (upper_bound == c
3594 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3595 {
3596 upper_bound = c;
3597 u_color = pb->geqs[e].color;
3598 }
3599 }
3600 }
3601
3602 if (dump_file && (dump_flags & TDF_DETAILS))
3603 {
3604 fprintf (dump_file, "upper bound = %d\n", upper_bound);
3605 fprintf (dump_file, "lower bound = %d\n", lower_bound);
3606 }
3607
3608 if (lower_bound > upper_bound)
3609 return omega_problem_has_no_solution ();
3610
3611 if (desired_res == omega_simplify)
3612 {
3613 pb->num_geqs = 0;
3614 if (pb->safe_vars == 1)
3615 {
3616
3617 if (lower_bound == upper_bound
3618 && u_color == omega_black
3619 && l_color == omega_black)
3620 {
3621 pb->eqs[0].coef[0] = -lower_bound;
3622 pb->eqs[0].coef[1] = 1;
3623 pb->eqs[0].color = omega_black;
3624 pb->num_eqs = 1;
3625 return omega_solve_problem (pb, desired_res);
3626 }
3627 else
3628 {
3629 if (lower_bound > neg_infinity)
3630 {
3631 pb->geqs[0].coef[0] = -lower_bound;
3632 pb->geqs[0].coef[1] = 1;
3633 pb->geqs[0].key = 1;
3634 pb->geqs[0].color = l_color;
3635 pb->geqs[0].touched = 0;
3636 pb->num_geqs = 1;
3637 }
3638
3639 if (upper_bound < pos_infinity)
3640 {
3641 pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3642 pb->geqs[pb->num_geqs].coef[1] = -1;
3643 pb->geqs[pb->num_geqs].key = -1;
3644 pb->geqs[pb->num_geqs].color = u_color;
3645 pb->geqs[pb->num_geqs].touched = 0;
3646 pb->num_geqs++;
3647 }
3648 }
3649 }
3650 else
3651 pb->num_vars = 0;
3652
3653 omega_problem_reduced (pb);
3654 return omega_false;
3655 }
3656
3657 if (original_problem != no_problem
3658 && l_color == omega_black
3659 && u_color == omega_black
3660 && !conservative
3661 && lower_bound == upper_bound)
3662 {
3663 pb->eqs[0].coef[0] = -lower_bound;
3664 pb->eqs[0].coef[1] = 1;
3665 pb->num_eqs = 1;
3666 adding_equality_constraint (pb, 0);
3667 }
3668
3669 return omega_true;
3670 }
3671
3672 if (!pb->variables_freed)
3673 {
3674 pb->variables_freed = true;
3675
3676 if (desired_res != omega_simplify)
3677 omega_free_eliminations (pb, 0);
3678 else
3679 omega_free_eliminations (pb, pb->safe_vars);
3680
3681 n_vars = pb->num_vars;
3682
3683 if (n_vars == 1)
3684 continue;
3685 }
3686
3687 switch (normalize_omega_problem (pb))
3688 {
3689 case normalize_false:
3690 return omega_false;
3691 break;
3692
3693 case normalize_coupled:
3694 coupled_subscripts = true;
3695 break;
3696
3697 case normalize_uncoupled:
3698 coupled_subscripts = false;
3699 break;
3700
3701 default:
3702 gcc_unreachable ();
3703 }
3704
3705 n_vars = pb->num_vars;
3706
3707 if (dump_file && (dump_flags & TDF_DETAILS))
3708 {
3709 fprintf (dump_file, "\nafter normalization:\n");
3710 omega_print_problem (dump_file, pb);
3711 fprintf (dump_file, "\n");
3712 fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3713 }
3714
3715 do {
3716 int parallel_difference = INT_MAX;
3717 int best_parallel_eqn = -1;
3718 int minC, maxC, minCj = 0;
3719 int lower_bound_count = 0;
3720 int e2, Le = 0, Ue;
3721 bool possible_easy_int_solution;
3722 int max_splinters = 1;
3723 bool exact = false;
3724 bool lucky_exact = false;
3725 int best = (INT_MAX);
3726 int j = 0, jLe = 0, jLowerBoundCount = 0;
3727
3728
3729 eliminate_again = false;
3730
3731 if (pb->num_eqs > 0)
3732 return omega_solve_problem (pb, desired_res);
3733
3734 if (!coupled_subscripts)
3735 {
3736 if (pb->safe_vars == 0)
3737 pb->num_geqs = 0;
3738 else
3739 for (e = pb->num_geqs - 1; e >= 0; e--)
3740 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3741 omega_delete_geq (pb, e, n_vars);
3742
3743 pb->num_vars = pb->safe_vars;
3744
3745 if (desired_res == omega_simplify)
3746 {
3747 omega_problem_reduced (pb);
3748 return omega_false;
3749 }
3750
3751 return omega_true;
3752 }
3753
3754 if (desired_res != omega_simplify)
3755 fv = 0;
3756 else
3757 fv = pb->safe_vars;
3758
3759 if (pb->num_geqs == 0)
3760 {
3761 if (desired_res == omega_simplify)
3762 {
3763 pb->num_vars = pb->safe_vars;
3764 omega_problem_reduced (pb);
3765 return omega_false;
3766 }
3767 return omega_true;
3768 }
3769
3770 if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3771 {
3772 omega_problem_reduced (pb);
3773 return omega_false;
3774 }
3775
3776 if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3777 || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3778 {
3779 if (dump_file && (dump_flags & TDF_DETAILS))
3780 fprintf (dump_file,
3781 "TOO MANY EQUATIONS; "
3782 "%d equations, %d variables, "
3783 "ELIMINATING REDUNDANT ONES\n",
3784 pb->num_geqs, n_vars);
3785
3786 if (!omega_eliminate_redundant (pb, false))
3787 return omega_false;
3788
3789 n_vars = pb->num_vars;
3790
3791 if (pb->num_eqs > 0)
3792 return omega_solve_problem (pb, desired_res);
3793
3794 if (dump_file && (dump_flags & TDF_DETAILS))
3795 fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3796 }
3797
3798 if (desired_res != omega_simplify)
3799 fv = 0;
3800 else
3801 fv = pb->safe_vars;
3802
3803 for (i = n_vars; i != fv; i--)
3804 {
3805 int score;
3806 int ub = -2;
3807 int lb = -2;
3808 bool lucky = false;
3809 int upper_bound_count = 0;
3810
3811 lower_bound_count = 0;
3812 minC = maxC = 0;
3813
3814 for (e = pb->num_geqs - 1; e >= 0; e--)
3815 if (pb->geqs[e].coef[i] < 0)
3816 {
3817 minC = MIN (minC, pb->geqs[e].coef[i]);
3818 upper_bound_count++;
3819 if (pb->geqs[e].coef[i] < -1)
3820 {
3821 if (ub == -2)
3822 ub = e;
3823 else
3824 ub = -1;
3825 }
3826 }
3827 else if (pb->geqs[e].coef[i] > 0)
3828 {
3829 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3830 lower_bound_count++;
3831 Le = e;
3832 if (pb->geqs[e].coef[i] > 1)
3833 {
3834 if (lb == -2)
3835 lb = e;
3836 else
3837 lb = -1;
3838 }
3839 }
3840
3841 if (lower_bound_count == 0
3842 || upper_bound_count == 0)
3843 {
3844 lower_bound_count = 0;
3845 break;
3846 }
3847
3848 if (ub >= 0 && lb >= 0
3849 && pb->geqs[lb].key == -pb->geqs[ub].key)
3850 {
3851 int Lc = pb->geqs[lb].coef[i];
3852 int Uc = -pb->geqs[ub].coef[i];
3853 int diff =
3854 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3855 lucky = (diff >= (Uc - 1) * (Lc - 1));
3856 }
3857
3858 if (maxC == 1
3859 || minC == -1
3860 || lucky
3861 || in_approximate_mode)
3862 {
3863 score = upper_bound_count * lower_bound_count;
3864
3865 if (dump_file && (dump_flags & TDF_DETAILS))
3866 fprintf (dump_file,
3867 "For %s, exact, score = %d*%d, range = %d ... %d,"
3868 "\nlucky = %d, in_approximate_mode=%d \n",
3869 omega_variable_to_str (pb, i),
3870 upper_bound_count,
3871 lower_bound_count, minC, maxC, lucky,
3872 in_approximate_mode);
3873
3874 if (!exact
3875 || score < best)
3876 {
3877
3878 best = score;
3879 j = i;
3880 minCj = minC;
3881 jLe = Le;
3882 jLowerBoundCount = lower_bound_count;
3883 exact = true;
3884 lucky_exact = lucky;
3885 if (score == 1)
3886 break;
3887 }
3888 }
3889 else if (!exact)
3890 {
3891 if (dump_file && (dump_flags & TDF_DETAILS))
3892 fprintf (dump_file,
3893 "For %s, non-exact, score = %d*%d,"
3894 "range = %d ... %d \n",
3895 omega_variable_to_str (pb, i),
3896 upper_bound_count,
3897 lower_bound_count, minC, maxC);
3898
3899 score = maxC - minC;
3900
3901 if (best > score)
3902 {
3903 best = score;
3904 j = i;
3905 minCj = minC;
3906 jLe = Le;
3907 jLowerBoundCount = lower_bound_count;
3908 }
3909 }
3910 }
3911
3912 if (lower_bound_count == 0)
3913 {
3914 omega_free_eliminations (pb, pb->safe_vars);
3915 n_vars = pb->num_vars;
3916 eliminate_again = true;
3917 continue;
3918 }
3919
3920 i = j;
3921 minC = minCj;
3922 Le = jLe;
3923 lower_bound_count = jLowerBoundCount;
3924
3925 for (e = pb->num_geqs - 1; e >= 0; e--)
3926 if (pb->geqs[e].coef[i] > 0)
3927 {
3928 if (pb->geqs[e].coef[i] == -minC)
3929 max_splinters += -minC - 1;
3930 else
3931 max_splinters +=
3932 check_pos_mul ((pb->geqs[e].coef[i] - 1),
3933 (-minC - 1)) / (-minC) + 1;
3934 }
3935
3936 /* #ifdef Omega3 */
3937 /* Trying to produce exact elimination by finding redundant
3938 constraints. */
3939 if (!exact && !tried_eliminating_redundant)
3940 {
3941 omega_eliminate_redundant (pb, false);
3942 tried_eliminating_redundant = true;
3943 eliminate_again = true;
3944 continue;
3945 }
3946 tried_eliminating_redundant = false;
3947 /* #endif */
3948
3949 if (return_single_result && desired_res == omega_simplify && !exact)
3950 {
3951 omega_problem_reduced (pb);
3952 return omega_true;
3953 }
3954
3955 /* #ifndef Omega3 */
3956 /* Trying to produce exact elimination by finding redundant
3957 constraints. */
3958 if (!exact && !tried_eliminating_redundant)
3959 {
3960 omega_eliminate_redundant (pb, false);
3961 tried_eliminating_redundant = true;
3962 continue;
3963 }
3964 tried_eliminating_redundant = false;
3965 /* #endif */
3966
3967 if (!exact)
3968 {
3969 int e1, e2;
3970
3971 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3972 if (pb->geqs[e1].color == omega_black)
3973 for (e2 = e1 - 1; e2 >= 0; e2--)
3974 if (pb->geqs[e2].color == omega_black
3975 && pb->geqs[e1].key == -pb->geqs[e2].key
3976 && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3977 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3978 / 2 < parallel_difference))
3979 {
3980 parallel_difference =
3981 (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3982 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3983 / 2;
3984 best_parallel_eqn = e1;
3985 }
3986
3987 if (dump_file && (dump_flags & TDF_DETAILS)
3988 && best_parallel_eqn >= 0)
3989 {
3990 fprintf (dump_file,
3991 "Possible parallel projection, diff = %d, in ",
3992 parallel_difference);
3993 omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3994 fprintf (dump_file, "\n");
3995 omega_print_problem (dump_file, pb);
3996 }
3997 }
3998
3999 if (dump_file && (dump_flags & TDF_DETAILS))
4000 {
4001 fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
4002 omega_variable_to_str (pb, i), i, minC,
4003 lower_bound_count);
4004 omega_print_problem (dump_file, pb);
4005
4006 if (lucky_exact)
4007 fprintf (dump_file, "(a lucky exact elimination)\n");
4008
4009 else if (exact)
4010 fprintf (dump_file, "(an exact elimination)\n");
4011
4012 fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
4013 }
4014
4015 gcc_assert (max_splinters >= 1);
4016
4017 if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
4018 && parallel_difference <= max_splinters)
4019 return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
4020 desired_res);
4021
4022 smoothed = false;
4023
4024 if (i != n_vars)
4025 {
4026 int t;
4027 int j = pb->num_vars;
4028
4029 if (dump_file && (dump_flags & TDF_DETAILS))
4030 {
4031 fprintf (dump_file, "Swapping %d and %d\n", i, j);
4032 omega_print_problem (dump_file, pb);
4033 }
4034
4035 swap (&pb->var[i], &pb->var[j]);
4036
4037 for (e = pb->num_geqs - 1; e >= 0; e--)
4038 if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
4039 {
4040 pb->geqs[e].touched = 1;
4041 t = pb->geqs[e].coef[i];
4042 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
4043 pb->geqs[e].coef[j] = t;
4044 }
4045
4046 for (e = pb->num_subs - 1; e >= 0; e--)
4047 if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
4048 {
4049 t = pb->subs[e].coef[i];
4050 pb->subs[e].coef[i] = pb->subs[e].coef[j];
4051 pb->subs[e].coef[j] = t;
4052 }
4053
4054 if (dump_file && (dump_flags & TDF_DETAILS))
4055 {
4056 fprintf (dump_file, "Swapping complete \n");
4057 omega_print_problem (dump_file, pb);
4058 fprintf (dump_file, "\n");
4059 }
4060
4061 i = j;
4062 }
4063
4064 else if (dump_file && (dump_flags & TDF_DETAILS))
4065 {
4066 fprintf (dump_file, "No swap needed\n");
4067 omega_print_problem (dump_file, pb);
4068 }
4069
4070 pb->num_vars--;
4071 n_vars = pb->num_vars;
4072
4073 if (exact)
4074 {
4075 if (n_vars == 1)
4076 {
4077 int upper_bound = pos_infinity;
4078 int lower_bound = neg_infinity;
4079 enum omega_eqn_color ub_color = omega_black;
4080 enum omega_eqn_color lb_color = omega_black;
4081 int topeqn = pb->num_geqs - 1;
4082 int Lc = pb->geqs[Le].coef[i];
4083
4084 for (Le = topeqn; Le >= 0; Le--)
4085 if ((Lc = pb->geqs[Le].coef[i]) == 0)
4086 {
4087 if (pb->geqs[Le].coef[1] == 1)
4088 {
4089 int constantTerm = -pb->geqs[Le].coef[0];
4090
4091 if (constantTerm > lower_bound ||
4092 (constantTerm == lower_bound &&
4093 !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
4094 {
4095 lower_bound = constantTerm;
4096 lb_color = pb->geqs[Le].color;
4097 }
4098
4099 if (dump_file && (dump_flags & TDF_DETAILS))
4100 {
4101 if (pb->geqs[Le].color == omega_black)
4102 fprintf (dump_file, " :::=> %s >= %d\n",
4103 omega_variable_to_str (pb, 1),
4104 constantTerm);
4105 else
4106 fprintf (dump_file,
4107 " :::=> [%s >= %d]\n",
4108 omega_variable_to_str (pb, 1),
4109 constantTerm);
4110 }
4111 }
4112 else
4113 {
4114 int constantTerm = pb->geqs[Le].coef[0];
4115 if (constantTerm < upper_bound ||
4116 (constantTerm == upper_bound
4117 && !omega_eqn_is_red (&pb->geqs[Le],
4118 desired_res)))
4119 {
4120 upper_bound = constantTerm;
4121 ub_color = pb->geqs[Le].color;
4122 }
4123
4124 if (dump_file && (dump_flags & TDF_DETAILS))
4125 {
4126 if (pb->geqs[Le].color == omega_black)
4127 fprintf (dump_file, " :::=> %s <= %d\n",
4128 omega_variable_to_str (pb, 1),
4129 constantTerm);
4130 else
4131 fprintf (dump_file,
4132 " :::=> [%s <= %d]\n",
4133 omega_variable_to_str (pb, 1),
4134 constantTerm);
4135 }
4136 }
4137 }
4138 else if (Lc > 0)
4139 for (Ue = topeqn; Ue >= 0; Ue--)
4140 if (pb->geqs[Ue].coef[i] < 0
4141 && pb->geqs[Le].key != -pb->geqs[Ue].key)
4142 {
4143 int Uc = -pb->geqs[Ue].coef[i];
4144 int coefficient = pb->geqs[Ue].coef[1] * Lc
4145 + pb->geqs[Le].coef[1] * Uc;
4146 int constantTerm = pb->geqs[Ue].coef[0] * Lc
4147 + pb->geqs[Le].coef[0] * Uc;
4148
4149 if (dump_file && (dump_flags & TDF_DETAILS))
4150 {
4151 omega_print_geq_extra (dump_file, pb,
4152 &(pb->geqs[Ue]));
4153 fprintf (dump_file, "\n");
4154 omega_print_geq_extra (dump_file, pb,
4155 &(pb->geqs[Le]));
4156 fprintf (dump_file, "\n");
4157 }
4158
4159 if (coefficient > 0)
4160 {
4161 constantTerm = -int_div (constantTerm, coefficient);
4162
4163 if (constantTerm > lower_bound
4164 || (constantTerm == lower_bound
4165 && (desired_res != omega_simplify
4166 || (pb->geqs[Ue].color == omega_black
4167 && pb->geqs[Le].color == omega_black))))
4168 {
4169 lower_bound = constantTerm;
4170 lb_color = (pb->geqs[Ue].color == omega_red
4171 || pb->geqs[Le].color == omega_red)
4172 ? omega_red : omega_black;
4173 }
4174
4175 if (dump_file && (dump_flags & TDF_DETAILS))
4176 {
4177 if (pb->geqs[Ue].color == omega_red
4178 || pb->geqs[Le].color == omega_red)
4179 fprintf (dump_file,
4180 " ::=> [%s >= %d]\n",
4181 omega_variable_to_str (pb, 1),
4182 constantTerm);
4183 else
4184 fprintf (dump_file,
4185 " ::=> %s >= %d\n",
4186 omega_variable_to_str (pb, 1),
4187 constantTerm);
4188 }
4189 }
4190 else
4191 {
4192 constantTerm = int_div (constantTerm, -coefficient);
4193 if (constantTerm < upper_bound
4194 || (constantTerm == upper_bound
4195 && pb->geqs[Ue].color == omega_black
4196 && pb->geqs[Le].color == omega_black))
4197 {
4198 upper_bound = constantTerm;
4199 ub_color = (pb->geqs[Ue].color == omega_red
4200 || pb->geqs[Le].color == omega_red)
4201 ? omega_red : omega_black;
4202 }
4203
4204 if (dump_file
4205 && (dump_flags & TDF_DETAILS))
4206 {
4207 if (pb->geqs[Ue].color == omega_red
4208 || pb->geqs[Le].color == omega_red)
4209 fprintf (dump_file,
4210 " ::=> [%s <= %d]\n",
4211 omega_variable_to_str (pb, 1),
4212 constantTerm);
4213 else
4214 fprintf (dump_file,
4215 " ::=> %s <= %d\n",
4216 omega_variable_to_str (pb, 1),
4217 constantTerm);
4218 }
4219 }
4220 }
4221
4222 pb->num_geqs = 0;
4223
4224 if (dump_file && (dump_flags & TDF_DETAILS))
4225 fprintf (dump_file,
4226 " therefore, %c%d <= %c%s%c <= %d%c\n",
4227 lb_color == omega_red ? '[' : ' ', lower_bound,
4228 (lb_color == omega_red && ub_color == omega_black)
4229 ? ']' : ' ',
4230 omega_variable_to_str (pb, 1),
4231 (lb_color == omega_black && ub_color == omega_red)
4232 ? '[' : ' ',
4233 upper_bound, ub_color == omega_red ? ']' : ' ');
4234
4235 if (lower_bound > upper_bound)
4236 return omega_false;
4237
4238 if (pb->safe_vars == 1)
4239 {
4240 if (upper_bound == lower_bound
4241 && !(ub_color == omega_red || lb_color == omega_red)
4242 && !please_no_equalities_in_simplified_problems)
4243 {
4244 pb->num_eqs++;
4245 pb->eqs[0].coef[1] = -1;
4246 pb->eqs[0].coef[0] = upper_bound;
4247
4248 if (ub_color == omega_red
4249 || lb_color == omega_red)
4250 pb->eqs[0].color = omega_red;
4251
4252 if (desired_res == omega_simplify
4253 && pb->eqs[0].color == omega_black)
4254 return omega_solve_problem (pb, desired_res);
4255 }
4256
4257 if (upper_bound != pos_infinity)
4258 {
4259 pb->geqs[0].coef[1] = -1;
4260 pb->geqs[0].coef[0] = upper_bound;
4261 pb->geqs[0].color = ub_color;
4262 pb->geqs[0].key = -1;
4263 pb->geqs[0].touched = 0;
4264 pb->num_geqs++;
4265 }
4266
4267 if (lower_bound != neg_infinity)
4268 {
4269 pb->geqs[pb->num_geqs].coef[1] = 1;
4270 pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
4271 pb->geqs[pb->num_geqs].color = lb_color;
4272 pb->geqs[pb->num_geqs].key = 1;
4273 pb->geqs[pb->num_geqs].touched = 0;
4274 pb->num_geqs++;
4275 }
4276 }
4277
4278 if (desired_res == omega_simplify)
4279 {
4280 omega_problem_reduced (pb);
4281 return omega_false;
4282 }
4283 else
4284 {
4285 if (!conservative
4286 && (desired_res != omega_simplify
4287 || (lb_color == omega_black
4288 && ub_color == omega_black))
4289 && original_problem != no_problem
4290 && lower_bound == upper_bound)
4291 {
4292 for (i = original_problem->num_vars; i >= 0; i--)
4293 if (original_problem->var[i] == pb->var[1])
4294 break;
4295
4296 if (i == 0)
4297 break;
4298
4299 e = original_problem->num_eqs++;
4300 omega_init_eqn_zero (&original_problem->eqs[e],
4301 original_problem->num_vars);
4302 original_problem->eqs[e].coef[i] = -1;
4303 original_problem->eqs[e].coef[0] = upper_bound;
4304
4305 if (dump_file && (dump_flags & TDF_DETAILS))
4306 {
4307 fprintf (dump_file,
4308 "adding equality %d to outer problem\n", e);
4309 omega_print_problem (dump_file, original_problem);
4310 }
4311 }
4312 return omega_true;
4313 }
4314 }
4315
4316 eliminate_again = true;
4317
4318 if (lower_bound_count == 1)
4319 {
4320 eqn lbeqn = omega_alloc_eqns (0, 1);
4321 int Lc = pb->geqs[Le].coef[i];
4322
4323 if (dump_file && (dump_flags & TDF_DETAILS))
4324 fprintf (dump_file, "an inplace elimination\n");
4325
4326 omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
4327 omega_delete_geq_extra (pb, Le, n_vars + 1);
4328
4329 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4330 if (pb->geqs[Ue].coef[i] < 0)
4331 {
4332 if (lbeqn->key == -pb->geqs[Ue].key)
4333 omega_delete_geq_extra (pb, Ue, n_vars + 1);
4334 else
4335 {
4336 int k;
4337 int Uc = -pb->geqs[Ue].coef[i];
4338 pb->geqs[Ue].touched = 1;
4339 eliminate_again = false;
4340
4341 if (lbeqn->color == omega_red)
4342 pb->geqs[Ue].color = omega_red;
4343
4344 for (k = 0; k <= n_vars; k++)
4345 pb->geqs[Ue].coef[k] =
4346 check_mul (pb->geqs[Ue].coef[k], Lc) +
4347 check_mul (lbeqn->coef[k], Uc);
4348
4349 if (dump_file && (dump_flags & TDF_DETAILS))
4350 {
4351 omega_print_geq (dump_file, pb,
4352 &(pb->geqs[Ue]));
4353 fprintf (dump_file, "\n");
4354 }
4355 }
4356 }
4357
4358 omega_free_eqns (lbeqn, 1);
4359 continue;
4360 }
4361 else
4362 {
4363 int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
4364 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
4365 int num_dead = 0;
4366 int top_eqn = pb->num_geqs - 1;
4367 lower_bound_count--;
4368
4369 if (dump_file && (dump_flags & TDF_DETAILS))
4370 fprintf (dump_file, "lower bound count = %d\n",
4371 lower_bound_count);
4372
4373 for (Le = top_eqn; Le >= 0; Le--)
4374 if (pb->geqs[Le].coef[i] > 0)
4375 {
4376 int Lc = pb->geqs[Le].coef[i];
4377 for (Ue = top_eqn; Ue >= 0; Ue--)
4378 if (pb->geqs[Ue].coef[i] < 0)
4379 {
4380 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4381 {
4382 int k;
4383 int Uc = -pb->geqs[Ue].coef[i];
4384
4385 if (num_dead == 0)
4386 e2 = pb->num_geqs++;
4387 else
4388 e2 = dead_eqns[--num_dead];
4389
4390 gcc_assert (e2 < OMEGA_MAX_GEQS);
4391
4392 if (dump_file && (dump_flags & TDF_DETAILS))
4393 {
4394 fprintf (dump_file,
4395 "Le = %d, Ue = %d, gen = %d\n",
4396 Le, Ue, e2);
4397 omega_print_geq_extra (dump_file, pb,
4398 &(pb->geqs[Le]));
4399 fprintf (dump_file, "\n");
4400 omega_print_geq_extra (dump_file, pb,
4401 &(pb->geqs[Ue]));
4402 fprintf (dump_file, "\n");
4403 }
4404
4405 eliminate_again = false;
4406
4407 for (k = n_vars; k >= 0; k--)
4408 pb->geqs[e2].coef[k] =
4409 check_mul (pb->geqs[Ue].coef[k], Lc) +
4410 check_mul (pb->geqs[Le].coef[k], Uc);
4411
4412 pb->geqs[e2].coef[n_vars + 1] = 0;
4413 pb->geqs[e2].touched = 1;
4414
4415 if (pb->geqs[Ue].color == omega_red
4416 || pb->geqs[Le].color == omega_red)
4417 pb->geqs[e2].color = omega_red;
4418 else
4419 pb->geqs[e2].color = omega_black;
4420
4421 if (dump_file && (dump_flags & TDF_DETAILS))
4422 {
4423 omega_print_geq (dump_file, pb,
4424 &(pb->geqs[e2]));
4425 fprintf (dump_file, "\n");
4426 }
4427 }
4428
4429 if (lower_bound_count == 0)
4430 {
4431 dead_eqns[num_dead++] = Ue;
4432
4433 if (dump_file && (dump_flags & TDF_DETAILS))
4434 fprintf (dump_file, "Killed %d\n", Ue);
4435 }
4436 }
4437
4438 lower_bound_count--;
4439 dead_eqns[num_dead++] = Le;
4440
4441 if (dump_file && (dump_flags & TDF_DETAILS))
4442 fprintf (dump_file, "Killed %d\n", Le);
4443 }
4444
4445 for (e = pb->num_geqs - 1; e >= 0; e--)
4446 is_dead[e] = false;
4447
4448 while (num_dead > 0)
4449 is_dead[dead_eqns[--num_dead]] = true;
4450
4451 for (e = pb->num_geqs - 1; e >= 0; e--)
4452 if (is_dead[e])
4453 omega_delete_geq_extra (pb, e, n_vars + 1);
4454
4455 free (dead_eqns);
4456 free (is_dead);
4457 continue;
4458 }
4459 }
4460 else
4461 {
4462 omega_pb rS, iS;
4463
4464 rS = omega_alloc_problem (0, 0);
4465 iS = omega_alloc_problem (0, 0);
4466 e2 = 0;
4467 possible_easy_int_solution = true;
4468
4469 for (e = 0; e < pb->num_geqs; e++)
4470 if (pb->geqs[e].coef[i] == 0)
4471 {
4472 omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
4473 pb->num_vars);
4474 omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
4475 pb->num_vars);
4476
4477 if (dump_file && (dump_flags & TDF_DETAILS))
4478 {
4479 int t;
4480 fprintf (dump_file, "Copying (%d, %d): ", i,
4481 pb->geqs[e].coef[i]);
4482 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
4483 fprintf (dump_file, "\n");
4484 for (t = 0; t <= n_vars + 1; t++)
4485 fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
4486 fprintf (dump_file, "\n");
4487
4488 }
4489 e2++;
4490 gcc_assert (e2 < OMEGA_MAX_GEQS);
4491 }
4492
4493 for (Le = pb->num_geqs - 1; Le >= 0; Le--)
4494 if (pb->geqs[Le].coef[i] > 0)
4495 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4496 if (pb->geqs[Ue].coef[i] < 0)
4497 {
4498 int k;
4499 int Lc = pb->geqs[Le].coef[i];
4500 int Uc = -pb->geqs[Ue].coef[i];
4501
4502 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4503 {
4504
4505 rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
4506
4507 if (dump_file && (dump_flags & TDF_DETAILS))
4508 {
4509 fprintf (dump_file, "---\n");
4510 fprintf (dump_file,
4511 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4512 Le, Lc, Ue, Uc, e2);
4513 omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
4514 fprintf (dump_file, "\n");
4515 omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
4516 fprintf (dump_file, "\n");
4517 }
4518
4519 if (Uc == Lc)
4520 {
4521 for (k = n_vars; k >= 0; k--)
4522 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4523 pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
4524
4525 iS->geqs[e2].coef[0] -= (Uc - 1);
4526 }
4527 else
4528 {
4529 for (k = n_vars; k >= 0; k--)
4530 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4531 check_mul (pb->geqs[Ue].coef[k], Lc) +
4532 check_mul (pb->geqs[Le].coef[k], Uc);
4533
4534 iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
4535 }
4536
4537 if (pb->geqs[Ue].color == omega_red
4538 || pb->geqs[Le].color == omega_red)
4539 iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
4540 else
4541 iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
4542
4543 if (dump_file && (dump_flags & TDF_DETAILS))
4544 {
4545 omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
4546 fprintf (dump_file, "\n");
4547 }
4548
4549 e2++;
4550 gcc_assert (e2 < OMEGA_MAX_GEQS);
4551 }
4552 else if (pb->geqs[Ue].coef[0] * Lc +
4553 pb->geqs[Le].coef[0] * Uc -
4554 (Uc - 1) * (Lc - 1) < 0)
4555 possible_easy_int_solution = false;
4556 }
4557
4558 iS->variables_initialized = rS->variables_initialized = true;
4559 iS->num_vars = rS->num_vars = pb->num_vars;
4560 iS->num_geqs = rS->num_geqs = e2;
4561 iS->num_eqs = rS->num_eqs = 0;
4562 iS->num_subs = rS->num_subs = pb->num_subs;
4563 iS->safe_vars = rS->safe_vars = pb->safe_vars;
4564
4565 for (e = n_vars; e >= 0; e--)
4566 rS->var[e] = pb->var[e];
4567
4568 for (e = n_vars; e >= 0; e--)
4569 iS->var[e] = pb->var[e];
4570
4571 for (e = pb->num_subs - 1; e >= 0; e--)
4572 {
4573 omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
4574 omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
4575 }
4576
4577 pb->num_vars++;
4578 n_vars = pb->num_vars;
4579
4580 if (desired_res != omega_true)
4581 {
4582 if (original_problem == no_problem)
4583 {
4584 original_problem = pb;
4585 result = omega_solve_geq (rS, omega_false);
4586 original_problem = no_problem;
4587 }
4588 else
4589 result = omega_solve_geq (rS, omega_false);
4590
4591 if (result == omega_false)
4592 {
4593 free (rS);
4594 free (iS);
4595 return result;
4596 }
4597
4598 if (pb->num_eqs > 0)
4599 {
4600 /* An equality constraint must have been found */
4601 free (rS);
4602 free (iS);
4603 return omega_solve_problem (pb, desired_res);
4604 }
4605 }
4606
4607 if (desired_res != omega_false)
4608 {
4609 int j;
4610 int lower_bounds = 0;
4611 int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
4612
4613 if (possible_easy_int_solution)
4614 {
4615 conservative++;
4616 result = omega_solve_geq (iS, desired_res);
4617 conservative--;
4618
4619 if (result != omega_false)
4620 {
4621 free (rS);
4622 free (iS);
4623 free (lower_bound);
4624 return result;
4625 }
4626 }
4627
4628 if (!exact && best_parallel_eqn >= 0
4629 && parallel_difference <= max_splinters)
4630 {
4631 free (rS);
4632 free (iS);
4633 free (lower_bound);
4634 return parallel_splinter (pb, best_parallel_eqn,
4635 parallel_difference,
4636 desired_res);
4637 }
4638
4639 if (dump_file && (dump_flags & TDF_DETAILS))
4640 fprintf (dump_file, "have to do exact analysis\n");
4641
4642 conservative++;
4643
4644 for (e = 0; e < pb->num_geqs; e++)
4645 if (pb->geqs[e].coef[i] > 1)
4646 lower_bound[lower_bounds++] = e;
4647
4648 /* Sort array LOWER_BOUND. */
4649 for (j = 0; j < lower_bounds; j++)
4650 {
4651 int k, smallest = j;
4652
4653 for (k = j + 1; k < lower_bounds; k++)
4654 if (pb->geqs[lower_bound[smallest]].coef[i] >
4655 pb->geqs[lower_bound[k]].coef[i])
4656 smallest = k;
4657
4658 k = lower_bound[smallest];
4659 lower_bound[smallest] = lower_bound[j];
4660 lower_bound[j] = k;
4661 }
4662
4663 if (dump_file && (dump_flags & TDF_DETAILS))
4664 {
4665 fprintf (dump_file, "lower bound coefficients = ");
4666
4667 for (j = 0; j < lower_bounds; j++)
4668 fprintf (dump_file, " %d",
4669 pb->geqs[lower_bound[j]].coef[i]);
4670
4671 fprintf (dump_file, "\n");
4672 }
4673
4674 for (j = 0; j < lower_bounds; j++)
4675 {
4676 int max_incr;
4677 int c;
4678 int worst_lower_bound_constant = -minC;
4679
4680 e = lower_bound[j];
4681 max_incr = (((pb->geqs[e].coef[i] - 1) *
4682 (worst_lower_bound_constant - 1) - 1)
4683 / worst_lower_bound_constant);
4684 /* max_incr += 2; */
4685
4686 if (dump_file && (dump_flags & TDF_DETAILS))
4687 {
4688 fprintf (dump_file, "for equation ");
4689 omega_print_geq (dump_file, pb, &pb->geqs[e]);
4690 fprintf (dump_file,
4691 "\ntry decrements from 0 to %d\n",
4692 max_incr);
4693 omega_print_problem (dump_file, pb);
4694 }
4695
4696 if (max_incr > 50 && !smoothed
4697 && smooth_weird_equations (pb))
4698 {
4699 conservative--;
4700 free (rS);
4701 free (iS);
4702 smoothed = true;
4703 goto solve_geq_start;
4704 }
4705
4706 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4707 pb->num_vars);
4708 pb->eqs[0].color = omega_black;
4709 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4710 pb->geqs[e].touched = 1;
4711 pb->num_eqs = 1;
4712
4713 for (c = max_incr; c >= 0; c--)
4714 {
4715 if (dump_file && (dump_flags & TDF_DETAILS))
4716 {
4717 fprintf (dump_file,
4718 "trying next decrement of %d\n",
4719 max_incr - c);
4720 omega_print_problem (dump_file, pb);
4721 }
4722
4723 omega_copy_problem (rS, pb);
4724
4725 if (dump_file && (dump_flags & TDF_DETAILS))
4726 omega_print_problem (dump_file, rS);
4727
4728 result = omega_solve_problem (rS, desired_res);
4729
4730 if (result == omega_true)
4731 {
4732 free (rS);
4733 free (iS);
4734 free (lower_bound);
4735 conservative--;
4736 return omega_true;
4737 }
4738
4739 pb->eqs[0].coef[0]--;
4740 }
4741
4742 if (j + 1 < lower_bounds)
4743 {
4744 pb->num_eqs = 0;
4745 omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4746 pb->num_vars);
4747 pb->geqs[e].touched = 1;
4748 pb->geqs[e].color = omega_black;
4749 omega_copy_problem (rS, pb);
4750
4751 if (dump_file && (dump_flags & TDF_DETAILS))
4752 fprintf (dump_file,
4753 "exhausted lower bound, "
4754 "checking if still feasible ");
4755
4756 result = omega_solve_problem (rS, omega_false);
4757
4758 if (result == omega_false)
4759 break;
4760 }
4761 }
4762
4763 if (dump_file && (dump_flags & TDF_DETAILS))
4764 fprintf (dump_file, "fall-off the end\n");
4765
4766 free (rS);
4767 free (iS);
4768 free (lower_bound);
4769 conservative--;
4770 return omega_false;
4771 }
4772
4773 free (rS);
4774 free (iS);
4775 }
4776 return omega_unknown;
4777 } while (eliminate_again);
4778 } while (1);
4779 }
4780
4781 /* Because the omega solver is recursive, this counter limits the
4782 recursion depth. */
4783 static int omega_solve_depth = 0;
4784
4785 /* Return omega_true when the problem PB has a solution following the
4786 DESIRED_RES. */
4787
4788 enum omega_result
4789 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4790 {
4791 enum omega_result result;
4792
4793 gcc_assert (pb->num_vars >= pb->safe_vars);
4794 omega_solve_depth++;
4795
4796 if (desired_res != omega_simplify)
4797 pb->safe_vars = 0;
4798
4799 if (omega_solve_depth > 50)
4800 {
4801 if (dump_file && (dump_flags & TDF_DETAILS))
4802 {
4803 fprintf (dump_file,
4804 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4805 omega_solve_depth, in_approximate_mode);
4806 omega_print_problem (dump_file, pb);
4807 }
4808 gcc_assert (0);
4809 }
4810
4811 if (omega_solve_eq (pb, desired_res) == omega_false)
4812 {
4813 omega_solve_depth--;
4814 return omega_false;
4815 }
4816
4817 if (in_approximate_mode && !pb->num_geqs)
4818 {
4819 result = omega_true;
4820 pb->num_vars = pb->safe_vars;
4821 omega_problem_reduced (pb);
4822 }
4823 else
4824 result = omega_solve_geq (pb, desired_res);
4825
4826 omega_solve_depth--;
4827
4828 if (!omega_reduce_with_subs)
4829 {
4830 resurrect_subs (pb);
4831 gcc_assert (please_no_equalities_in_simplified_problems
4832 || !result || pb->num_subs == 0);
4833 }
4834
4835 return result;
4836 }
4837
4838 /* Return true if red equations constrain the set of possible solutions.
4839 We assume that there are solutions to the black equations by
4840 themselves, so if there is no solution to the combined problem, we
4841 return true. */
4842
4843 bool
4844 omega_problem_has_red_equations (omega_pb pb)
4845 {
4846 bool result;
4847 int e;
4848 int i;
4849
4850 if (dump_file && (dump_flags & TDF_DETAILS))
4851 {
4852 fprintf (dump_file, "Checking for red equations:\n");
4853 omega_print_problem (dump_file, pb);
4854 }
4855
4856 please_no_equalities_in_simplified_problems++;
4857 may_be_red++;
4858
4859 if (omega_single_result)
4860 return_single_result++;
4861
4862 create_color = true;
4863 result = (omega_simplify_problem (pb) == omega_false);
4864
4865 if (omega_single_result)
4866 return_single_result--;
4867
4868 may_be_red--;
4869 please_no_equalities_in_simplified_problems--;
4870
4871 if (result)
4872 {
4873 if (dump_file && (dump_flags & TDF_DETAILS))
4874 fprintf (dump_file, "Gist is FALSE\n");
4875
4876 pb->num_subs = 0;
4877 pb->num_geqs = 0;
4878 pb->num_eqs = 1;
4879 pb->eqs[0].color = omega_red;
4880
4881 for (i = pb->num_vars; i > 0; i--)
4882 pb->eqs[0].coef[i] = 0;
4883
4884 pb->eqs[0].coef[0] = 1;
4885 return true;
4886 }
4887
4888 free_red_eliminations (pb);
4889 gcc_assert (pb->num_eqs == 0);
4890
4891 for (e = pb->num_geqs - 1; e >= 0; e--)
4892 if (pb->geqs[e].color == omega_red)
4893 result = true;
4894
4895 if (!result)
4896 return false;
4897
4898 for (i = pb->safe_vars; i >= 1; i--)
4899 {
4900 int ub = 0;
4901 int lb = 0;
4902
4903 for (e = pb->num_geqs - 1; e >= 0; e--)
4904 {
4905 if (pb->geqs[e].coef[i])
4906 {
4907 if (pb->geqs[e].coef[i] > 0)
4908 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4909
4910 else
4911 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4912 }
4913 }
4914
4915 if (ub == 2 || lb == 2)
4916 {
4917
4918 if (dump_file && (dump_flags & TDF_DETAILS))
4919 fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4920
4921 if (!omega_reduce_with_subs)
4922 {
4923 resurrect_subs (pb);
4924 gcc_assert (pb->num_subs == 0);
4925 }
4926
4927 return true;
4928 }
4929 }
4930
4931
4932 if (dump_file && (dump_flags & TDF_DETAILS))
4933 fprintf (dump_file,
4934 "*** Doing potentially expensive elimination tests "
4935 "for red equations\n");
4936
4937 please_no_equalities_in_simplified_problems++;
4938 omega_eliminate_red (pb, true);
4939 please_no_equalities_in_simplified_problems--;
4940
4941 result = false;
4942 gcc_assert (pb->num_eqs == 0);
4943
4944 for (e = pb->num_geqs - 1; e >= 0; e--)
4945 if (pb->geqs[e].color == omega_red)
4946 result = true;
4947
4948 if (dump_file && (dump_flags & TDF_DETAILS))
4949 {
4950 if (!result)
4951 fprintf (dump_file,
4952 "******************** Redundant Red Equations eliminated!!\n");
4953 else
4954 fprintf (dump_file,
4955 "******************** Red Equations remain\n");
4956
4957 omega_print_problem (dump_file, pb);
4958 }
4959
4960 if (!omega_reduce_with_subs)
4961 {
4962 normalize_return_type r;
4963
4964 resurrect_subs (pb);
4965 r = normalize_omega_problem (pb);
4966 gcc_assert (r != normalize_false);
4967
4968 coalesce (pb);
4969 cleanout_wildcards (pb);
4970 gcc_assert (pb->num_subs == 0);
4971 }
4972
4973 return result;
4974 }
4975
4976 /* Calls omega_simplify_problem in approximate mode. */
4977
4978 enum omega_result
4979 omega_simplify_approximate (omega_pb pb)
4980 {
4981 enum omega_result result;
4982
4983 if (dump_file && (dump_flags & TDF_DETAILS))
4984 fprintf (dump_file, "(Entering approximate mode\n");
4985
4986 in_approximate_mode = true;
4987 result = omega_simplify_problem (pb);
4988 in_approximate_mode = false;
4989
4990 gcc_assert (pb->num_vars == pb->safe_vars);
4991 if (!omega_reduce_with_subs)
4992 gcc_assert (pb->num_subs == 0);
4993
4994 if (dump_file && (dump_flags & TDF_DETAILS))
4995 fprintf (dump_file, "Leaving approximate mode)\n");
4996
4997 return result;
4998 }
4999
5000
5001 /* Simplifies problem PB by eliminating redundant constraints and
5002 reducing the constraints system to a minimal form. Returns
5003 omega_true when the problem was successfully reduced, omega_unknown
5004 when the solver is unable to determine an answer. */
5005
5006 enum omega_result
5007 omega_simplify_problem (omega_pb pb)
5008 {
5009 int i;
5010
5011 omega_found_reduction = omega_false;
5012
5013 if (!pb->variables_initialized)
5014 omega_initialize_variables (pb);
5015
5016 if (next_key * 3 > MAX_KEYS)
5017 {
5018 int e;
5019
5020 hash_version++;
5021 next_key = OMEGA_MAX_VARS + 1;
5022
5023 for (e = pb->num_geqs - 1; e >= 0; e--)
5024 pb->geqs[e].touched = 1;
5025
5026 for (i = 0; i < HASH_TABLE_SIZE; i++)
5027 hash_master[i].touched = -1;
5028
5029 pb->hash_version = hash_version;
5030 }
5031
5032 else if (pb->hash_version != hash_version)
5033 {
5034 int e;
5035
5036 for (e = pb->num_geqs - 1; e >= 0; e--)
5037 pb->geqs[e].touched = 1;
5038
5039 pb->hash_version = hash_version;
5040 }
5041
5042 if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
5043 omega_free_eliminations (pb, pb->safe_vars);
5044
5045 if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
5046 {
5047 omega_found_reduction = omega_solve_problem (pb, omega_unknown);
5048
5049 if (omega_found_reduction != omega_false
5050 && !return_single_result)
5051 {
5052 pb->num_geqs = 0;
5053 pb->num_eqs = 0;
5054 (*omega_when_reduced) (pb);
5055 }
5056
5057 return omega_found_reduction;
5058 }
5059
5060 omega_solve_problem (pb, omega_simplify);
5061
5062 if (omega_found_reduction != omega_false)
5063 {
5064 for (i = 1; omega_safe_var_p (pb, i); i++)
5065 pb->forwarding_address[pb->var[i]] = i;
5066
5067 for (i = 0; i < pb->num_subs; i++)
5068 pb->forwarding_address[pb->subs[i].key] = -i - 1;
5069 }
5070
5071 if (!omega_reduce_with_subs)
5072 gcc_assert (please_no_equalities_in_simplified_problems
5073 || omega_found_reduction == omega_false
5074 || pb->num_subs == 0);
5075
5076 return omega_found_reduction;
5077 }
5078
5079 /* Make variable VAR unprotected: it then can be eliminated. */
5080
5081 void
5082 omega_unprotect_variable (omega_pb pb, int var)
5083 {
5084 int e, idx;
5085 idx = pb->forwarding_address[var];
5086
5087 if (idx < 0)
5088 {
5089 idx = -1 - idx;
5090 pb->num_subs--;
5091
5092 if (idx < pb->num_subs)
5093 {
5094 omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5095 pb->num_vars);
5096 pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5097 }
5098 }
5099 else
5100 {
5101 int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5102 int e2;
5103
5104 for (e = pb->num_subs - 1; e >= 0; e--)
5105 bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5106
5107 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5108 if (bring_to_life[e2])
5109 {
5110 pb->num_vars++;
5111 pb->safe_vars++;
5112
5113 if (pb->safe_vars < pb->num_vars)
5114 {
5115 for (e = pb->num_geqs - 1; e >= 0; e--)
5116 {
5117 pb->geqs[e].coef[pb->num_vars] =
5118 pb->geqs[e].coef[pb->safe_vars];
5119
5120 pb->geqs[e].coef[pb->safe_vars] = 0;
5121 }
5122
5123 for (e = pb->num_eqs - 1; e >= 0; e--)
5124 {
5125 pb->eqs[e].coef[pb->num_vars] =
5126 pb->eqs[e].coef[pb->safe_vars];
5127
5128 pb->eqs[e].coef[pb->safe_vars] = 0;
5129 }
5130
5131 for (e = pb->num_subs - 1; e >= 0; e--)
5132 {
5133 pb->subs[e].coef[pb->num_vars] =
5134 pb->subs[e].coef[pb->safe_vars];
5135
5136 pb->subs[e].coef[pb->safe_vars] = 0;
5137 }
5138
5139 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5140 pb->forwarding_address[pb->var[pb->num_vars]] =
5141 pb->num_vars;
5142 }
5143 else
5144 {
5145 for (e = pb->num_geqs - 1; e >= 0; e--)
5146 pb->geqs[e].coef[pb->safe_vars] = 0;
5147
5148 for (e = pb->num_eqs - 1; e >= 0; e--)
5149 pb->eqs[e].coef[pb->safe_vars] = 0;
5150
5151 for (e = pb->num_subs - 1; e >= 0; e--)
5152 pb->subs[e].coef[pb->safe_vars] = 0;
5153 }
5154
5155 pb->var[pb->safe_vars] = pb->subs[e2].key;
5156 pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5157
5158 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5159 pb->num_vars);
5160 pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5161 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5162
5163 if (e2 < pb->num_subs - 1)
5164 omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5165 pb->num_vars);
5166
5167 pb->num_subs--;
5168 }
5169
5170 omega_unprotect_1 (pb, &idx, NULL);
5171 free (bring_to_life);
5172 }
5173
5174 chain_unprotect (pb);
5175 }
5176
5177 /* Unprotects VAR and simplifies PB. */
5178
5179 enum omega_result
5180 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5181 int var, int sign)
5182 {
5183 int n_vars = pb->num_vars;
5184 int e, j;
5185 int k = pb->forwarding_address[var];
5186
5187 if (k < 0)
5188 {
5189 k = -1 - k;
5190
5191 if (sign != 0)
5192 {
5193 e = pb->num_geqs++;
5194 omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5195
5196 for (j = 0; j <= n_vars; j++)
5197 pb->geqs[e].coef[j] *= sign;
5198
5199 pb->geqs[e].coef[0]--;
5200 pb->geqs[e].touched = 1;
5201 pb->geqs[e].color = color;
5202 }
5203 else
5204 {
5205 e = pb->num_eqs++;
5206 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5207 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5208 pb->eqs[e].color = color;
5209 }
5210 }
5211 else if (sign != 0)
5212 {
5213 e = pb->num_geqs++;
5214 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5215 pb->geqs[e].coef[k] = sign;
5216 pb->geqs[e].coef[0] = -1;
5217 pb->geqs[e].touched = 1;
5218 pb->geqs[e].color = color;
5219 }
5220 else
5221 {
5222 e = pb->num_eqs++;
5223 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5224 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5225 pb->eqs[e].coef[k] = 1;
5226 pb->eqs[e].color = color;
5227 }
5228
5229 omega_unprotect_variable (pb, var);
5230 return omega_simplify_problem (pb);
5231 }
5232
5233 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5234
5235 void
5236 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5237 int var, int value)
5238 {
5239 int e;
5240 int k = pb->forwarding_address[var];
5241
5242 if (k < 0)
5243 {
5244 k = -1 - k;
5245 e = pb->num_eqs++;
5246 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5247 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5248 pb->eqs[e].coef[0] -= value;
5249 }
5250 else
5251 {
5252 e = pb->num_eqs++;
5253 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5254 pb->eqs[e].coef[k] = 1;
5255 pb->eqs[e].coef[0] = -value;
5256 }
5257
5258 pb->eqs[e].color = color;
5259 }
5260
5261 /* Return false when the upper and lower bounds are not coupled.
5262 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5263 variable I. */
5264
5265 bool
5266 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5267 {
5268 int n_vars = pb->num_vars;
5269 int e, j;
5270 bool is_simple;
5271 bool coupled = false;
5272
5273 *lower_bound = neg_infinity;
5274 *upper_bound = pos_infinity;
5275 i = pb->forwarding_address[i];
5276
5277 if (i < 0)
5278 {
5279 i = -i - 1;
5280
5281 for (j = 1; j <= n_vars; j++)
5282 if (pb->subs[i].coef[j] != 0)
5283 return true;
5284
5285 *upper_bound = *lower_bound = pb->subs[i].coef[0];
5286 return false;
5287 }
5288
5289 for (e = pb->num_subs - 1; e >= 0; e--)
5290 if (pb->subs[e].coef[i] != 0)
5291 coupled = true;
5292
5293 for (e = pb->num_eqs - 1; e >= 0; e--)
5294 if (pb->eqs[e].coef[i] != 0)
5295 {
5296 is_simple = true;
5297
5298 for (j = 1; j <= n_vars; j++)
5299 if (i != j && pb->eqs[e].coef[j] != 0)
5300 {
5301 is_simple = false;
5302 coupled = true;
5303 break;
5304 }
5305
5306 if (!is_simple)
5307 continue;
5308 else
5309 {
5310 *lower_bound = *upper_bound =
5311 -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5312 return false;
5313 }
5314 }
5315
5316 for (e = pb->num_geqs - 1; e >= 0; e--)
5317 if (pb->geqs[e].coef[i] != 0)
5318 {
5319 if (pb->geqs[e].key == i)
5320 *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5321
5322 else if (pb->geqs[e].key == -i)
5323 *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5324
5325 else
5326 coupled = true;
5327 }
5328
5329 return coupled;
5330 }
5331
5332 /* Sets the lower bound L and upper bound U for the values of variable
5333 I, and sets COULD_BE_ZERO to true if variable I might take value
5334 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5335 variable I. */
5336
5337 static void
5338 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5339 bool *could_be_zero, int lower_bound, int upper_bound)
5340 {
5341 int e, b1, b2;
5342 eqn eqn;
5343 int sign;
5344 int v;
5345
5346 /* Preconditions. */
5347 gcc_assert (abs (pb->forwarding_address[i]) == 1
5348 && pb->num_vars + pb->num_subs == 2
5349 && pb->num_eqs + pb->num_subs == 1);
5350
5351 /* Define variable I in terms of variable V. */
5352 if (pb->forwarding_address[i] == -1)
5353 {
5354 eqn = &pb->subs[0];
5355 sign = 1;
5356 v = 1;
5357 }
5358 else
5359 {
5360 eqn = &pb->eqs[0];
5361 sign = -eqn->coef[1];
5362 v = 2;
5363 }
5364
5365 for (e = pb->num_geqs - 1; e >= 0; e--)
5366 if (pb->geqs[e].coef[v] != 0)
5367 {
5368 if (pb->geqs[e].coef[v] == 1)
5369 lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5370
5371 else
5372 upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5373 }
5374
5375 if (lower_bound > upper_bound)
5376 {
5377 *l = pos_infinity;
5378 *u = neg_infinity;
5379 *could_be_zero = 0;
5380 return;
5381 }
5382
5383 if (lower_bound == neg_infinity)
5384 {
5385 if (eqn->coef[v] > 0)
5386 b1 = sign * neg_infinity;
5387
5388 else
5389 b1 = -sign * neg_infinity;
5390 }
5391 else
5392 b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5393
5394 if (upper_bound == pos_infinity)
5395 {
5396 if (eqn->coef[v] > 0)
5397 b2 = sign * pos_infinity;
5398
5399 else
5400 b2 = -sign * pos_infinity;
5401 }
5402 else
5403 b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5404
5405 *l = MAX (*l, b1 <= b2 ? b1 : b2);
5406 *u = MIN (*u, b1 <= b2 ? b2 : b1);
5407
5408 *could_be_zero = (*l <= 0 && 0 <= *u
5409 && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5410 }
5411
5412 /* Return false when a lower bound L and an upper bound U for variable
5413 I in problem PB have been initialized. */
5414
5415 bool
5416 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5417 {
5418 *l = neg_infinity;
5419 *u = pos_infinity;
5420
5421 if (!omega_query_variable (pb, i, l, u)
5422 || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5423 return false;
5424
5425 if (abs (pb->forwarding_address[i]) == 1
5426 && pb->num_vars + pb->num_subs == 2
5427 && pb->num_eqs + pb->num_subs == 1)
5428 {
5429 bool could_be_zero;
5430 query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5431 pos_infinity);
5432 return false;
5433 }
5434
5435 return true;
5436 }
5437
5438 /* For problem PB, return an integer that represents the classic data
5439 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5440 masks that are added to the result. When DIST_KNOWN is true, DIST
5441 is set to the classic data dependence distance. LOWER_BOUND and
5442 UPPER_BOUND are bounds on the value of variable I, for example, it
5443 is possible to narrow the iteration domain with safe approximations
5444 of loop counts, and thus discard some data dependences that cannot
5445 occur. */
5446
5447 int
5448 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5449 int dd_eq, int dd_gt, int lower_bound,
5450 int upper_bound, bool *dist_known, int *dist)
5451 {
5452 int result;
5453 int l, u;
5454 bool could_be_zero;
5455
5456 l = neg_infinity;
5457 u = pos_infinity;
5458
5459 omega_query_variable (pb, i, &l, &u);
5460 query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5461 upper_bound);
5462 result = 0;
5463
5464 if (l < 0)
5465 result |= dd_gt;
5466
5467 if (u > 0)
5468 result |= dd_lt;
5469
5470 if (could_be_zero)
5471 result |= dd_eq;
5472
5473 if (l == u)
5474 {
5475 *dist_known = true;
5476 *dist = l;
5477 }
5478 else
5479 *dist_known = false;
5480
5481 return result;
5482 }
5483
5484 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5485 safe variables. Safe variables are not eliminated during the
5486 Fourier-Motzkin elimination. Safe variables are all those
5487 variables that are placed at the beginning of the array of
5488 variables: P->var[0, ..., NPROT - 1]. */
5489
5490 omega_pb
5491 omega_alloc_problem (int nvars, int nprot)
5492 {
5493 omega_pb pb;
5494
5495 gcc_assert (nvars <= OMEGA_MAX_VARS);
5496 omega_initialize ();
5497
5498 /* Allocate and initialize PB. */
5499 pb = XCNEW (struct omega_pb_d);
5500 pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5501 pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5502 pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5503 pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5504 pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5505
5506 pb->hash_version = hash_version;
5507 pb->num_vars = nvars;
5508 pb->safe_vars = nprot;
5509 pb->variables_initialized = false;
5510 pb->variables_freed = false;
5511 pb->num_eqs = 0;
5512 pb->num_geqs = 0;
5513 pb->num_subs = 0;
5514 return pb;
5515 }
5516
5517 /* Keeps the state of the initialization. */
5518 static bool omega_initialized = false;
5519
5520 /* Initialization of the Omega solver. */
5521
5522 void
5523 omega_initialize (void)
5524 {
5525 int i;
5526
5527 if (omega_initialized)
5528 return;
5529
5530 next_wild_card = 0;
5531 next_key = OMEGA_MAX_VARS + 1;
5532 packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5533 fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5534 fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5535 hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5536
5537 for (i = 0; i < HASH_TABLE_SIZE; i++)
5538 hash_master[i].touched = -1;
5539
5540 sprintf (wild_name[0], "1");
5541 sprintf (wild_name[1], "a");
5542 sprintf (wild_name[2], "b");
5543 sprintf (wild_name[3], "c");
5544 sprintf (wild_name[4], "d");
5545 sprintf (wild_name[5], "e");
5546 sprintf (wild_name[6], "f");
5547 sprintf (wild_name[7], "g");
5548 sprintf (wild_name[8], "h");
5549 sprintf (wild_name[9], "i");
5550 sprintf (wild_name[10], "j");
5551 sprintf (wild_name[11], "k");
5552 sprintf (wild_name[12], "l");
5553 sprintf (wild_name[13], "m");
5554 sprintf (wild_name[14], "n");
5555 sprintf (wild_name[15], "o");
5556 sprintf (wild_name[16], "p");
5557 sprintf (wild_name[17], "q");
5558 sprintf (wild_name[18], "r");
5559 sprintf (wild_name[19], "s");
5560 sprintf (wild_name[20], "t");
5561 sprintf (wild_name[40 - 1], "alpha");
5562 sprintf (wild_name[40 - 2], "beta");
5563 sprintf (wild_name[40 - 3], "gamma");
5564 sprintf (wild_name[40 - 4], "delta");
5565 sprintf (wild_name[40 - 5], "tau");
5566 sprintf (wild_name[40 - 6], "sigma");
5567 sprintf (wild_name[40 - 7], "chi");
5568 sprintf (wild_name[40 - 8], "omega");
5569 sprintf (wild_name[40 - 9], "pi");
5570 sprintf (wild_name[40 - 10], "ni");
5571 sprintf (wild_name[40 - 11], "Alpha");
5572 sprintf (wild_name[40 - 12], "Beta");
5573 sprintf (wild_name[40 - 13], "Gamma");
5574 sprintf (wild_name[40 - 14], "Delta");
5575 sprintf (wild_name[40 - 15], "Tau");
5576 sprintf (wild_name[40 - 16], "Sigma");
5577 sprintf (wild_name[40 - 17], "Chi");
5578 sprintf (wild_name[40 - 18], "Omega");
5579 sprintf (wild_name[40 - 19], "xxx");
5580
5581 omega_initialized = true;
5582 }