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