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