2012-11-28 Oleg Raikhman <oleg@adapteva.com>
[official-gcc.git] / gcc / omega.c
blob5f78ed1b0d33c6b4651691cb737259c3c59eabfe
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.
5 This code has no license restrictions, and is considered public
6 domain.
8 Changes copyright (C) 2005, 2006, 2007, 2008, 2009,
9 2010 Free Software Foundation, Inc.
10 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
12 This file is part of GCC.
14 GCC is free software; you can redistribute it and/or modify it under
15 the terms of the GNU General Public License as published by the Free
16 Software Foundation; either version 3, or (at your option) any later
17 version.
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING3. If not see
26 <http://www.gnu.org/licenses/>. */
28 /* For a detailed description, see "Constraint-Based Array Dependence
29 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
30 Wonnacott's thesis:
31 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
34 #include "config.h"
35 #include "system.h"
36 #include "coretypes.h"
37 #include "tree.h"
38 #include "diagnostic-core.h"
39 #include "dumpfile.h"
40 #include "omega.h"
42 /* When set to true, keep substitution variables. When set to false,
43 resurrect substitution variables (convert substitutions back to EQs). */
44 static bool omega_reduce_with_subs = true;
46 /* When set to true, omega_simplify_problem checks for problem with no
47 solutions, calling verify_omega_pb. */
48 static bool omega_verify_simplification = false;
50 /* When set to true, only produce a single simplified result. */
51 static bool omega_single_result = false;
53 /* Set return_single_result to 1 when omega_single_result is true. */
54 static int return_single_result = 0;
56 /* Hash table for equations generated by the solver. */
57 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
58 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
59 static eqn hash_master;
60 static int next_key;
61 static int hash_version = 0;
63 /* Set to true for making the solver enter in approximation mode. */
64 static bool in_approximate_mode = false;
66 /* When set to zero, the solver is allowed to add new equalities to
67 the problem to be solved. */
68 static int conservative = 0;
70 /* Set to omega_true when the problem was successfully reduced, set to
71 omega_unknown when the solver is unable to determine an answer. */
72 static enum omega_result omega_found_reduction;
74 /* Set to true when the solver is allowed to add omega_red equations. */
75 static bool create_color = false;
77 /* Set to nonzero when the problem to be solved can be reduced. */
78 static int may_be_red = 0;
80 /* When false, there should be no substitution equations in the
81 simplified problem. */
82 static int please_no_equalities_in_simplified_problems = 0;
84 /* Variables names for pretty printing. */
85 static char wild_name[200][40];
87 /* Pointer to the void problem. */
88 static omega_pb no_problem = (omega_pb) 0;
90 /* Pointer to the problem to be solved. */
91 static omega_pb original_problem = (omega_pb) 0;
94 /* Return the integer A divided by B. */
96 static inline int
97 int_div (int a, int b)
99 if (a > 0)
100 return a/b;
101 else
102 return -((-a + b - 1)/b);
105 /* Return the integer A modulo B. */
107 static inline int
108 int_mod (int a, int b)
110 return a - b * int_div (a, b);
113 /* Test whether equation E is red. */
115 static inline bool
116 omega_eqn_is_red (eqn e, int desired_res)
118 return (desired_res == omega_simplify && e->color == omega_red);
121 /* Return a string for VARIABLE. */
123 static inline char *
124 omega_var_to_str (int variable)
126 if (0 <= variable && variable <= 20)
127 return wild_name[variable];
129 if (-20 < variable && variable < 0)
130 return wild_name[40 + variable];
132 /* Collapse all the entries that would have overflowed. */
133 return wild_name[21];
136 /* Return a string for variable I in problem PB. */
138 static inline char *
139 omega_variable_to_str (omega_pb pb, int i)
141 return omega_var_to_str (pb->var[i]);
144 /* Do nothing function: used for default initializations. */
146 void
147 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
151 void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
153 /* Print to FILE from PB equation E with all its coefficients
154 multiplied by C. */
156 static void
157 omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
159 int i;
160 bool first = true;
161 int n = pb->num_vars;
162 int went_first = -1;
164 for (i = 1; i <= n; i++)
165 if (c * e->coef[i] > 0)
167 first = false;
168 went_first = i;
170 if (c * e->coef[i] == 1)
171 fprintf (file, "%s", omega_variable_to_str (pb, i));
172 else
173 fprintf (file, "%d * %s", c * e->coef[i],
174 omega_variable_to_str (pb, i));
175 break;
178 for (i = 1; i <= n; i++)
179 if (i != went_first && c * e->coef[i] != 0)
181 if (!first && c * e->coef[i] > 0)
182 fprintf (file, " + ");
184 first = false;
186 if (c * e->coef[i] == 1)
187 fprintf (file, "%s", omega_variable_to_str (pb, i));
188 else if (c * e->coef[i] == -1)
189 fprintf (file, " - %s", omega_variable_to_str (pb, i));
190 else
191 fprintf (file, "%d * %s", c * e->coef[i],
192 omega_variable_to_str (pb, i));
195 if (!first && c * e->coef[0] > 0)
196 fprintf (file, " + ");
198 if (first || c * e->coef[0] != 0)
199 fprintf (file, "%d", c * e->coef[0]);
202 /* Print to FILE the equation E of problem PB. */
204 void
205 omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
207 int i;
208 int n = pb->num_vars + extra;
209 bool is_lt = test && e->coef[0] == -1;
210 bool first;
212 if (test)
214 if (e->touched)
215 fprintf (file, "!");
217 else if (e->key != 0)
218 fprintf (file, "%d: ", e->key);
221 if (e->color == omega_red)
222 fprintf (file, "[");
224 first = true;
226 for (i = is_lt ? 1 : 0; i <= n; i++)
227 if (e->coef[i] < 0)
229 if (!first)
230 fprintf (file, " + ");
231 else
232 first = false;
234 if (i == 0)
235 fprintf (file, "%d", -e->coef[i]);
236 else if (e->coef[i] == -1)
237 fprintf (file, "%s", omega_variable_to_str (pb, i));
238 else
239 fprintf (file, "%d * %s", -e->coef[i],
240 omega_variable_to_str (pb, i));
243 if (first)
245 if (is_lt)
247 fprintf (file, "1");
248 is_lt = false;
250 else
251 fprintf (file, "0");
254 if (test == 0)
255 fprintf (file, " = ");
256 else if (is_lt)
257 fprintf (file, " < ");
258 else
259 fprintf (file, " <= ");
261 first = true;
263 for (i = 0; i <= n; i++)
264 if (e->coef[i] > 0)
266 if (!first)
267 fprintf (file, " + ");
268 else
269 first = false;
271 if (i == 0)
272 fprintf (file, "%d", e->coef[i]);
273 else if (e->coef[i] == 1)
274 fprintf (file, "%s", omega_variable_to_str (pb, i));
275 else
276 fprintf (file, "%d * %s", e->coef[i],
277 omega_variable_to_str (pb, i));
280 if (first)
281 fprintf (file, "0");
283 if (e->color == omega_red)
284 fprintf (file, "]");
287 /* Print to FILE all the variables of problem PB. */
289 static void
290 omega_print_vars (FILE *file, omega_pb pb)
292 int i;
294 fprintf (file, "variables = ");
296 if (pb->safe_vars > 0)
297 fprintf (file, "protected (");
299 for (i = 1; i <= pb->num_vars; i++)
301 fprintf (file, "%s", omega_variable_to_str (pb, i));
303 if (i == pb->safe_vars)
304 fprintf (file, ")");
306 if (i < pb->num_vars)
307 fprintf (file, ", ");
310 fprintf (file, "\n");
313 /* Debug problem PB. */
315 DEBUG_FUNCTION void
316 debug_omega_problem (omega_pb pb)
318 omega_print_problem (stderr, pb);
321 /* Print to FILE problem PB. */
323 void
324 omega_print_problem (FILE *file, omega_pb pb)
326 int e;
328 if (!pb->variables_initialized)
329 omega_initialize_variables (pb);
331 omega_print_vars (file, pb);
333 for (e = 0; e < pb->num_eqs; e++)
335 omega_print_eq (file, pb, &pb->eqs[e]);
336 fprintf (file, "\n");
339 fprintf (file, "Done with EQ\n");
341 for (e = 0; e < pb->num_geqs; e++)
343 omega_print_geq (file, pb, &pb->geqs[e]);
344 fprintf (file, "\n");
347 fprintf (file, "Done with GEQ\n");
349 for (e = 0; e < pb->num_subs; e++)
351 eqn eq = &pb->subs[e];
353 if (eq->color == omega_red)
354 fprintf (file, "[");
356 if (eq->key > 0)
357 fprintf (file, "%s := ", omega_var_to_str (eq->key));
358 else
359 fprintf (file, "#%d := ", eq->key);
361 omega_print_term (file, pb, eq, 1);
363 if (eq->color == omega_red)
364 fprintf (file, "]");
366 fprintf (file, "\n");
370 /* Return the number of equations in PB tagged omega_red. */
373 omega_count_red_equations (omega_pb pb)
375 int e, i;
376 int result = 0;
378 for (e = 0; e < pb->num_eqs; e++)
379 if (pb->eqs[e].color == omega_red)
381 for (i = pb->num_vars; i > 0; i--)
382 if (pb->geqs[e].coef[i])
383 break;
385 if (i == 0 && pb->geqs[e].coef[0] == 1)
386 return 0;
387 else
388 result += 2;
391 for (e = 0; e < pb->num_geqs; e++)
392 if (pb->geqs[e].color == omega_red)
393 result += 1;
395 for (e = 0; e < pb->num_subs; e++)
396 if (pb->subs[e].color == omega_red)
397 result += 2;
399 return result;
402 /* Print to FILE all the equations in PB that are tagged omega_red. */
404 void
405 omega_print_red_equations (FILE *file, omega_pb pb)
407 int e;
409 if (!pb->variables_initialized)
410 omega_initialize_variables (pb);
412 omega_print_vars (file, pb);
414 for (e = 0; e < pb->num_eqs; e++)
415 if (pb->eqs[e].color == omega_red)
417 omega_print_eq (file, pb, &pb->eqs[e]);
418 fprintf (file, "\n");
421 for (e = 0; e < pb->num_geqs; e++)
422 if (pb->geqs[e].color == omega_red)
424 omega_print_geq (file, pb, &pb->geqs[e]);
425 fprintf (file, "\n");
428 for (e = 0; e < pb->num_subs; e++)
429 if (pb->subs[e].color == omega_red)
431 eqn eq = &pb->subs[e];
432 fprintf (file, "[");
434 if (eq->key > 0)
435 fprintf (file, "%s := ", omega_var_to_str (eq->key));
436 else
437 fprintf (file, "#%d := ", eq->key);
439 omega_print_term (file, pb, eq, 1);
440 fprintf (file, "]\n");
444 /* Pretty print PB to FILE. */
446 void
447 omega_pretty_print_problem (FILE *file, omega_pb pb)
449 int e, v, v1, v2, v3, t;
450 bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
451 int stuffPrinted = 0;
452 bool change;
454 typedef enum {
455 none, le, lt
456 } partial_order_type;
458 partial_order_type **po = XNEWVEC (partial_order_type *,
459 OMEGA_MAX_VARS * OMEGA_MAX_VARS);
460 int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
461 int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
462 int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
463 int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
464 int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
465 int i, m;
466 bool multiprint;
468 if (!pb->variables_initialized)
469 omega_initialize_variables (pb);
471 if (pb->num_vars > 0)
473 omega_eliminate_redundant (pb, false);
475 for (e = 0; e < pb->num_eqs; e++)
477 if (stuffPrinted)
478 fprintf (file, "; ");
480 stuffPrinted = 1;
481 omega_print_eq (file, pb, &pb->eqs[e]);
484 for (e = 0; e < pb->num_geqs; e++)
485 live[e] = true;
487 while (1)
489 for (v = 1; v <= pb->num_vars; v++)
491 last_links[v] = first_links[v] = 0;
492 chain_length[v] = 0;
494 for (v2 = 1; v2 <= pb->num_vars; v2++)
495 po[v][v2] = none;
498 for (e = 0; e < pb->num_geqs; e++)
499 if (live[e])
501 for (v = 1; v <= pb->num_vars; v++)
502 if (pb->geqs[e].coef[v] == 1)
503 first_links[v]++;
504 else if (pb->geqs[e].coef[v] == -1)
505 last_links[v]++;
507 v1 = pb->num_vars;
509 while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
510 v1--;
512 v2 = v1 - 1;
514 while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
515 v2--;
517 v3 = v2 - 1;
519 while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
520 v3--;
522 if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
523 || v2 <= 0 || v3 > 0
524 || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
526 /* Not a partial order relation. */
528 else
530 if (pb->geqs[e].coef[v1] == 1)
532 v3 = v2;
533 v2 = v1;
534 v1 = v3;
537 /* Relation is v1 <= v2 or v1 < v2. */
538 po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
539 po_eq[v1][v2] = e;
542 for (v = 1; v <= pb->num_vars; v++)
543 chain_length[v] = last_links[v];
545 /* Just in case pb->num_vars <= 0. */
546 change = false;
547 for (t = 0; t < pb->num_vars; t++)
549 change = false;
551 for (v1 = 1; v1 <= pb->num_vars; v1++)
552 for (v2 = 1; v2 <= pb->num_vars; v2++)
553 if (po[v1][v2] != none &&
554 chain_length[v1] <= chain_length[v2])
556 chain_length[v1] = chain_length[v2] + 1;
557 change = true;
561 /* Caught in cycle. */
562 gcc_assert (!change);
564 for (v1 = 1; v1 <= pb->num_vars; v1++)
565 if (chain_length[v1] == 0)
566 first_links[v1] = 0;
568 v = 1;
570 for (v1 = 2; v1 <= pb->num_vars; v1++)
571 if (chain_length[v1] + first_links[v1] >
572 chain_length[v] + first_links[v])
573 v = v1;
575 if (chain_length[v] + first_links[v] == 0)
576 break;
578 if (stuffPrinted)
579 fprintf (file, "; ");
581 stuffPrinted = 1;
583 /* Chain starts at v. */
585 int tmp;
586 bool first = true;
588 for (e = 0; e < pb->num_geqs; e++)
589 if (live[e] && pb->geqs[e].coef[v] == 1)
591 if (!first)
592 fprintf (file, ", ");
594 tmp = pb->geqs[e].coef[v];
595 pb->geqs[e].coef[v] = 0;
596 omega_print_term (file, pb, &pb->geqs[e], -1);
597 pb->geqs[e].coef[v] = tmp;
598 live[e] = false;
599 first = false;
602 if (!first)
603 fprintf (file, " <= ");
606 /* Find chain. */
607 chain[0] = v;
608 m = 1;
609 while (1)
611 /* Print chain. */
612 for (v2 = 1; v2 <= pb->num_vars; v2++)
613 if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
614 break;
616 if (v2 > pb->num_vars)
617 break;
619 chain[m++] = v2;
620 v = v2;
623 fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
625 for (multiprint = false, i = 1; i < m; i++)
627 v = chain[i - 1];
628 v2 = chain[i];
630 if (po[v][v2] == le)
631 fprintf (file, " <= ");
632 else
633 fprintf (file, " < ");
635 fprintf (file, "%s", omega_variable_to_str (pb, v2));
636 live[po_eq[v][v2]] = false;
638 if (!multiprint && i < m - 1)
639 for (v3 = 1; v3 <= pb->num_vars; v3++)
641 if (v == v3 || v2 == v3
642 || po[v][v2] != po[v][v3]
643 || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
644 continue;
646 fprintf (file, ",%s", omega_variable_to_str (pb, v3));
647 live[po_eq[v][v3]] = false;
648 live[po_eq[v3][chain[i + 1]]] = false;
649 multiprint = true;
651 else
652 multiprint = false;
655 v = chain[m - 1];
656 /* Print last_links. */
658 int tmp;
659 bool first = true;
661 for (e = 0; e < pb->num_geqs; e++)
662 if (live[e] && pb->geqs[e].coef[v] == -1)
664 if (!first)
665 fprintf (file, ", ");
666 else
667 fprintf (file, " <= ");
669 tmp = pb->geqs[e].coef[v];
670 pb->geqs[e].coef[v] = 0;
671 omega_print_term (file, pb, &pb->geqs[e], 1);
672 pb->geqs[e].coef[v] = tmp;
673 live[e] = false;
674 first = false;
679 for (e = 0; e < pb->num_geqs; e++)
680 if (live[e])
682 if (stuffPrinted)
683 fprintf (file, "; ");
684 stuffPrinted = 1;
685 omega_print_geq (file, pb, &pb->geqs[e]);
688 for (e = 0; e < pb->num_subs; e++)
690 eqn eq = &pb->subs[e];
692 if (stuffPrinted)
693 fprintf (file, "; ");
695 stuffPrinted = 1;
697 if (eq->key > 0)
698 fprintf (file, "%s := ", omega_var_to_str (eq->key));
699 else
700 fprintf (file, "#%d := ", eq->key);
702 omega_print_term (file, pb, eq, 1);
706 free (live);
707 free (po);
708 free (po_eq);
709 free (last_links);
710 free (first_links);
711 free (chain_length);
712 free (chain);
715 /* Assign to variable I in PB the next wildcard name. The name of a
716 wildcard is a negative number. */
717 static int next_wild_card = 0;
719 static void
720 omega_name_wild_card (omega_pb pb, int i)
722 --next_wild_card;
723 if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
724 next_wild_card = -1;
725 pb->var[i] = next_wild_card;
728 /* Return the index of the last protected (or safe) variable in PB,
729 after having added a new wildcard variable. */
731 static int
732 omega_add_new_wild_card (omega_pb pb)
734 int e;
735 int i = ++pb->safe_vars;
736 pb->num_vars++;
738 /* Make a free place in the protected (safe) variables, by moving
739 the non protected variable pointed by "I" at the end, ie. at
740 offset pb->num_vars. */
741 if (pb->num_vars != i)
743 /* Move "I" for all the inequalities. */
744 for (e = pb->num_geqs - 1; e >= 0; e--)
746 if (pb->geqs[e].coef[i])
747 pb->geqs[e].touched = 1;
749 pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
752 /* Move "I" for all the equalities. */
753 for (e = pb->num_eqs - 1; e >= 0; e--)
754 pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
756 /* Move "I" for all the substitutions. */
757 for (e = pb->num_subs - 1; e >= 0; e--)
758 pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
760 /* Move the identifier. */
761 pb->var[pb->num_vars] = pb->var[i];
764 /* Initialize at zero all the coefficients */
765 for (e = pb->num_geqs - 1; e >= 0; e--)
766 pb->geqs[e].coef[i] = 0;
768 for (e = pb->num_eqs - 1; e >= 0; e--)
769 pb->eqs[e].coef[i] = 0;
771 for (e = pb->num_subs - 1; e >= 0; e--)
772 pb->subs[e].coef[i] = 0;
774 /* And give it a name. */
775 omega_name_wild_card (pb, i);
776 return i;
779 /* Delete inequality E from problem PB that has N_VARS variables. */
781 static void
782 omega_delete_geq (omega_pb pb, int e, int n_vars)
784 if (dump_file && (dump_flags & TDF_DETAILS))
786 fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
787 omega_print_geq (dump_file, pb, &pb->geqs[e]);
788 fprintf (dump_file, "\n");
791 if (e < pb->num_geqs - 1)
792 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
794 pb->num_geqs--;
797 /* Delete extra inequality E from problem PB that has N_VARS
798 variables. */
800 static void
801 omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
803 if (dump_file && (dump_flags & TDF_DETAILS))
805 fprintf (dump_file, "Deleting %d: ",e);
806 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
807 fprintf (dump_file, "\n");
810 if (e < pb->num_geqs - 1)
811 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
813 pb->num_geqs--;
817 /* Remove variable I from problem PB. */
819 static void
820 omega_delete_variable (omega_pb pb, int i)
822 int n_vars = pb->num_vars;
823 int e;
825 if (omega_safe_var_p (pb, i))
827 int j = pb->safe_vars;
829 for (e = pb->num_geqs - 1; e >= 0; e--)
831 pb->geqs[e].touched = 1;
832 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
833 pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
836 for (e = pb->num_eqs - 1; e >= 0; e--)
838 pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
839 pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
842 for (e = pb->num_subs - 1; e >= 0; e--)
844 pb->subs[e].coef[i] = pb->subs[e].coef[j];
845 pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
848 pb->var[i] = pb->var[j];
849 pb->var[j] = pb->var[n_vars];
851 else if (i < n_vars)
853 for (e = pb->num_geqs - 1; e >= 0; e--)
854 if (pb->geqs[e].coef[n_vars])
856 pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
857 pb->geqs[e].touched = 1;
860 for (e = pb->num_eqs - 1; e >= 0; e--)
861 pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
863 for (e = pb->num_subs - 1; e >= 0; e--)
864 pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
866 pb->var[i] = pb->var[n_vars];
869 if (omega_safe_var_p (pb, i))
870 pb->safe_vars--;
872 pb->num_vars--;
875 /* Because the coefficients of an equation are sparse, PACKING records
876 indices for non null coefficients. */
877 static int *packing;
879 /* Set up the coefficients of PACKING, following the coefficients of
880 equation EQN that has NUM_VARS variables. */
882 static inline int
883 setup_packing (eqn eqn, int num_vars)
885 int k;
886 int n = 0;
888 for (k = num_vars; k >= 0; k--)
889 if (eqn->coef[k])
890 packing[n++] = k;
892 return n;
895 /* Computes a linear combination of EQ and SUB at VAR with coefficient
896 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
897 non null indices of SUB stored in PACKING. */
899 static inline void
900 omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
901 int top_var)
903 if (eq->coef[var] != 0)
905 if (eq->color == omega_black)
906 *found_black = true;
907 else
909 int j, k = eq->coef[var];
911 eq->coef[var] = 0;
913 for (j = top_var; j >= 0; j--)
914 eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
919 /* Substitute in PB variable VAR with "C * SUB". */
921 static void
922 omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
924 int e, top_var = setup_packing (sub, pb->num_vars);
926 *found_black = false;
928 if (dump_file && (dump_flags & TDF_DETAILS))
930 if (sub->color == omega_red)
931 fprintf (dump_file, "[");
933 fprintf (dump_file, "substituting using %s := ",
934 omega_variable_to_str (pb, var));
935 omega_print_term (dump_file, pb, sub, -c);
937 if (sub->color == omega_red)
938 fprintf (dump_file, "]");
940 fprintf (dump_file, "\n");
941 omega_print_vars (dump_file, pb);
944 for (e = pb->num_eqs - 1; e >= 0; e--)
946 eqn eqn = &(pb->eqs[e]);
948 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
950 if (dump_file && (dump_flags & TDF_DETAILS))
952 omega_print_eq (dump_file, pb, eqn);
953 fprintf (dump_file, "\n");
957 for (e = pb->num_geqs - 1; e >= 0; e--)
959 eqn eqn = &(pb->geqs[e]);
961 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
963 if (eqn->coef[var] && eqn->color == omega_red)
964 eqn->touched = 1;
966 if (dump_file && (dump_flags & TDF_DETAILS))
968 omega_print_geq (dump_file, pb, eqn);
969 fprintf (dump_file, "\n");
973 for (e = pb->num_subs - 1; e >= 0; e--)
975 eqn eqn = &(pb->subs[e]);
977 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
979 if (dump_file && (dump_flags & TDF_DETAILS))
981 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
982 omega_print_term (dump_file, pb, eqn, 1);
983 fprintf (dump_file, "\n");
987 if (dump_file && (dump_flags & TDF_DETAILS))
988 fprintf (dump_file, "---\n\n");
990 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
991 *found_black = true;
994 /* Substitute in PB variable VAR with "C * SUB". */
996 static void
997 omega_substitute (omega_pb pb, eqn sub, int var, int c)
999 int e, j, j0;
1000 int top_var = setup_packing (sub, pb->num_vars);
1002 if (dump_file && (dump_flags & TDF_DETAILS))
1004 fprintf (dump_file, "substituting using %s := ",
1005 omega_variable_to_str (pb, var));
1006 omega_print_term (dump_file, pb, sub, -c);
1007 fprintf (dump_file, "\n");
1008 omega_print_vars (dump_file, pb);
1011 if (top_var < 0)
1013 for (e = pb->num_eqs - 1; e >= 0; e--)
1014 pb->eqs[e].coef[var] = 0;
1016 for (e = pb->num_geqs - 1; e >= 0; e--)
1017 if (pb->geqs[e].coef[var] != 0)
1019 pb->geqs[e].touched = 1;
1020 pb->geqs[e].coef[var] = 0;
1023 for (e = pb->num_subs - 1; e >= 0; e--)
1024 pb->subs[e].coef[var] = 0;
1026 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1028 int k;
1029 eqn eqn = &(pb->subs[pb->num_subs++]);
1031 for (k = pb->num_vars; k >= 0; k--)
1032 eqn->coef[k] = 0;
1034 eqn->key = pb->var[var];
1035 eqn->color = omega_black;
1038 else if (top_var == 0 && packing[0] == 0)
1040 c = -sub->coef[0] * c;
1042 for (e = pb->num_eqs - 1; e >= 0; e--)
1044 pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
1045 pb->eqs[e].coef[var] = 0;
1048 for (e = pb->num_geqs - 1; e >= 0; e--)
1049 if (pb->geqs[e].coef[var] != 0)
1051 pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
1052 pb->geqs[e].coef[var] = 0;
1053 pb->geqs[e].touched = 1;
1056 for (e = pb->num_subs - 1; e >= 0; e--)
1058 pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
1059 pb->subs[e].coef[var] = 0;
1062 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1064 int k;
1065 eqn eqn = &(pb->subs[pb->num_subs++]);
1067 for (k = pb->num_vars; k >= 1; k--)
1068 eqn->coef[k] = 0;
1070 eqn->coef[0] = c;
1071 eqn->key = pb->var[var];
1072 eqn->color = omega_black;
1075 if (dump_file && (dump_flags & TDF_DETAILS))
1077 fprintf (dump_file, "---\n\n");
1078 omega_print_problem (dump_file, pb);
1079 fprintf (dump_file, "===\n\n");
1082 else
1084 for (e = pb->num_eqs - 1; e >= 0; e--)
1086 eqn eqn = &(pb->eqs[e]);
1087 int k = eqn->coef[var];
1089 if (k != 0)
1091 k = c * k;
1092 eqn->coef[var] = 0;
1094 for (j = top_var; j >= 0; j--)
1096 j0 = packing[j];
1097 eqn->coef[j0] -= sub->coef[j0] * k;
1101 if (dump_file && (dump_flags & TDF_DETAILS))
1103 omega_print_eq (dump_file, pb, eqn);
1104 fprintf (dump_file, "\n");
1108 for (e = pb->num_geqs - 1; e >= 0; e--)
1110 eqn eqn = &(pb->geqs[e]);
1111 int k = eqn->coef[var];
1113 if (k != 0)
1115 k = c * k;
1116 eqn->touched = 1;
1117 eqn->coef[var] = 0;
1119 for (j = top_var; j >= 0; j--)
1121 j0 = packing[j];
1122 eqn->coef[j0] -= sub->coef[j0] * k;
1126 if (dump_file && (dump_flags & TDF_DETAILS))
1128 omega_print_geq (dump_file, pb, eqn);
1129 fprintf (dump_file, "\n");
1133 for (e = pb->num_subs - 1; e >= 0; e--)
1135 eqn eqn = &(pb->subs[e]);
1136 int k = eqn->coef[var];
1138 if (k != 0)
1140 k = c * k;
1141 eqn->coef[var] = 0;
1143 for (j = top_var; j >= 0; j--)
1145 j0 = packing[j];
1146 eqn->coef[j0] -= sub->coef[j0] * k;
1150 if (dump_file && (dump_flags & TDF_DETAILS))
1152 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1153 omega_print_term (dump_file, pb, eqn, 1);
1154 fprintf (dump_file, "\n");
1158 if (dump_file && (dump_flags & TDF_DETAILS))
1160 fprintf (dump_file, "---\n\n");
1161 omega_print_problem (dump_file, pb);
1162 fprintf (dump_file, "===\n\n");
1165 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1167 int k;
1168 eqn eqn = &(pb->subs[pb->num_subs++]);
1169 c = -c;
1171 for (k = pb->num_vars; k >= 0; k--)
1172 eqn->coef[k] = c * (sub->coef[k]);
1174 eqn->key = pb->var[var];
1175 eqn->color = sub->color;
1180 /* Solve e = factor alpha for x_j and substitute. */
1182 static void
1183 omega_do_mod (omega_pb pb, int factor, int e, int j)
1185 int k, i;
1186 eqn eq = omega_alloc_eqns (0, 1);
1187 int nfactor;
1188 bool kill_j = false;
1190 omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
1192 for (k = pb->num_vars; k >= 0; k--)
1194 eq->coef[k] = int_mod (eq->coef[k], factor);
1196 if (2 * eq->coef[k] >= factor)
1197 eq->coef[k] -= factor;
1200 nfactor = eq->coef[j];
1202 if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
1204 i = omega_add_new_wild_card (pb);
1205 eq->coef[pb->num_vars] = eq->coef[i];
1206 eq->coef[j] = 0;
1207 eq->coef[i] = -factor;
1208 kill_j = true;
1210 else
1212 eq->coef[j] = -factor;
1213 if (!omega_wildcard_p (pb, j))
1214 omega_name_wild_card (pb, j);
1217 omega_substitute (pb, eq, j, nfactor);
1219 for (k = pb->num_vars; k >= 0; k--)
1220 pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
1222 if (kill_j)
1223 omega_delete_variable (pb, j);
1225 if (dump_file && (dump_flags & TDF_DETAILS))
1227 fprintf (dump_file, "Mod-ing and normalizing produces:\n");
1228 omega_print_problem (dump_file, pb);
1231 omega_free_eqns (eq, 1);
1234 /* Multiplies by -1 inequality E. */
1236 void
1237 omega_negate_geq (omega_pb pb, int e)
1239 int i;
1241 for (i = pb->num_vars; i >= 0; i--)
1242 pb->geqs[e].coef[i] *= -1;
1244 pb->geqs[e].coef[0]--;
1245 pb->geqs[e].touched = 1;
1248 /* Returns OMEGA_TRUE when problem PB has a solution. */
1250 static enum omega_result
1251 verify_omega_pb (omega_pb pb)
1253 enum omega_result result;
1254 int e;
1255 bool any_color = false;
1256 omega_pb tmp_problem = XNEW (struct omega_pb_d);
1258 omega_copy_problem (tmp_problem, pb);
1259 tmp_problem->safe_vars = 0;
1260 tmp_problem->num_subs = 0;
1262 for (e = pb->num_geqs - 1; e >= 0; e--)
1263 if (pb->geqs[e].color == omega_red)
1265 any_color = true;
1266 break;
1269 if (please_no_equalities_in_simplified_problems)
1270 any_color = true;
1272 if (any_color)
1273 original_problem = no_problem;
1274 else
1275 original_problem = pb;
1277 if (dump_file && (dump_flags & TDF_DETAILS))
1279 fprintf (dump_file, "verifying problem");
1281 if (any_color)
1282 fprintf (dump_file, " (color mode)");
1284 fprintf (dump_file, " :\n");
1285 omega_print_problem (dump_file, pb);
1288 result = omega_solve_problem (tmp_problem, omega_unknown);
1289 original_problem = no_problem;
1290 free (tmp_problem);
1292 if (dump_file && (dump_flags & TDF_DETAILS))
1294 if (result != omega_false)
1295 fprintf (dump_file, "verified problem\n");
1296 else
1297 fprintf (dump_file, "disproved problem\n");
1298 omega_print_problem (dump_file, pb);
1301 return result;
1304 /* Add a new equality to problem PB at last position E. */
1306 static void
1307 adding_equality_constraint (omega_pb pb, int e)
1309 if (original_problem != no_problem
1310 && original_problem != pb
1311 && !conservative)
1313 int i, j;
1314 int e2 = original_problem->num_eqs++;
1316 if (dump_file && (dump_flags & TDF_DETAILS))
1317 fprintf (dump_file,
1318 "adding equality constraint %d to outer problem\n", e2);
1319 omega_init_eqn_zero (&original_problem->eqs[e2],
1320 original_problem->num_vars);
1322 for (i = pb->num_vars; i >= 1; i--)
1324 for (j = original_problem->num_vars; j >= 1; j--)
1325 if (original_problem->var[j] == pb->var[i])
1326 break;
1328 if (j <= 0)
1330 if (dump_file && (dump_flags & TDF_DETAILS))
1331 fprintf (dump_file, "retracting\n");
1332 original_problem->num_eqs--;
1333 return;
1335 original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
1338 original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
1340 if (dump_file && (dump_flags & TDF_DETAILS))
1341 omega_print_problem (dump_file, original_problem);
1345 static int *fast_lookup;
1346 static int *fast_lookup_red;
1348 typedef enum {
1349 normalize_false,
1350 normalize_uncoupled,
1351 normalize_coupled
1352 } normalize_return_type;
1354 /* Normalizes PB by removing redundant constraints. Returns
1355 normalize_false when the constraints system has no solution,
1356 otherwise returns normalize_coupled or normalize_uncoupled. */
1358 static normalize_return_type
1359 normalize_omega_problem (omega_pb pb)
1361 int e, i, j, k, n_vars;
1362 int coupled_subscripts = 0;
1364 n_vars = pb->num_vars;
1366 for (e = 0; e < pb->num_geqs; e++)
1368 if (!pb->geqs[e].touched)
1370 if (!single_var_geq (&pb->geqs[e], n_vars))
1371 coupled_subscripts = 1;
1373 else
1375 int g, top_var, i0, hashCode;
1376 int *p = &packing[0];
1378 for (k = 1; k <= n_vars; k++)
1379 if (pb->geqs[e].coef[k])
1380 *(p++) = k;
1382 top_var = (p - &packing[0]) - 1;
1384 if (top_var == -1)
1386 if (pb->geqs[e].coef[0] < 0)
1388 if (dump_file && (dump_flags & TDF_DETAILS))
1390 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1391 fprintf (dump_file, "\nequations have no solution \n");
1393 return normalize_false;
1396 omega_delete_geq (pb, e, n_vars);
1397 e--;
1398 continue;
1400 else if (top_var == 0)
1402 int singlevar = packing[0];
1404 g = pb->geqs[e].coef[singlevar];
1406 if (g > 0)
1408 pb->geqs[e].coef[singlevar] = 1;
1409 pb->geqs[e].key = singlevar;
1411 else
1413 g = -g;
1414 pb->geqs[e].coef[singlevar] = -1;
1415 pb->geqs[e].key = -singlevar;
1418 if (g > 1)
1419 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1421 else
1423 int g2;
1424 int hash_key_multiplier = 31;
1426 coupled_subscripts = 1;
1427 i0 = top_var;
1428 i = packing[i0--];
1429 g = pb->geqs[e].coef[i];
1430 hashCode = g * (i + 3);
1432 if (g < 0)
1433 g = -g;
1435 for (; i0 >= 0; i0--)
1437 int x;
1439 i = packing[i0];
1440 x = pb->geqs[e].coef[i];
1441 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1443 if (x < 0)
1444 x = -x;
1446 if (x == 1)
1448 g = 1;
1449 i0--;
1450 break;
1452 else
1453 g = gcd (x, g);
1456 for (; i0 >= 0; i0--)
1458 int x;
1459 i = packing[i0];
1460 x = pb->geqs[e].coef[i];
1461 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1464 if (g > 1)
1466 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1467 i0 = top_var;
1468 i = packing[i0--];
1469 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1470 hashCode = pb->geqs[e].coef[i] * (i + 3);
1472 for (; i0 >= 0; i0--)
1474 i = packing[i0];
1475 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1476 hashCode = hashCode * hash_key_multiplier * (i + 3)
1477 + pb->geqs[e].coef[i];
1481 g2 = abs (hashCode);
1483 if (dump_file && (dump_flags & TDF_DETAILS))
1485 fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
1486 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1487 fprintf (dump_file, "\n");
1490 j = g2 % HASH_TABLE_SIZE;
1492 do {
1493 eqn proto = &(hash_master[j]);
1495 if (proto->touched == g2)
1497 if (proto->coef[0] == top_var)
1499 if (hashCode >= 0)
1500 for (i0 = top_var; i0 >= 0; i0--)
1502 i = packing[i0];
1504 if (pb->geqs[e].coef[i] != proto->coef[i])
1505 break;
1507 else
1508 for (i0 = top_var; i0 >= 0; i0--)
1510 i = packing[i0];
1512 if (pb->geqs[e].coef[i] != -proto->coef[i])
1513 break;
1516 if (i0 < 0)
1518 if (hashCode >= 0)
1519 pb->geqs[e].key = proto->key;
1520 else
1521 pb->geqs[e].key = -proto->key;
1522 break;
1526 else if (proto->touched < 0)
1528 omega_init_eqn_zero (proto, pb->num_vars);
1529 if (hashCode >= 0)
1530 for (i0 = top_var; i0 >= 0; i0--)
1532 i = packing[i0];
1533 proto->coef[i] = pb->geqs[e].coef[i];
1535 else
1536 for (i0 = top_var; i0 >= 0; i0--)
1538 i = packing[i0];
1539 proto->coef[i] = -pb->geqs[e].coef[i];
1542 proto->coef[0] = top_var;
1543 proto->touched = g2;
1545 if (dump_file && (dump_flags & TDF_DETAILS))
1546 fprintf (dump_file, " constraint key = %d\n",
1547 next_key);
1549 proto->key = next_key++;
1551 /* Too many hash keys generated. */
1552 gcc_assert (proto->key <= MAX_KEYS);
1554 if (hashCode >= 0)
1555 pb->geqs[e].key = proto->key;
1556 else
1557 pb->geqs[e].key = -proto->key;
1559 break;
1562 j = (j + 1) % HASH_TABLE_SIZE;
1563 } while (1);
1566 pb->geqs[e].touched = 0;
1570 int eKey = pb->geqs[e].key;
1571 int e2;
1572 if (e > 0)
1574 int cTerm = pb->geqs[e].coef[0];
1575 e2 = fast_lookup[MAX_KEYS - eKey];
1577 if (e2 < e && pb->geqs[e2].key == -eKey
1578 && pb->geqs[e2].color == omega_black)
1580 if (pb->geqs[e2].coef[0] < -cTerm)
1582 if (dump_file && (dump_flags & TDF_DETAILS))
1584 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1585 fprintf (dump_file, "\n");
1586 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1587 fprintf (dump_file,
1588 "\nequations have no solution \n");
1590 return normalize_false;
1593 if (pb->geqs[e2].coef[0] == -cTerm
1594 && (create_color
1595 || pb->geqs[e].color == omega_black))
1597 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1598 pb->num_vars);
1599 if (pb->geqs[e].color == omega_black)
1600 adding_equality_constraint (pb, pb->num_eqs);
1601 pb->num_eqs++;
1602 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1606 e2 = fast_lookup_red[MAX_KEYS - eKey];
1608 if (e2 < e && pb->geqs[e2].key == -eKey
1609 && pb->geqs[e2].color == omega_red)
1611 if (pb->geqs[e2].coef[0] < -cTerm)
1613 if (dump_file && (dump_flags & TDF_DETAILS))
1615 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1616 fprintf (dump_file, "\n");
1617 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1618 fprintf (dump_file,
1619 "\nequations have no solution \n");
1621 return normalize_false;
1624 if (pb->geqs[e2].coef[0] == -cTerm && create_color)
1626 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1627 pb->num_vars);
1628 pb->eqs[pb->num_eqs].color = omega_red;
1629 pb->num_eqs++;
1630 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1634 e2 = fast_lookup[MAX_KEYS + eKey];
1636 if (e2 < e && pb->geqs[e2].key == eKey
1637 && pb->geqs[e2].color == omega_black)
1639 if (pb->geqs[e2].coef[0] > cTerm)
1641 if (pb->geqs[e].color == omega_black)
1643 if (dump_file && (dump_flags & TDF_DETAILS))
1645 fprintf (dump_file,
1646 "Removing Redundant Equation: ");
1647 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1648 fprintf (dump_file, "\n");
1649 fprintf (dump_file,
1650 "[a] Made Redundant by: ");
1651 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1652 fprintf (dump_file, "\n");
1654 pb->geqs[e2].coef[0] = cTerm;
1655 omega_delete_geq (pb, e, n_vars);
1656 e--;
1657 continue;
1660 else
1662 if (dump_file && (dump_flags & TDF_DETAILS))
1664 fprintf (dump_file, "Removing Redundant Equation: ");
1665 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1666 fprintf (dump_file, "\n");
1667 fprintf (dump_file, "[b] Made Redundant by: ");
1668 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1669 fprintf (dump_file, "\n");
1671 omega_delete_geq (pb, e, n_vars);
1672 e--;
1673 continue;
1677 e2 = fast_lookup_red[MAX_KEYS + eKey];
1679 if (e2 < e && pb->geqs[e2].key == eKey
1680 && pb->geqs[e2].color == omega_red)
1682 if (pb->geqs[e2].coef[0] >= cTerm)
1684 if (dump_file && (dump_flags & TDF_DETAILS))
1686 fprintf (dump_file, "Removing Redundant Equation: ");
1687 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1688 fprintf (dump_file, "\n");
1689 fprintf (dump_file, "[c] Made Redundant by: ");
1690 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1691 fprintf (dump_file, "\n");
1693 pb->geqs[e2].coef[0] = cTerm;
1694 pb->geqs[e2].color = pb->geqs[e].color;
1696 else if (pb->geqs[e].color == omega_red)
1698 if (dump_file && (dump_flags & TDF_DETAILS))
1700 fprintf (dump_file, "Removing Redundant Equation: ");
1701 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1702 fprintf (dump_file, "\n");
1703 fprintf (dump_file, "[d] Made Redundant by: ");
1704 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1705 fprintf (dump_file, "\n");
1708 omega_delete_geq (pb, e, n_vars);
1709 e--;
1710 continue;
1715 if (pb->geqs[e].color == omega_red)
1716 fast_lookup_red[MAX_KEYS + eKey] = e;
1717 else
1718 fast_lookup[MAX_KEYS + eKey] = e;
1722 create_color = false;
1723 return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
1726 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1727 of variables in EQN. */
1729 static inline void
1730 divide_eqn_by_gcd (eqn eqn, int n_vars)
1732 int var, g = 0;
1734 for (var = n_vars; var >= 0; var--)
1735 g = gcd (abs (eqn->coef[var]), g);
1737 if (g)
1738 for (var = n_vars; var >= 0; var--)
1739 eqn->coef[var] = eqn->coef[var] / g;
1742 /* Rewrite some non-safe variables in function of protected
1743 wildcard variables. */
1745 static void
1746 cleanout_wildcards (omega_pb pb)
1748 int e, i, j;
1749 int n_vars = pb->num_vars;
1750 bool renormalize = false;
1752 for (e = pb->num_eqs - 1; e >= 0; e--)
1753 for (i = n_vars; !omega_safe_var_p (pb, i); i--)
1754 if (pb->eqs[e].coef[i] != 0)
1756 /* i is the last nonzero non-safe variable. */
1758 for (j = i - 1; !omega_safe_var_p (pb, j); j--)
1759 if (pb->eqs[e].coef[j] != 0)
1760 break;
1762 /* j is the next nonzero non-safe variable, or points
1763 to a safe variable: it is then a wildcard variable. */
1765 /* Clean it out. */
1766 if (omega_safe_var_p (pb, j))
1768 eqn sub = &(pb->eqs[e]);
1769 int c = pb->eqs[e].coef[i];
1770 int a = abs (c);
1771 int e2;
1773 if (dump_file && (dump_flags & TDF_DETAILS))
1775 fprintf (dump_file,
1776 "Found a single wild card equality: ");
1777 omega_print_eq (dump_file, pb, &pb->eqs[e]);
1778 fprintf (dump_file, "\n");
1779 omega_print_problem (dump_file, pb);
1782 for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
1783 if (e != e2 && pb->eqs[e2].coef[i]
1784 && (pb->eqs[e2].color == omega_red
1785 || (pb->eqs[e2].color == omega_black
1786 && pb->eqs[e].color == omega_black)))
1788 eqn eqn = &(pb->eqs[e2]);
1789 int var, k;
1791 for (var = n_vars; var >= 0; var--)
1792 eqn->coef[var] *= a;
1794 k = eqn->coef[i];
1796 for (var = n_vars; var >= 0; var--)
1797 eqn->coef[var] -= sub->coef[var] * k / c;
1799 eqn->coef[i] = 0;
1800 divide_eqn_by_gcd (eqn, n_vars);
1803 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
1804 if (pb->geqs[e2].coef[i]
1805 && (pb->geqs[e2].color == omega_red
1806 || (pb->eqs[e].color == omega_black
1807 && pb->geqs[e2].color == omega_black)))
1809 eqn eqn = &(pb->geqs[e2]);
1810 int var, k;
1812 for (var = n_vars; var >= 0; var--)
1813 eqn->coef[var] *= a;
1815 k = eqn->coef[i];
1817 for (var = n_vars; var >= 0; var--)
1818 eqn->coef[var] -= sub->coef[var] * k / c;
1820 eqn->coef[i] = 0;
1821 eqn->touched = 1;
1822 renormalize = true;
1825 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
1826 if (pb->subs[e2].coef[i]
1827 && (pb->subs[e2].color == omega_red
1828 || (pb->subs[e2].color == omega_black
1829 && pb->eqs[e].color == omega_black)))
1831 eqn eqn = &(pb->subs[e2]);
1832 int var, k;
1834 for (var = n_vars; var >= 0; var--)
1835 eqn->coef[var] *= a;
1837 k = eqn->coef[i];
1839 for (var = n_vars; var >= 0; var--)
1840 eqn->coef[var] -= sub->coef[var] * k / c;
1842 eqn->coef[i] = 0;
1843 divide_eqn_by_gcd (eqn, n_vars);
1846 if (dump_file && (dump_flags & TDF_DETAILS))
1848 fprintf (dump_file, "cleaned-out wildcard: ");
1849 omega_print_problem (dump_file, pb);
1851 break;
1855 if (renormalize)
1856 normalize_omega_problem (pb);
1859 /* Swap values contained in I and J. */
1861 static inline void
1862 swap (int *i, int *j)
1864 int tmp;
1865 tmp = *i;
1866 *i = *j;
1867 *j = tmp;
1870 /* Swap values contained in I and J. */
1872 static inline void
1873 bswap (bool *i, bool *j)
1875 bool tmp;
1876 tmp = *i;
1877 *i = *j;
1878 *j = tmp;
1881 /* Make variable IDX unprotected in PB, by swapping its index at the
1882 PB->safe_vars rank. */
1884 static inline void
1885 omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
1887 /* If IDX is protected... */
1888 if (*idx < pb->safe_vars)
1890 /* ... swap its index with the last non protected index. */
1891 int j = pb->safe_vars;
1892 int e;
1894 for (e = pb->num_geqs - 1; e >= 0; e--)
1896 pb->geqs[e].touched = 1;
1897 swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
1900 for (e = pb->num_eqs - 1; e >= 0; e--)
1901 swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
1903 for (e = pb->num_subs - 1; e >= 0; e--)
1904 swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
1906 if (unprotect)
1907 bswap (&unprotect[*idx], &unprotect[j]);
1909 swap (&pb->var[*idx], &pb->var[j]);
1910 pb->forwarding_address[pb->var[*idx]] = *idx;
1911 pb->forwarding_address[pb->var[j]] = j;
1912 (*idx)--;
1915 /* The variable at pb->safe_vars is also unprotected now. */
1916 pb->safe_vars--;
1919 /* During the Fourier-Motzkin elimination some variables are
1920 substituted with other variables. This function resurrects the
1921 substituted variables in PB. */
1923 static void
1924 resurrect_subs (omega_pb pb)
1926 if (pb->num_subs > 0
1927 && please_no_equalities_in_simplified_problems == 0)
1929 int i, e, m;
1931 if (dump_file && (dump_flags & TDF_DETAILS))
1933 fprintf (dump_file,
1934 "problem reduced, bringing variables back to life\n");
1935 omega_print_problem (dump_file, pb);
1938 for (i = 1; omega_safe_var_p (pb, i); i++)
1939 if (omega_wildcard_p (pb, i))
1940 omega_unprotect_1 (pb, &i, NULL);
1942 m = pb->num_subs;
1944 for (e = pb->num_geqs - 1; e >= 0; e--)
1945 if (single_var_geq (&pb->geqs[e], pb->num_vars))
1947 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
1948 pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
1950 else
1952 pb->geqs[e].touched = 1;
1953 pb->geqs[e].key = 0;
1956 for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
1958 pb->var[i + m] = pb->var[i];
1960 for (e = pb->num_geqs - 1; e >= 0; e--)
1961 pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
1963 for (e = pb->num_eqs - 1; e >= 0; e--)
1964 pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
1966 for (e = pb->num_subs - 1; e >= 0; e--)
1967 pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
1970 for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
1972 for (e = pb->num_geqs - 1; e >= 0; e--)
1973 pb->geqs[e].coef[i] = 0;
1975 for (e = pb->num_eqs - 1; e >= 0; e--)
1976 pb->eqs[e].coef[i] = 0;
1978 for (e = pb->num_subs - 1; e >= 0; e--)
1979 pb->subs[e].coef[i] = 0;
1982 pb->num_vars += m;
1984 for (e = pb->num_subs - 1; e >= 0; e--)
1986 pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
1987 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
1988 pb->num_vars);
1989 pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
1990 pb->eqs[pb->num_eqs].color = omega_black;
1992 if (dump_file && (dump_flags & TDF_DETAILS))
1994 fprintf (dump_file, "brought back: ");
1995 omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
1996 fprintf (dump_file, "\n");
1999 pb->num_eqs++;
2000 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2003 pb->safe_vars += m;
2004 pb->num_subs = 0;
2006 if (dump_file && (dump_flags & TDF_DETAILS))
2008 fprintf (dump_file, "variables brought back to life\n");
2009 omega_print_problem (dump_file, pb);
2012 cleanout_wildcards (pb);
2016 static inline bool
2017 implies (unsigned int a, unsigned int b)
2019 return (a == (a & b));
2022 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2023 extra step is performed. Returns omega_false when there exist no
2024 solution, omega_true otherwise. */
2026 enum omega_result
2027 omega_eliminate_redundant (omega_pb pb, bool expensive)
2029 int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
2030 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2031 omega_pb tmp_problem;
2033 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2034 unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2035 unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2036 unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2038 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2039 unsigned int pp, pz, pn;
2041 if (dump_file && (dump_flags & TDF_DETAILS))
2043 fprintf (dump_file, "in eliminate Redundant:\n");
2044 omega_print_problem (dump_file, pb);
2047 for (e = pb->num_geqs - 1; e >= 0; e--)
2049 int tmp = 1;
2051 is_dead[e] = false;
2052 peqs[e] = zeqs[e] = neqs[e] = 0;
2054 for (i = pb->num_vars; i >= 1; i--)
2056 if (pb->geqs[e].coef[i] > 0)
2057 peqs[e] |= tmp;
2058 else if (pb->geqs[e].coef[i] < 0)
2059 neqs[e] |= tmp;
2060 else
2061 zeqs[e] |= tmp;
2063 tmp <<= 1;
2068 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2069 if (!is_dead[e1])
2070 for (e2 = e1 - 1; e2 >= 0; e2--)
2071 if (!is_dead[e2])
2073 for (p = pb->num_vars; p > 1; p--)
2074 for (q = p - 1; q > 0; q--)
2075 if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
2076 - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
2077 goto foundPQ;
2079 continue;
2081 foundPQ:
2082 pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
2083 | (neqs[e1] & peqs[e2]));
2084 pp = peqs[e1] | peqs[e2];
2085 pn = neqs[e1] | neqs[e2];
2087 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2088 if (e3 != e1 && e3 != e2)
2090 if (!implies (zeqs[e3], pz))
2091 goto nextE3;
2093 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2094 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2095 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2096 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2097 alpha3 = alpha;
2099 if (alpha1 * alpha2 <= 0)
2100 goto nextE3;
2102 if (alpha1 < 0)
2104 alpha1 = -alpha1;
2105 alpha2 = -alpha2;
2106 alpha3 = -alpha3;
2109 if (alpha3 > 0)
2111 /* Trying to prove e3 is redundant. */
2112 if (!implies (peqs[e3], pp)
2113 || !implies (neqs[e3], pn))
2114 goto nextE3;
2116 if (pb->geqs[e3].color == omega_black
2117 && (pb->geqs[e1].color == omega_red
2118 || pb->geqs[e2].color == omega_red))
2119 goto nextE3;
2121 for (k = pb->num_vars; k >= 1; k--)
2122 if (alpha3 * pb->geqs[e3].coef[k]
2123 != (alpha1 * pb->geqs[e1].coef[k]
2124 + alpha2 * pb->geqs[e2].coef[k]))
2125 goto nextE3;
2127 c = (alpha1 * pb->geqs[e1].coef[0]
2128 + alpha2 * pb->geqs[e2].coef[0]);
2130 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2132 if (dump_file && (dump_flags & TDF_DETAILS))
2134 fprintf (dump_file,
2135 "found redundant inequality\n");
2136 fprintf (dump_file,
2137 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2138 alpha1, alpha2, alpha3);
2140 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2141 fprintf (dump_file, "\n");
2142 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2143 fprintf (dump_file, "\n=> ");
2144 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2145 fprintf (dump_file, "\n\n");
2148 is_dead[e3] = true;
2151 else
2153 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2154 or trying to prove e3 < 0, and therefore the
2155 problem has no solutions. */
2156 if (!implies (peqs[e3], pn)
2157 || !implies (neqs[e3], pp))
2158 goto nextE3;
2160 if (pb->geqs[e1].color == omega_red
2161 || pb->geqs[e2].color == omega_red
2162 || pb->geqs[e3].color == omega_red)
2163 goto nextE3;
2165 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2166 for (k = pb->num_vars; k >= 1; k--)
2167 if (alpha3 * pb->geqs[e3].coef[k]
2168 != (alpha1 * pb->geqs[e1].coef[k]
2169 + alpha2 * pb->geqs[e2].coef[k]))
2170 goto nextE3;
2172 c = (alpha1 * pb->geqs[e1].coef[0]
2173 + alpha2 * pb->geqs[e2].coef[0]);
2175 if (c < alpha3 * (pb->geqs[e3].coef[0]))
2177 /* We just proved e3 < 0, so no solutions exist. */
2178 if (dump_file && (dump_flags & TDF_DETAILS))
2180 fprintf (dump_file,
2181 "found implied over tight inequality\n");
2182 fprintf (dump_file,
2183 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2184 alpha1, alpha2, -alpha3);
2185 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2186 fprintf (dump_file, "\n");
2187 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2188 fprintf (dump_file, "\n=> not ");
2189 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2190 fprintf (dump_file, "\n\n");
2192 free (is_dead);
2193 free (peqs);
2194 free (zeqs);
2195 free (neqs);
2196 return omega_false;
2198 else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2200 /* We just proved that e3 <=0, so e3 = 0. */
2201 if (dump_file && (dump_flags & TDF_DETAILS))
2203 fprintf (dump_file,
2204 "found implied tight inequality\n");
2205 fprintf (dump_file,
2206 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2207 alpha1, alpha2, -alpha3);
2208 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2209 fprintf (dump_file, "\n");
2210 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2211 fprintf (dump_file, "\n=> inverse ");
2212 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2213 fprintf (dump_file, "\n\n");
2216 omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2217 &pb->geqs[e3], pb->num_vars);
2218 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2219 adding_equality_constraint (pb, pb->num_eqs - 1);
2220 is_dead[e3] = true;
2223 nextE3:;
2227 /* Delete the inequalities that were marked as dead. */
2228 for (e = pb->num_geqs - 1; e >= 0; e--)
2229 if (is_dead[e])
2230 omega_delete_geq (pb, e, pb->num_vars);
2232 if (!expensive)
2233 goto eliminate_redundant_done;
2235 tmp_problem = XNEW (struct omega_pb_d);
2236 conservative++;
2238 for (e = pb->num_geqs - 1; e >= 0; e--)
2240 if (dump_file && (dump_flags & TDF_DETAILS))
2242 fprintf (dump_file,
2243 "checking equation %d to see if it is redundant: ", e);
2244 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2245 fprintf (dump_file, "\n");
2248 omega_copy_problem (tmp_problem, pb);
2249 omega_negate_geq (tmp_problem, e);
2250 tmp_problem->safe_vars = 0;
2251 tmp_problem->variables_freed = false;
2253 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2254 omega_delete_geq (pb, e, pb->num_vars);
2257 free (tmp_problem);
2258 conservative--;
2260 if (!omega_reduce_with_subs)
2262 resurrect_subs (pb);
2263 gcc_assert (please_no_equalities_in_simplified_problems
2264 || pb->num_subs == 0);
2267 eliminate_redundant_done:
2268 free (is_dead);
2269 free (peqs);
2270 free (zeqs);
2271 free (neqs);
2272 return omega_true;
2275 /* For each inequality that has coefficients bigger than 20, try to
2276 create a new constraint that cannot be derived from the original
2277 constraint and that has smaller coefficients. Add the new
2278 constraint at the end of geqs. Return the number of inequalities
2279 that have been added to PB. */
2281 static int
2282 smooth_weird_equations (omega_pb pb)
2284 int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2285 int c;
2286 int v;
2287 int result = 0;
2289 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2290 if (pb->geqs[e1].color == omega_black)
2292 int g = 999999;
2294 for (v = pb->num_vars; v >= 1; v--)
2295 if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2296 g = abs (pb->geqs[e1].coef[v]);
2298 /* Magic number. */
2299 if (g > 20)
2301 e3 = pb->num_geqs;
2303 for (v = pb->num_vars; v >= 1; v--)
2304 pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2307 pb->geqs[e3].color = omega_black;
2308 pb->geqs[e3].touched = 1;
2309 /* Magic number. */
2310 pb->geqs[e3].coef[0] = 9997;
2312 if (dump_file && (dump_flags & TDF_DETAILS))
2314 fprintf (dump_file, "Checking to see if we can derive: ");
2315 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2316 fprintf (dump_file, "\n from: ");
2317 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2318 fprintf (dump_file, "\n");
2321 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2322 if (e1 != e2 && pb->geqs[e2].color == omega_black)
2324 for (p = pb->num_vars; p > 1; p--)
2326 for (q = p - 1; q > 0; q--)
2328 alpha =
2329 (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2330 pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2331 if (alpha != 0)
2332 goto foundPQ;
2335 continue;
2337 foundPQ:
2339 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2340 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2341 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2342 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2343 alpha3 = alpha;
2345 if (alpha1 * alpha2 <= 0)
2346 continue;
2348 if (alpha1 < 0)
2350 alpha1 = -alpha1;
2351 alpha2 = -alpha2;
2352 alpha3 = -alpha3;
2355 if (alpha3 > 0)
2357 /* Try to prove e3 is redundant: verify
2358 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2359 for (k = pb->num_vars; k >= 1; k--)
2360 if (alpha3 * pb->geqs[e3].coef[k]
2361 != (alpha1 * pb->geqs[e1].coef[k]
2362 + alpha2 * pb->geqs[e2].coef[k]))
2363 goto nextE2;
2365 c = alpha1 * pb->geqs[e1].coef[0]
2366 + alpha2 * pb->geqs[e2].coef[0];
2368 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2369 pb->geqs[e3].coef[0] = int_div (c, alpha3);
2371 nextE2:;
2374 if (pb->geqs[e3].coef[0] < 9997)
2376 result++;
2377 pb->num_geqs++;
2379 if (dump_file && (dump_flags & TDF_DETAILS))
2381 fprintf (dump_file,
2382 "Smoothing weird equations; adding:\n");
2383 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2384 fprintf (dump_file, "\nto:\n");
2385 omega_print_problem (dump_file, pb);
2386 fprintf (dump_file, "\n\n");
2391 return result;
2394 /* Replace tuples of inequalities, that define upper and lower half
2395 spaces, with an equation. */
2397 static void
2398 coalesce (omega_pb pb)
2400 int e, e2;
2401 int colors = 0;
2402 bool *is_dead;
2403 int found_something = 0;
2405 for (e = 0; e < pb->num_geqs; e++)
2406 if (pb->geqs[e].color == omega_red)
2407 colors++;
2409 if (colors < 2)
2410 return;
2412 is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2414 for (e = 0; e < pb->num_geqs; e++)
2415 is_dead[e] = false;
2417 for (e = 0; e < pb->num_geqs; e++)
2418 if (pb->geqs[e].color == omega_red
2419 && !pb->geqs[e].touched)
2420 for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2421 if (!pb->geqs[e2].touched
2422 && pb->geqs[e].key == -pb->geqs[e2].key
2423 && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2424 && pb->geqs[e2].color == omega_red)
2426 omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2427 pb->num_vars);
2428 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2429 found_something++;
2430 is_dead[e] = true;
2431 is_dead[e2] = true;
2434 for (e = pb->num_geqs - 1; e >= 0; e--)
2435 if (is_dead[e])
2436 omega_delete_geq (pb, e, pb->num_vars);
2438 if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2440 fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2441 found_something);
2442 omega_print_problem (dump_file, pb);
2445 free (is_dead);
2448 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2449 true, continue to eliminate all the red inequalities. */
2451 void
2452 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2454 int e, e2, e3, i, j, k, a, alpha1, alpha2;
2455 int c = 0;
2456 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2457 int dead_count = 0;
2458 int red_found;
2459 omega_pb tmp_problem;
2461 if (dump_file && (dump_flags & TDF_DETAILS))
2463 fprintf (dump_file, "in eliminate RED:\n");
2464 omega_print_problem (dump_file, pb);
2467 if (pb->num_eqs > 0)
2468 omega_simplify_problem (pb);
2470 for (e = pb->num_geqs - 1; e >= 0; e--)
2471 is_dead[e] = false;
2473 for (e = pb->num_geqs - 1; e >= 0; e--)
2474 if (pb->geqs[e].color == omega_black && !is_dead[e])
2475 for (e2 = e - 1; e2 >= 0; e2--)
2476 if (pb->geqs[e2].color == omega_black
2477 && !is_dead[e2])
2479 a = 0;
2481 for (i = pb->num_vars; i > 1; i--)
2482 for (j = i - 1; j > 0; j--)
2483 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2484 - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2485 goto found_pair;
2487 continue;
2489 found_pair:
2490 if (dump_file && (dump_flags & TDF_DETAILS))
2492 fprintf (dump_file,
2493 "found two equations to combine, i = %s, ",
2494 omega_variable_to_str (pb, i));
2495 fprintf (dump_file, "j = %s, alpha = %d\n",
2496 omega_variable_to_str (pb, j), a);
2497 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2498 fprintf (dump_file, "\n");
2499 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2500 fprintf (dump_file, "\n");
2503 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2504 if (pb->geqs[e3].color == omega_red)
2506 alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2507 - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2508 alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2509 - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2511 if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2512 || (a < 0 && alpha1 < 0 && alpha2 < 0))
2514 if (dump_file && (dump_flags & TDF_DETAILS))
2516 fprintf (dump_file,
2517 "alpha1 = %d, alpha2 = %d;"
2518 "comparing against: ",
2519 alpha1, alpha2);
2520 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2521 fprintf (dump_file, "\n");
2524 for (k = pb->num_vars; k >= 0; k--)
2526 c = (alpha1 * pb->geqs[e].coef[k]
2527 + alpha2 * pb->geqs[e2].coef[k]);
2529 if (c != a * pb->geqs[e3].coef[k])
2530 break;
2532 if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2533 fprintf (dump_file, " %s: %d, %d\n",
2534 omega_variable_to_str (pb, k), c,
2535 a * pb->geqs[e3].coef[k]);
2538 if (k < 0
2539 || (k == 0 &&
2540 ((a > 0 && c < a * pb->geqs[e3].coef[k])
2541 || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2543 if (dump_file && (dump_flags & TDF_DETAILS))
2545 dead_count++;
2546 fprintf (dump_file,
2547 "red equation#%d is dead "
2548 "(%d dead so far, %d remain)\n",
2549 e3, dead_count,
2550 pb->num_geqs - dead_count);
2551 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2552 fprintf (dump_file, "\n");
2553 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2554 fprintf (dump_file, "\n");
2555 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2556 fprintf (dump_file, "\n");
2558 is_dead[e3] = true;
2564 for (e = pb->num_geqs - 1; e >= 0; e--)
2565 if (is_dead[e])
2566 omega_delete_geq (pb, e, pb->num_vars);
2568 free (is_dead);
2570 if (dump_file && (dump_flags & TDF_DETAILS))
2572 fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2573 omega_print_problem (dump_file, pb);
2576 for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2577 if (pb->geqs[e].color == omega_red)
2578 red_found = 1;
2580 if (!red_found)
2582 if (dump_file && (dump_flags & TDF_DETAILS))
2583 fprintf (dump_file, "fast checks worked\n");
2585 if (!omega_reduce_with_subs)
2586 gcc_assert (please_no_equalities_in_simplified_problems
2587 || pb->num_subs == 0);
2589 return;
2592 if (!omega_verify_simplification
2593 && verify_omega_pb (pb) == omega_false)
2594 return;
2596 conservative++;
2597 tmp_problem = XNEW (struct omega_pb_d);
2599 for (e = pb->num_geqs - 1; e >= 0; e--)
2600 if (pb->geqs[e].color == omega_red)
2602 if (dump_file && (dump_flags & TDF_DETAILS))
2604 fprintf (dump_file,
2605 "checking equation %d to see if it is redundant: ", e);
2606 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2607 fprintf (dump_file, "\n");
2610 omega_copy_problem (tmp_problem, pb);
2611 omega_negate_geq (tmp_problem, e);
2612 tmp_problem->safe_vars = 0;
2613 tmp_problem->variables_freed = false;
2614 tmp_problem->num_subs = 0;
2616 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2618 if (dump_file && (dump_flags & TDF_DETAILS))
2619 fprintf (dump_file, "it is redundant\n");
2620 omega_delete_geq (pb, e, pb->num_vars);
2622 else
2624 if (dump_file && (dump_flags & TDF_DETAILS))
2625 fprintf (dump_file, "it is not redundant\n");
2627 if (!eliminate_all)
2629 if (dump_file && (dump_flags & TDF_DETAILS))
2630 fprintf (dump_file, "no need to check other red equations\n");
2631 break;
2636 conservative--;
2637 free (tmp_problem);
2638 /* omega_simplify_problem (pb); */
2640 if (!omega_reduce_with_subs)
2641 gcc_assert (please_no_equalities_in_simplified_problems
2642 || pb->num_subs == 0);
2645 /* Transform some wildcard variables to non-safe variables. */
2647 static void
2648 chain_unprotect (omega_pb pb)
2650 int i, e;
2651 bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2653 for (i = 1; omega_safe_var_p (pb, i); i++)
2655 unprotect[i] = omega_wildcard_p (pb, i);
2657 for (e = pb->num_subs - 1; e >= 0; e--)
2658 if (pb->subs[e].coef[i])
2659 unprotect[i] = false;
2662 if (dump_file && (dump_flags & TDF_DETAILS))
2664 fprintf (dump_file, "Doing chain reaction unprotection\n");
2665 omega_print_problem (dump_file, pb);
2667 for (i = 1; omega_safe_var_p (pb, i); i++)
2668 if (unprotect[i])
2669 fprintf (dump_file, "unprotecting %s\n",
2670 omega_variable_to_str (pb, i));
2673 for (i = 1; omega_safe_var_p (pb, i); i++)
2674 if (unprotect[i])
2675 omega_unprotect_1 (pb, &i, unprotect);
2677 if (dump_file && (dump_flags & TDF_DETAILS))
2679 fprintf (dump_file, "After chain reactions\n");
2680 omega_print_problem (dump_file, pb);
2683 free (unprotect);
2686 /* Reduce problem PB. */
2688 static void
2689 omega_problem_reduced (omega_pb pb)
2691 if (omega_verify_simplification
2692 && !in_approximate_mode
2693 && verify_omega_pb (pb) == omega_false)
2694 return;
2696 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2697 && !omega_eliminate_redundant (pb, true))
2698 return;
2700 omega_found_reduction = omega_true;
2702 if (!please_no_equalities_in_simplified_problems)
2703 coalesce (pb);
2705 if (omega_reduce_with_subs
2706 || please_no_equalities_in_simplified_problems)
2707 chain_unprotect (pb);
2708 else
2709 resurrect_subs (pb);
2711 if (!return_single_result)
2713 int i;
2715 for (i = 1; omega_safe_var_p (pb, i); i++)
2716 pb->forwarding_address[pb->var[i]] = i;
2718 for (i = 0; i < pb->num_subs; i++)
2719 pb->forwarding_address[pb->subs[i].key] = -i - 1;
2721 (*omega_when_reduced) (pb);
2724 if (dump_file && (dump_flags & TDF_DETAILS))
2726 fprintf (dump_file, "-------------------------------------------\n");
2727 fprintf (dump_file, "problem reduced:\n");
2728 omega_print_problem (dump_file, pb);
2729 fprintf (dump_file, "-------------------------------------------\n");
2733 /* Eliminates all the free variables for problem PB, that is all the
2734 variables from FV to PB->NUM_VARS. */
2736 static void
2737 omega_free_eliminations (omega_pb pb, int fv)
2739 bool try_again = true;
2740 int i, e, e2;
2741 int n_vars = pb->num_vars;
2743 while (try_again)
2745 try_again = false;
2747 for (i = n_vars; i > fv; i--)
2749 for (e = pb->num_geqs - 1; e >= 0; e--)
2750 if (pb->geqs[e].coef[i])
2751 break;
2753 if (e < 0)
2754 e2 = e;
2755 else if (pb->geqs[e].coef[i] > 0)
2757 for (e2 = e - 1; e2 >= 0; e2--)
2758 if (pb->geqs[e2].coef[i] < 0)
2759 break;
2761 else
2763 for (e2 = e - 1; e2 >= 0; e2--)
2764 if (pb->geqs[e2].coef[i] > 0)
2765 break;
2768 if (e2 < 0)
2770 int e3;
2771 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2772 if (pb->subs[e3].coef[i])
2773 break;
2775 if (e3 >= 0)
2776 continue;
2778 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2779 if (pb->eqs[e3].coef[i])
2780 break;
2782 if (e3 >= 0)
2783 continue;
2785 if (dump_file && (dump_flags & TDF_DETAILS))
2786 fprintf (dump_file, "a free elimination of %s\n",
2787 omega_variable_to_str (pb, i));
2789 if (e >= 0)
2791 omega_delete_geq (pb, e, n_vars);
2793 for (e--; e >= 0; e--)
2794 if (pb->geqs[e].coef[i])
2795 omega_delete_geq (pb, e, n_vars);
2797 try_again = (i < n_vars);
2800 omega_delete_variable (pb, i);
2801 n_vars = pb->num_vars;
2806 if (dump_file && (dump_flags & TDF_DETAILS))
2808 fprintf (dump_file, "\nafter free eliminations:\n");
2809 omega_print_problem (dump_file, pb);
2810 fprintf (dump_file, "\n");
2814 /* Do free red eliminations. */
2816 static void
2817 free_red_eliminations (omega_pb pb)
2819 bool try_again = true;
2820 int i, e, e2;
2821 int n_vars = pb->num_vars;
2822 bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2823 bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2824 bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2826 for (i = n_vars; i > 0; i--)
2828 is_red_var[i] = false;
2829 is_dead_var[i] = false;
2832 for (e = pb->num_geqs - 1; e >= 0; e--)
2834 is_dead_geq[e] = false;
2836 if (pb->geqs[e].color == omega_red)
2837 for (i = n_vars; i > 0; i--)
2838 if (pb->geqs[e].coef[i] != 0)
2839 is_red_var[i] = true;
2842 while (try_again)
2844 try_again = false;
2845 for (i = n_vars; i > 0; i--)
2846 if (!is_red_var[i] && !is_dead_var[i])
2848 for (e = pb->num_geqs - 1; e >= 0; e--)
2849 if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2850 break;
2852 if (e < 0)
2853 e2 = e;
2854 else if (pb->geqs[e].coef[i] > 0)
2856 for (e2 = e - 1; e2 >= 0; e2--)
2857 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2858 break;
2860 else
2862 for (e2 = e - 1; e2 >= 0; e2--)
2863 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2864 break;
2867 if (e2 < 0)
2869 int e3;
2870 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2871 if (pb->subs[e3].coef[i])
2872 break;
2874 if (e3 >= 0)
2875 continue;
2877 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2878 if (pb->eqs[e3].coef[i])
2879 break;
2881 if (e3 >= 0)
2882 continue;
2884 if (dump_file && (dump_flags & TDF_DETAILS))
2885 fprintf (dump_file, "a free red elimination of %s\n",
2886 omega_variable_to_str (pb, i));
2888 for (; e >= 0; e--)
2889 if (pb->geqs[e].coef[i])
2890 is_dead_geq[e] = true;
2892 try_again = true;
2893 is_dead_var[i] = true;
2898 for (e = pb->num_geqs - 1; e >= 0; e--)
2899 if (is_dead_geq[e])
2900 omega_delete_geq (pb, e, n_vars);
2902 for (i = n_vars; i > 0; i--)
2903 if (is_dead_var[i])
2904 omega_delete_variable (pb, i);
2906 if (dump_file && (dump_flags & TDF_DETAILS))
2908 fprintf (dump_file, "\nafter free red eliminations:\n");
2909 omega_print_problem (dump_file, pb);
2910 fprintf (dump_file, "\n");
2913 free (is_red_var);
2914 free (is_dead_var);
2915 free (is_dead_geq);
2918 /* For equation EQ of the form "0 = EQN", insert in PB two
2919 inequalities "0 <= EQN" and "0 <= -EQN". */
2921 void
2922 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2924 int i;
2926 if (dump_file && (dump_flags & TDF_DETAILS))
2927 fprintf (dump_file, "Converting Eq to Geqs\n");
2929 /* Insert "0 <= EQN". */
2930 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2931 pb->geqs[pb->num_geqs].touched = 1;
2932 pb->num_geqs++;
2934 /* Insert "0 <= -EQN". */
2935 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2936 pb->geqs[pb->num_geqs].touched = 1;
2938 for (i = 0; i <= pb->num_vars; i++)
2939 pb->geqs[pb->num_geqs].coef[i] *= -1;
2941 pb->num_geqs++;
2943 if (dump_file && (dump_flags & TDF_DETAILS))
2944 omega_print_problem (dump_file, pb);
2947 /* Eliminates variable I from PB. */
2949 static void
2950 omega_do_elimination (omega_pb pb, int e, int i)
2952 eqn sub = omega_alloc_eqns (0, 1);
2953 int c;
2954 int n_vars = pb->num_vars;
2956 if (dump_file && (dump_flags & TDF_DETAILS))
2957 fprintf (dump_file, "eliminating variable %s\n",
2958 omega_variable_to_str (pb, i));
2960 omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
2961 c = sub->coef[i];
2962 sub->coef[i] = 0;
2963 if (c == 1 || c == -1)
2965 if (pb->eqs[e].color == omega_red)
2967 bool fB;
2968 omega_substitute_red (pb, sub, i, c, &fB);
2969 if (fB)
2970 omega_convert_eq_to_geqs (pb, e);
2971 else
2972 omega_delete_variable (pb, i);
2974 else
2976 omega_substitute (pb, sub, i, c);
2977 omega_delete_variable (pb, i);
2980 else
2982 int a = abs (c);
2983 int e2 = e;
2985 if (dump_file && (dump_flags & TDF_DETAILS))
2986 fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
2988 for (e = pb->num_eqs - 1; e >= 0; e--)
2989 if (pb->eqs[e].coef[i])
2991 eqn eqn = &(pb->eqs[e]);
2992 int j, k;
2993 for (j = n_vars; j >= 0; j--)
2994 eqn->coef[j] *= a;
2995 k = eqn->coef[i];
2996 eqn->coef[i] = 0;
2997 if (sub->color == omega_red)
2998 eqn->color = omega_red;
2999 for (j = n_vars; j >= 0; j--)
3000 eqn->coef[j] -= sub->coef[j] * k / c;
3003 for (e = pb->num_geqs - 1; e >= 0; e--)
3004 if (pb->geqs[e].coef[i])
3006 eqn eqn = &(pb->geqs[e]);
3007 int j, k;
3009 if (sub->color == omega_red)
3010 eqn->color = omega_red;
3012 for (j = n_vars; j >= 0; j--)
3013 eqn->coef[j] *= a;
3015 eqn->touched = 1;
3016 k = eqn->coef[i];
3017 eqn->coef[i] = 0;
3019 for (j = n_vars; j >= 0; j--)
3020 eqn->coef[j] -= sub->coef[j] * k / c;
3024 for (e = pb->num_subs - 1; e >= 0; e--)
3025 if (pb->subs[e].coef[i])
3027 eqn eqn = &(pb->subs[e]);
3028 int j, k;
3029 gcc_assert (0);
3030 gcc_assert (sub->color == omega_black);
3031 for (j = n_vars; j >= 0; j--)
3032 eqn->coef[j] *= a;
3033 k = eqn->coef[i];
3034 eqn->coef[i] = 0;
3035 for (j = n_vars; j >= 0; j--)
3036 eqn->coef[j] -= sub->coef[j] * k / c;
3039 if (in_approximate_mode)
3040 omega_delete_variable (pb, i);
3041 else
3042 omega_convert_eq_to_geqs (pb, e2);
3045 omega_free_eqns (sub, 1);
3048 /* Helper function for printing "sorry, no solution". */
3050 static inline enum omega_result
3051 omega_problem_has_no_solution (void)
3053 if (dump_file && (dump_flags & TDF_DETAILS))
3054 fprintf (dump_file, "\nequations have no solution \n");
3056 return omega_false;
3059 /* Helper function: solve equations in PB one at a time, following the
3060 DESIRED_RES result. */
3062 static enum omega_result
3063 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3065 int i, j, e;
3066 int g, g2;
3067 g = 0;
3070 if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3072 fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3073 desired_res, may_be_red);
3074 omega_print_problem (dump_file, pb);
3075 fprintf (dump_file, "\n");
3078 if (may_be_red)
3080 i = 0;
3081 j = pb->num_eqs - 1;
3083 while (1)
3085 eqn eq;
3087 while (i <= j && pb->eqs[i].color == omega_red)
3088 i++;
3090 while (i <= j && pb->eqs[j].color == omega_black)
3091 j--;
3093 if (i >= j)
3094 break;
3096 eq = omega_alloc_eqns (0, 1);
3097 omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3098 omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3099 omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3100 omega_free_eqns (eq, 1);
3101 i++;
3102 j--;
3106 /* Eliminate all EQ equations */
3107 for (e = pb->num_eqs - 1; e >= 0; e--)
3109 eqn eqn = &(pb->eqs[e]);
3110 int sv;
3112 if (dump_file && (dump_flags & TDF_DETAILS))
3113 fprintf (dump_file, "----\n");
3115 for (i = pb->num_vars; i > 0; i--)
3116 if (eqn->coef[i])
3117 break;
3119 g = eqn->coef[i];
3121 for (j = i - 1; j > 0; j--)
3122 if (eqn->coef[j])
3123 break;
3125 /* i is the position of last nonzero coefficient,
3126 g is the coefficient of i,
3127 j is the position of next nonzero coefficient. */
3129 if (j == 0)
3131 if (eqn->coef[0] % g != 0)
3132 return omega_problem_has_no_solution ();
3134 eqn->coef[0] = eqn->coef[0] / g;
3135 eqn->coef[i] = 1;
3136 pb->num_eqs--;
3137 omega_do_elimination (pb, e, i);
3138 continue;
3141 else if (j == -1)
3143 if (eqn->coef[0] != 0)
3144 return omega_problem_has_no_solution ();
3146 pb->num_eqs--;
3147 continue;
3150 if (g < 0)
3151 g = -g;
3153 if (g == 1)
3155 pb->num_eqs--;
3156 omega_do_elimination (pb, e, i);
3159 else
3161 int k = j;
3162 bool promotion_possible =
3163 (omega_safe_var_p (pb, j)
3164 && pb->safe_vars + 1 == i
3165 && !omega_eqn_is_red (eqn, desired_res)
3166 && !in_approximate_mode);
3168 if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3169 fprintf (dump_file, " Promotion possible\n");
3171 normalizeEQ:
3172 if (!omega_safe_var_p (pb, j))
3174 for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3175 g = gcd (abs (eqn->coef[j]), g);
3176 g2 = g;
3178 else if (!omega_safe_var_p (pb, i))
3179 g2 = g;
3180 else
3181 g2 = 0;
3183 for (; g != 1 && j > 0; j--)
3184 g = gcd (abs (eqn->coef[j]), g);
3186 if (g > 1)
3188 if (eqn->coef[0] % g != 0)
3189 return omega_problem_has_no_solution ();
3191 for (j = 0; j <= pb->num_vars; j++)
3192 eqn->coef[j] /= g;
3194 g2 = g2 / g;
3197 if (g2 > 1)
3199 int e2;
3201 for (e2 = e - 1; e2 >= 0; e2--)
3202 if (pb->eqs[e2].coef[i])
3203 break;
3205 if (e2 == -1)
3206 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3207 if (pb->geqs[e2].coef[i])
3208 break;
3210 if (e2 == -1)
3211 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3212 if (pb->subs[e2].coef[i])
3213 break;
3215 if (e2 == -1)
3217 bool change = false;
3219 if (dump_file && (dump_flags & TDF_DETAILS))
3221 fprintf (dump_file, "Ha! We own it! \n");
3222 omega_print_eq (dump_file, pb, eqn);
3223 fprintf (dump_file, " \n");
3226 g = eqn->coef[i];
3227 g = abs (g);
3229 for (j = i - 1; j >= 0; j--)
3231 int t = int_mod (eqn->coef[j], g);
3233 if (2 * t >= g)
3234 t -= g;
3236 if (t != eqn->coef[j])
3238 eqn->coef[j] = t;
3239 change = true;
3243 if (!change)
3245 if (dump_file && (dump_flags & TDF_DETAILS))
3246 fprintf (dump_file, "So what?\n");
3249 else
3251 omega_name_wild_card (pb, i);
3253 if (dump_file && (dump_flags & TDF_DETAILS))
3255 omega_print_eq (dump_file, pb, eqn);
3256 fprintf (dump_file, " \n");
3259 e++;
3260 continue;
3265 if (promotion_possible)
3267 if (dump_file && (dump_flags & TDF_DETAILS))
3269 fprintf (dump_file, "promoting %s to safety\n",
3270 omega_variable_to_str (pb, i));
3271 omega_print_vars (dump_file, pb);
3274 pb->safe_vars++;
3276 if (!omega_wildcard_p (pb, i))
3277 omega_name_wild_card (pb, i);
3279 promotion_possible = false;
3280 j = k;
3281 goto normalizeEQ;
3284 if (g2 > 1 && !in_approximate_mode)
3286 if (pb->eqs[e].color == omega_red)
3288 if (dump_file && (dump_flags & TDF_DETAILS))
3289 fprintf (dump_file, "handling red equality\n");
3291 pb->num_eqs--;
3292 omega_do_elimination (pb, e, i);
3293 continue;
3296 if (dump_file && (dump_flags & TDF_DETAILS))
3298 fprintf (dump_file,
3299 "adding equation to handle safe variable \n");
3300 omega_print_eq (dump_file, pb, eqn);
3301 fprintf (dump_file, "\n----\n");
3302 omega_print_problem (dump_file, pb);
3303 fprintf (dump_file, "\n----\n");
3304 fprintf (dump_file, "\n----\n");
3307 i = omega_add_new_wild_card (pb);
3308 pb->num_eqs++;
3309 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3310 omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3311 omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3313 for (j = pb->num_vars; j >= 0; j--)
3315 pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3317 if (2 * pb->eqs[e + 1].coef[j] >= g2)
3318 pb->eqs[e + 1].coef[j] -= g2;
3321 pb->eqs[e + 1].coef[i] = g2;
3322 e += 2;
3324 if (dump_file && (dump_flags & TDF_DETAILS))
3325 omega_print_problem (dump_file, pb);
3327 continue;
3330 sv = pb->safe_vars;
3331 if (g2 == 0)
3332 sv = 0;
3334 /* Find variable to eliminate. */
3335 if (g2 > 1)
3337 gcc_assert (in_approximate_mode);
3339 if (dump_file && (dump_flags & TDF_DETAILS))
3341 fprintf (dump_file, "non-exact elimination: ");
3342 omega_print_eq (dump_file, pb, eqn);
3343 fprintf (dump_file, "\n");
3344 omega_print_problem (dump_file, pb);
3347 for (i = pb->num_vars; i > sv; i--)
3348 if (pb->eqs[e].coef[i] != 0)
3349 break;
3351 else
3352 for (i = pb->num_vars; i > sv; i--)
3353 if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3354 break;
3356 if (i > sv)
3358 pb->num_eqs--;
3359 omega_do_elimination (pb, e, i);
3361 if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3363 fprintf (dump_file, "result of non-exact elimination:\n");
3364 omega_print_problem (dump_file, pb);
3367 else
3369 int factor = (INT_MAX);
3370 j = 0;
3372 if (dump_file && (dump_flags & TDF_DETAILS))
3373 fprintf (dump_file, "doing moding\n");
3375 for (i = pb->num_vars; i != sv; i--)
3376 if ((pb->eqs[e].coef[i] & 1) != 0)
3378 j = i;
3379 i--;
3381 for (; i != sv; i--)
3382 if ((pb->eqs[e].coef[i] & 1) != 0)
3383 break;
3385 break;
3388 if (j != 0 && i == sv)
3390 omega_do_mod (pb, 2, e, j);
3391 e++;
3392 continue;
3395 j = 0;
3396 for (i = pb->num_vars; i != sv; i--)
3397 if (pb->eqs[e].coef[i] != 0
3398 && factor > abs (pb->eqs[e].coef[i]) + 1)
3400 factor = abs (pb->eqs[e].coef[i]) + 1;
3401 j = i;
3404 if (j == sv)
3406 if (dump_file && (dump_flags & TDF_DETAILS))
3407 fprintf (dump_file, "should not have happened\n");
3408 gcc_assert (0);
3411 omega_do_mod (pb, factor, e, j);
3412 /* Go back and try this equation again. */
3413 e++;
3418 pb->num_eqs = 0;
3419 return omega_unknown;
3422 /* Transform an inequation E to an equality, then solve DIFF problems
3423 based on PB, and only differing by the constant part that is
3424 diminished by one, trying to figure out which of the constants
3425 satisfies PB. */
3427 static enum omega_result
3428 parallel_splinter (omega_pb pb, int e, int diff,
3429 enum omega_result desired_res)
3431 omega_pb tmp_problem;
3432 int i;
3434 if (dump_file && (dump_flags & TDF_DETAILS))
3436 fprintf (dump_file, "Using parallel splintering\n");
3437 omega_print_problem (dump_file, pb);
3440 tmp_problem = XNEW (struct omega_pb_d);
3441 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3442 pb->num_eqs = 1;
3444 for (i = 0; i <= diff; i++)
3446 omega_copy_problem (tmp_problem, pb);
3448 if (dump_file && (dump_flags & TDF_DETAILS))
3450 fprintf (dump_file, "Splinter # %i\n", i);
3451 omega_print_problem (dump_file, pb);
3454 if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3456 free (tmp_problem);
3457 return omega_true;
3460 pb->eqs[0].coef[0]--;
3463 free (tmp_problem);
3464 return omega_false;
3467 /* Helper function: solve equations one at a time. */
3469 static enum omega_result
3470 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3472 int i, e;
3473 int n_vars, fv;
3474 enum omega_result result;
3475 bool coupled_subscripts = false;
3476 bool smoothed = false;
3477 bool eliminate_again;
3478 bool tried_eliminating_redundant = false;
3480 if (desired_res != omega_simplify)
3482 pb->num_subs = 0;
3483 pb->safe_vars = 0;
3486 solve_geq_start:
3487 do {
3488 gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3490 /* Verify that there are not too many inequalities. */
3491 gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3493 if (dump_file && (dump_flags & TDF_DETAILS))
3495 fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3496 desired_res, please_no_equalities_in_simplified_problems);
3497 omega_print_problem (dump_file, pb);
3498 fprintf (dump_file, "\n");
3501 n_vars = pb->num_vars;
3503 if (n_vars == 1)
3505 enum omega_eqn_color u_color = omega_black;
3506 enum omega_eqn_color l_color = omega_black;
3507 int upper_bound = pos_infinity;
3508 int lower_bound = neg_infinity;
3510 for (e = pb->num_geqs - 1; e >= 0; e--)
3512 int a = pb->geqs[e].coef[1];
3513 int c = pb->geqs[e].coef[0];
3515 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3516 if (a == 0)
3518 if (c < 0)
3519 return omega_problem_has_no_solution ();
3521 else if (a > 0)
3523 if (a != 1)
3524 c = int_div (c, a);
3526 if (lower_bound < -c
3527 || (lower_bound == -c
3528 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3530 lower_bound = -c;
3531 l_color = pb->geqs[e].color;
3534 else
3536 if (a != -1)
3537 c = int_div (c, -a);
3539 if (upper_bound > c
3540 || (upper_bound == c
3541 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3543 upper_bound = c;
3544 u_color = pb->geqs[e].color;
3549 if (dump_file && (dump_flags & TDF_DETAILS))
3551 fprintf (dump_file, "upper bound = %d\n", upper_bound);
3552 fprintf (dump_file, "lower bound = %d\n", lower_bound);
3555 if (lower_bound > upper_bound)
3556 return omega_problem_has_no_solution ();
3558 if (desired_res == omega_simplify)
3560 pb->num_geqs = 0;
3561 if (pb->safe_vars == 1)
3564 if (lower_bound == upper_bound
3565 && u_color == omega_black
3566 && l_color == omega_black)
3568 pb->eqs[0].coef[0] = -lower_bound;
3569 pb->eqs[0].coef[1] = 1;
3570 pb->eqs[0].color = omega_black;
3571 pb->num_eqs = 1;
3572 return omega_solve_problem (pb, desired_res);
3574 else
3576 if (lower_bound > neg_infinity)
3578 pb->geqs[0].coef[0] = -lower_bound;
3579 pb->geqs[0].coef[1] = 1;
3580 pb->geqs[0].key = 1;
3581 pb->geqs[0].color = l_color;
3582 pb->geqs[0].touched = 0;
3583 pb->num_geqs = 1;
3586 if (upper_bound < pos_infinity)
3588 pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3589 pb->geqs[pb->num_geqs].coef[1] = -1;
3590 pb->geqs[pb->num_geqs].key = -1;
3591 pb->geqs[pb->num_geqs].color = u_color;
3592 pb->geqs[pb->num_geqs].touched = 0;
3593 pb->num_geqs++;
3597 else
3598 pb->num_vars = 0;
3600 omega_problem_reduced (pb);
3601 return omega_false;
3604 if (original_problem != no_problem
3605 && l_color == omega_black
3606 && u_color == omega_black
3607 && !conservative
3608 && lower_bound == upper_bound)
3610 pb->eqs[0].coef[0] = -lower_bound;
3611 pb->eqs[0].coef[1] = 1;
3612 pb->num_eqs = 1;
3613 adding_equality_constraint (pb, 0);
3616 return omega_true;
3619 if (!pb->variables_freed)
3621 pb->variables_freed = true;
3623 if (desired_res != omega_simplify)
3624 omega_free_eliminations (pb, 0);
3625 else
3626 omega_free_eliminations (pb, pb->safe_vars);
3628 n_vars = pb->num_vars;
3630 if (n_vars == 1)
3631 continue;
3634 switch (normalize_omega_problem (pb))
3636 case normalize_false:
3637 return omega_false;
3638 break;
3640 case normalize_coupled:
3641 coupled_subscripts = true;
3642 break;
3644 case normalize_uncoupled:
3645 coupled_subscripts = false;
3646 break;
3648 default:
3649 gcc_unreachable ();
3652 n_vars = pb->num_vars;
3654 if (dump_file && (dump_flags & TDF_DETAILS))
3656 fprintf (dump_file, "\nafter normalization:\n");
3657 omega_print_problem (dump_file, pb);
3658 fprintf (dump_file, "\n");
3659 fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3662 do {
3663 int parallel_difference = INT_MAX;
3664 int best_parallel_eqn = -1;
3665 int minC, maxC, minCj = 0;
3666 int lower_bound_count = 0;
3667 int e2, Le = 0, Ue;
3668 bool possible_easy_int_solution;
3669 int max_splinters = 1;
3670 bool exact = false;
3671 bool lucky_exact = false;
3672 int best = (INT_MAX);
3673 int j = 0, jLe = 0, jLowerBoundCount = 0;
3676 eliminate_again = false;
3678 if (pb->num_eqs > 0)
3679 return omega_solve_problem (pb, desired_res);
3681 if (!coupled_subscripts)
3683 if (pb->safe_vars == 0)
3684 pb->num_geqs = 0;
3685 else
3686 for (e = pb->num_geqs - 1; e >= 0; e--)
3687 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3688 omega_delete_geq (pb, e, n_vars);
3690 pb->num_vars = pb->safe_vars;
3692 if (desired_res == omega_simplify)
3694 omega_problem_reduced (pb);
3695 return omega_false;
3698 return omega_true;
3701 if (desired_res != omega_simplify)
3702 fv = 0;
3703 else
3704 fv = pb->safe_vars;
3706 if (pb->num_geqs == 0)
3708 if (desired_res == omega_simplify)
3710 pb->num_vars = pb->safe_vars;
3711 omega_problem_reduced (pb);
3712 return omega_false;
3714 return omega_true;
3717 if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3719 omega_problem_reduced (pb);
3720 return omega_false;
3723 if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3724 || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3726 if (dump_file && (dump_flags & TDF_DETAILS))
3727 fprintf (dump_file,
3728 "TOO MANY EQUATIONS; "
3729 "%d equations, %d variables, "
3730 "ELIMINATING REDUNDANT ONES\n",
3731 pb->num_geqs, n_vars);
3733 if (!omega_eliminate_redundant (pb, false))
3734 return omega_false;
3736 n_vars = pb->num_vars;
3738 if (pb->num_eqs > 0)
3739 return omega_solve_problem (pb, desired_res);
3741 if (dump_file && (dump_flags & TDF_DETAILS))
3742 fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3745 if (desired_res != omega_simplify)
3746 fv = 0;
3747 else
3748 fv = pb->safe_vars;
3750 for (i = n_vars; i != fv; i--)
3752 int score;
3753 int ub = -2;
3754 int lb = -2;
3755 bool lucky = false;
3756 int upper_bound_count = 0;
3758 lower_bound_count = 0;
3759 minC = maxC = 0;
3761 for (e = pb->num_geqs - 1; e >= 0; e--)
3762 if (pb->geqs[e].coef[i] < 0)
3764 minC = MIN (minC, pb->geqs[e].coef[i]);
3765 upper_bound_count++;
3766 if (pb->geqs[e].coef[i] < -1)
3768 if (ub == -2)
3769 ub = e;
3770 else
3771 ub = -1;
3774 else if (pb->geqs[e].coef[i] > 0)
3776 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3777 lower_bound_count++;
3778 Le = e;
3779 if (pb->geqs[e].coef[i] > 1)
3781 if (lb == -2)
3782 lb = e;
3783 else
3784 lb = -1;
3788 if (lower_bound_count == 0
3789 || upper_bound_count == 0)
3791 lower_bound_count = 0;
3792 break;
3795 if (ub >= 0 && lb >= 0
3796 && pb->geqs[lb].key == -pb->geqs[ub].key)
3798 int Lc = pb->geqs[lb].coef[i];
3799 int Uc = -pb->geqs[ub].coef[i];
3800 int diff =
3801 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3802 lucky = (diff >= (Uc - 1) * (Lc - 1));
3805 if (maxC == 1
3806 || minC == -1
3807 || lucky
3808 || in_approximate_mode)
3810 score = upper_bound_count * lower_bound_count;
3812 if (dump_file && (dump_flags & TDF_DETAILS))
3813 fprintf (dump_file,
3814 "For %s, exact, score = %d*%d, range = %d ... %d,"
3815 "\nlucky = %d, in_approximate_mode=%d \n",
3816 omega_variable_to_str (pb, i),
3817 upper_bound_count,
3818 lower_bound_count, minC, maxC, lucky,
3819 in_approximate_mode);
3821 if (!exact
3822 || score < best)
3825 best = score;
3826 j = i;
3827 minCj = minC;
3828 jLe = Le;
3829 jLowerBoundCount = lower_bound_count;
3830 exact = true;
3831 lucky_exact = lucky;
3832 if (score == 1)
3833 break;
3836 else if (!exact)
3838 if (dump_file && (dump_flags & TDF_DETAILS))
3839 fprintf (dump_file,
3840 "For %s, non-exact, score = %d*%d,"
3841 "range = %d ... %d \n",
3842 omega_variable_to_str (pb, i),
3843 upper_bound_count,
3844 lower_bound_count, minC, maxC);
3846 score = maxC - minC;
3848 if (best > score)
3850 best = score;
3851 j = i;
3852 minCj = minC;
3853 jLe = Le;
3854 jLowerBoundCount = lower_bound_count;
3859 if (lower_bound_count == 0)
3861 omega_free_eliminations (pb, pb->safe_vars);
3862 n_vars = pb->num_vars;
3863 eliminate_again = true;
3864 continue;
3867 i = j;
3868 minC = minCj;
3869 Le = jLe;
3870 lower_bound_count = jLowerBoundCount;
3872 for (e = pb->num_geqs - 1; e >= 0; e--)
3873 if (pb->geqs[e].coef[i] > 0)
3875 if (pb->geqs[e].coef[i] == -minC)
3876 max_splinters += -minC - 1;
3877 else
3878 max_splinters +=
3879 pos_mul_hwi ((pb->geqs[e].coef[i] - 1),
3880 (-minC - 1)) / (-minC) + 1;
3883 /* #ifdef Omega3 */
3884 /* Trying to produce exact elimination by finding redundant
3885 constraints. */
3886 if (!exact && !tried_eliminating_redundant)
3888 omega_eliminate_redundant (pb, false);
3889 tried_eliminating_redundant = true;
3890 eliminate_again = true;
3891 continue;
3893 tried_eliminating_redundant = false;
3894 /* #endif */
3896 if (return_single_result && desired_res == omega_simplify && !exact)
3898 omega_problem_reduced (pb);
3899 return omega_true;
3902 /* #ifndef Omega3 */
3903 /* Trying to produce exact elimination by finding redundant
3904 constraints. */
3905 if (!exact && !tried_eliminating_redundant)
3907 omega_eliminate_redundant (pb, false);
3908 tried_eliminating_redundant = true;
3909 continue;
3911 tried_eliminating_redundant = false;
3912 /* #endif */
3914 if (!exact)
3916 int e1, e2;
3918 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3919 if (pb->geqs[e1].color == omega_black)
3920 for (e2 = e1 - 1; e2 >= 0; e2--)
3921 if (pb->geqs[e2].color == omega_black
3922 && pb->geqs[e1].key == -pb->geqs[e2].key
3923 && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3924 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3925 / 2 < parallel_difference))
3927 parallel_difference =
3928 (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3929 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3930 / 2;
3931 best_parallel_eqn = e1;
3934 if (dump_file && (dump_flags & TDF_DETAILS)
3935 && best_parallel_eqn >= 0)
3937 fprintf (dump_file,
3938 "Possible parallel projection, diff = %d, in ",
3939 parallel_difference);
3940 omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3941 fprintf (dump_file, "\n");
3942 omega_print_problem (dump_file, pb);
3946 if (dump_file && (dump_flags & TDF_DETAILS))
3948 fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
3949 omega_variable_to_str (pb, i), i, minC,
3950 lower_bound_count);
3951 omega_print_problem (dump_file, pb);
3953 if (lucky_exact)
3954 fprintf (dump_file, "(a lucky exact elimination)\n");
3956 else if (exact)
3957 fprintf (dump_file, "(an exact elimination)\n");
3959 fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
3962 gcc_assert (max_splinters >= 1);
3964 if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
3965 && parallel_difference <= max_splinters)
3966 return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
3967 desired_res);
3969 smoothed = false;
3971 if (i != n_vars)
3973 int t;
3974 int j = pb->num_vars;
3976 if (dump_file && (dump_flags & TDF_DETAILS))
3978 fprintf (dump_file, "Swapping %d and %d\n", i, j);
3979 omega_print_problem (dump_file, pb);
3982 swap (&pb->var[i], &pb->var[j]);
3984 for (e = pb->num_geqs - 1; e >= 0; e--)
3985 if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
3987 pb->geqs[e].touched = 1;
3988 t = pb->geqs[e].coef[i];
3989 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
3990 pb->geqs[e].coef[j] = t;
3993 for (e = pb->num_subs - 1; e >= 0; e--)
3994 if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
3996 t = pb->subs[e].coef[i];
3997 pb->subs[e].coef[i] = pb->subs[e].coef[j];
3998 pb->subs[e].coef[j] = t;
4001 if (dump_file && (dump_flags & TDF_DETAILS))
4003 fprintf (dump_file, "Swapping complete \n");
4004 omega_print_problem (dump_file, pb);
4005 fprintf (dump_file, "\n");
4008 i = j;
4011 else if (dump_file && (dump_flags & TDF_DETAILS))
4013 fprintf (dump_file, "No swap needed\n");
4014 omega_print_problem (dump_file, pb);
4017 pb->num_vars--;
4018 n_vars = pb->num_vars;
4020 if (exact)
4022 if (n_vars == 1)
4024 int upper_bound = pos_infinity;
4025 int lower_bound = neg_infinity;
4026 enum omega_eqn_color ub_color = omega_black;
4027 enum omega_eqn_color lb_color = omega_black;
4028 int topeqn = pb->num_geqs - 1;
4029 int Lc = pb->geqs[Le].coef[i];
4031 for (Le = topeqn; Le >= 0; Le--)
4032 if ((Lc = pb->geqs[Le].coef[i]) == 0)
4034 if (pb->geqs[Le].coef[1] == 1)
4036 int constantTerm = -pb->geqs[Le].coef[0];
4038 if (constantTerm > lower_bound ||
4039 (constantTerm == lower_bound &&
4040 !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
4042 lower_bound = constantTerm;
4043 lb_color = pb->geqs[Le].color;
4046 if (dump_file && (dump_flags & TDF_DETAILS))
4048 if (pb->geqs[Le].color == omega_black)
4049 fprintf (dump_file, " :::=> %s >= %d\n",
4050 omega_variable_to_str (pb, 1),
4051 constantTerm);
4052 else
4053 fprintf (dump_file,
4054 " :::=> [%s >= %d]\n",
4055 omega_variable_to_str (pb, 1),
4056 constantTerm);
4059 else
4061 int constantTerm = pb->geqs[Le].coef[0];
4062 if (constantTerm < upper_bound ||
4063 (constantTerm == upper_bound
4064 && !omega_eqn_is_red (&pb->geqs[Le],
4065 desired_res)))
4067 upper_bound = constantTerm;
4068 ub_color = pb->geqs[Le].color;
4071 if (dump_file && (dump_flags & TDF_DETAILS))
4073 if (pb->geqs[Le].color == omega_black)
4074 fprintf (dump_file, " :::=> %s <= %d\n",
4075 omega_variable_to_str (pb, 1),
4076 constantTerm);
4077 else
4078 fprintf (dump_file,
4079 " :::=> [%s <= %d]\n",
4080 omega_variable_to_str (pb, 1),
4081 constantTerm);
4085 else if (Lc > 0)
4086 for (Ue = topeqn; Ue >= 0; Ue--)
4087 if (pb->geqs[Ue].coef[i] < 0
4088 && pb->geqs[Le].key != -pb->geqs[Ue].key)
4090 int Uc = -pb->geqs[Ue].coef[i];
4091 int coefficient = pb->geqs[Ue].coef[1] * Lc
4092 + pb->geqs[Le].coef[1] * Uc;
4093 int constantTerm = pb->geqs[Ue].coef[0] * Lc
4094 + pb->geqs[Le].coef[0] * Uc;
4096 if (dump_file && (dump_flags & TDF_DETAILS))
4098 omega_print_geq_extra (dump_file, pb,
4099 &(pb->geqs[Ue]));
4100 fprintf (dump_file, "\n");
4101 omega_print_geq_extra (dump_file, pb,
4102 &(pb->geqs[Le]));
4103 fprintf (dump_file, "\n");
4106 if (coefficient > 0)
4108 constantTerm = -int_div (constantTerm, coefficient);
4110 if (constantTerm > lower_bound
4111 || (constantTerm == lower_bound
4112 && (desired_res != omega_simplify
4113 || (pb->geqs[Ue].color == omega_black
4114 && pb->geqs[Le].color == omega_black))))
4116 lower_bound = constantTerm;
4117 lb_color = (pb->geqs[Ue].color == omega_red
4118 || pb->geqs[Le].color == omega_red)
4119 ? omega_red : omega_black;
4122 if (dump_file && (dump_flags & TDF_DETAILS))
4124 if (pb->geqs[Ue].color == omega_red
4125 || pb->geqs[Le].color == omega_red)
4126 fprintf (dump_file,
4127 " ::=> [%s >= %d]\n",
4128 omega_variable_to_str (pb, 1),
4129 constantTerm);
4130 else
4131 fprintf (dump_file,
4132 " ::=> %s >= %d\n",
4133 omega_variable_to_str (pb, 1),
4134 constantTerm);
4137 else
4139 constantTerm = int_div (constantTerm, -coefficient);
4140 if (constantTerm < upper_bound
4141 || (constantTerm == upper_bound
4142 && pb->geqs[Ue].color == omega_black
4143 && pb->geqs[Le].color == omega_black))
4145 upper_bound = constantTerm;
4146 ub_color = (pb->geqs[Ue].color == omega_red
4147 || pb->geqs[Le].color == omega_red)
4148 ? omega_red : omega_black;
4151 if (dump_file
4152 && (dump_flags & TDF_DETAILS))
4154 if (pb->geqs[Ue].color == omega_red
4155 || pb->geqs[Le].color == omega_red)
4156 fprintf (dump_file,
4157 " ::=> [%s <= %d]\n",
4158 omega_variable_to_str (pb, 1),
4159 constantTerm);
4160 else
4161 fprintf (dump_file,
4162 " ::=> %s <= %d\n",
4163 omega_variable_to_str (pb, 1),
4164 constantTerm);
4169 pb->num_geqs = 0;
4171 if (dump_file && (dump_flags & TDF_DETAILS))
4172 fprintf (dump_file,
4173 " therefore, %c%d <= %c%s%c <= %d%c\n",
4174 lb_color == omega_red ? '[' : ' ', lower_bound,
4175 (lb_color == omega_red && ub_color == omega_black)
4176 ? ']' : ' ',
4177 omega_variable_to_str (pb, 1),
4178 (lb_color == omega_black && ub_color == omega_red)
4179 ? '[' : ' ',
4180 upper_bound, ub_color == omega_red ? ']' : ' ');
4182 if (lower_bound > upper_bound)
4183 return omega_false;
4185 if (pb->safe_vars == 1)
4187 if (upper_bound == lower_bound
4188 && !(ub_color == omega_red || lb_color == omega_red)
4189 && !please_no_equalities_in_simplified_problems)
4191 pb->num_eqs++;
4192 pb->eqs[0].coef[1] = -1;
4193 pb->eqs[0].coef[0] = upper_bound;
4195 if (ub_color == omega_red
4196 || lb_color == omega_red)
4197 pb->eqs[0].color = omega_red;
4199 if (desired_res == omega_simplify
4200 && pb->eqs[0].color == omega_black)
4201 return omega_solve_problem (pb, desired_res);
4204 if (upper_bound != pos_infinity)
4206 pb->geqs[0].coef[1] = -1;
4207 pb->geqs[0].coef[0] = upper_bound;
4208 pb->geqs[0].color = ub_color;
4209 pb->geqs[0].key = -1;
4210 pb->geqs[0].touched = 0;
4211 pb->num_geqs++;
4214 if (lower_bound != neg_infinity)
4216 pb->geqs[pb->num_geqs].coef[1] = 1;
4217 pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
4218 pb->geqs[pb->num_geqs].color = lb_color;
4219 pb->geqs[pb->num_geqs].key = 1;
4220 pb->geqs[pb->num_geqs].touched = 0;
4221 pb->num_geqs++;
4225 if (desired_res == omega_simplify)
4227 omega_problem_reduced (pb);
4228 return omega_false;
4230 else
4232 if (!conservative
4233 && (desired_res != omega_simplify
4234 || (lb_color == omega_black
4235 && ub_color == omega_black))
4236 && original_problem != no_problem
4237 && lower_bound == upper_bound)
4239 for (i = original_problem->num_vars; i >= 0; i--)
4240 if (original_problem->var[i] == pb->var[1])
4241 break;
4243 if (i == 0)
4244 break;
4246 e = original_problem->num_eqs++;
4247 omega_init_eqn_zero (&original_problem->eqs[e],
4248 original_problem->num_vars);
4249 original_problem->eqs[e].coef[i] = -1;
4250 original_problem->eqs[e].coef[0] = upper_bound;
4252 if (dump_file && (dump_flags & TDF_DETAILS))
4254 fprintf (dump_file,
4255 "adding equality %d to outer problem\n", e);
4256 omega_print_problem (dump_file, original_problem);
4259 return omega_true;
4263 eliminate_again = true;
4265 if (lower_bound_count == 1)
4267 eqn lbeqn = omega_alloc_eqns (0, 1);
4268 int Lc = pb->geqs[Le].coef[i];
4270 if (dump_file && (dump_flags & TDF_DETAILS))
4271 fprintf (dump_file, "an inplace elimination\n");
4273 omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
4274 omega_delete_geq_extra (pb, Le, n_vars + 1);
4276 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4277 if (pb->geqs[Ue].coef[i] < 0)
4279 if (lbeqn->key == -pb->geqs[Ue].key)
4280 omega_delete_geq_extra (pb, Ue, n_vars + 1);
4281 else
4283 int k;
4284 int Uc = -pb->geqs[Ue].coef[i];
4285 pb->geqs[Ue].touched = 1;
4286 eliminate_again = false;
4288 if (lbeqn->color == omega_red)
4289 pb->geqs[Ue].color = omega_red;
4291 for (k = 0; k <= n_vars; k++)
4292 pb->geqs[Ue].coef[k] =
4293 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4294 mul_hwi (lbeqn->coef[k], Uc);
4296 if (dump_file && (dump_flags & TDF_DETAILS))
4298 omega_print_geq (dump_file, pb,
4299 &(pb->geqs[Ue]));
4300 fprintf (dump_file, "\n");
4305 omega_free_eqns (lbeqn, 1);
4306 continue;
4308 else
4310 int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
4311 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
4312 int num_dead = 0;
4313 int top_eqn = pb->num_geqs - 1;
4314 lower_bound_count--;
4316 if (dump_file && (dump_flags & TDF_DETAILS))
4317 fprintf (dump_file, "lower bound count = %d\n",
4318 lower_bound_count);
4320 for (Le = top_eqn; Le >= 0; Le--)
4321 if (pb->geqs[Le].coef[i] > 0)
4323 int Lc = pb->geqs[Le].coef[i];
4324 for (Ue = top_eqn; Ue >= 0; Ue--)
4325 if (pb->geqs[Ue].coef[i] < 0)
4327 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4329 int k;
4330 int Uc = -pb->geqs[Ue].coef[i];
4332 if (num_dead == 0)
4333 e2 = pb->num_geqs++;
4334 else
4335 e2 = dead_eqns[--num_dead];
4337 gcc_assert (e2 < OMEGA_MAX_GEQS);
4339 if (dump_file && (dump_flags & TDF_DETAILS))
4341 fprintf (dump_file,
4342 "Le = %d, Ue = %d, gen = %d\n",
4343 Le, Ue, e2);
4344 omega_print_geq_extra (dump_file, pb,
4345 &(pb->geqs[Le]));
4346 fprintf (dump_file, "\n");
4347 omega_print_geq_extra (dump_file, pb,
4348 &(pb->geqs[Ue]));
4349 fprintf (dump_file, "\n");
4352 eliminate_again = false;
4354 for (k = n_vars; k >= 0; k--)
4355 pb->geqs[e2].coef[k] =
4356 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4357 mul_hwi (pb->geqs[Le].coef[k], Uc);
4359 pb->geqs[e2].coef[n_vars + 1] = 0;
4360 pb->geqs[e2].touched = 1;
4362 if (pb->geqs[Ue].color == omega_red
4363 || pb->geqs[Le].color == omega_red)
4364 pb->geqs[e2].color = omega_red;
4365 else
4366 pb->geqs[e2].color = omega_black;
4368 if (dump_file && (dump_flags & TDF_DETAILS))
4370 omega_print_geq (dump_file, pb,
4371 &(pb->geqs[e2]));
4372 fprintf (dump_file, "\n");
4376 if (lower_bound_count == 0)
4378 dead_eqns[num_dead++] = Ue;
4380 if (dump_file && (dump_flags & TDF_DETAILS))
4381 fprintf (dump_file, "Killed %d\n", Ue);
4385 lower_bound_count--;
4386 dead_eqns[num_dead++] = Le;
4388 if (dump_file && (dump_flags & TDF_DETAILS))
4389 fprintf (dump_file, "Killed %d\n", Le);
4392 for (e = pb->num_geqs - 1; e >= 0; e--)
4393 is_dead[e] = false;
4395 while (num_dead > 0)
4396 is_dead[dead_eqns[--num_dead]] = true;
4398 for (e = pb->num_geqs - 1; e >= 0; e--)
4399 if (is_dead[e])
4400 omega_delete_geq_extra (pb, e, n_vars + 1);
4402 free (dead_eqns);
4403 free (is_dead);
4404 continue;
4407 else
4409 omega_pb rS, iS;
4411 rS = omega_alloc_problem (0, 0);
4412 iS = omega_alloc_problem (0, 0);
4413 e2 = 0;
4414 possible_easy_int_solution = true;
4416 for (e = 0; e < pb->num_geqs; e++)
4417 if (pb->geqs[e].coef[i] == 0)
4419 omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
4420 pb->num_vars);
4421 omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
4422 pb->num_vars);
4424 if (dump_file && (dump_flags & TDF_DETAILS))
4426 int t;
4427 fprintf (dump_file, "Copying (%d, %d): ", i,
4428 pb->geqs[e].coef[i]);
4429 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
4430 fprintf (dump_file, "\n");
4431 for (t = 0; t <= n_vars + 1; t++)
4432 fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
4433 fprintf (dump_file, "\n");
4436 e2++;
4437 gcc_assert (e2 < OMEGA_MAX_GEQS);
4440 for (Le = pb->num_geqs - 1; Le >= 0; Le--)
4441 if (pb->geqs[Le].coef[i] > 0)
4442 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4443 if (pb->geqs[Ue].coef[i] < 0)
4445 int k;
4446 int Lc = pb->geqs[Le].coef[i];
4447 int Uc = -pb->geqs[Ue].coef[i];
4449 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4452 rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
4454 if (dump_file && (dump_flags & TDF_DETAILS))
4456 fprintf (dump_file, "---\n");
4457 fprintf (dump_file,
4458 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4459 Le, Lc, Ue, Uc, e2);
4460 omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
4461 fprintf (dump_file, "\n");
4462 omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
4463 fprintf (dump_file, "\n");
4466 if (Uc == Lc)
4468 for (k = n_vars; k >= 0; k--)
4469 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4470 pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
4472 iS->geqs[e2].coef[0] -= (Uc - 1);
4474 else
4476 for (k = n_vars; k >= 0; k--)
4477 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4478 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4479 mul_hwi (pb->geqs[Le].coef[k], Uc);
4481 iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
4484 if (pb->geqs[Ue].color == omega_red
4485 || pb->geqs[Le].color == omega_red)
4486 iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
4487 else
4488 iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
4490 if (dump_file && (dump_flags & TDF_DETAILS))
4492 omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
4493 fprintf (dump_file, "\n");
4496 e2++;
4497 gcc_assert (e2 < OMEGA_MAX_GEQS);
4499 else if (pb->geqs[Ue].coef[0] * Lc +
4500 pb->geqs[Le].coef[0] * Uc -
4501 (Uc - 1) * (Lc - 1) < 0)
4502 possible_easy_int_solution = false;
4505 iS->variables_initialized = rS->variables_initialized = true;
4506 iS->num_vars = rS->num_vars = pb->num_vars;
4507 iS->num_geqs = rS->num_geqs = e2;
4508 iS->num_eqs = rS->num_eqs = 0;
4509 iS->num_subs = rS->num_subs = pb->num_subs;
4510 iS->safe_vars = rS->safe_vars = pb->safe_vars;
4512 for (e = n_vars; e >= 0; e--)
4513 rS->var[e] = pb->var[e];
4515 for (e = n_vars; e >= 0; e--)
4516 iS->var[e] = pb->var[e];
4518 for (e = pb->num_subs - 1; e >= 0; e--)
4520 omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
4521 omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
4524 pb->num_vars++;
4525 n_vars = pb->num_vars;
4527 if (desired_res != omega_true)
4529 if (original_problem == no_problem)
4531 original_problem = pb;
4532 result = omega_solve_geq (rS, omega_false);
4533 original_problem = no_problem;
4535 else
4536 result = omega_solve_geq (rS, omega_false);
4538 if (result == omega_false)
4540 free (rS);
4541 free (iS);
4542 return result;
4545 if (pb->num_eqs > 0)
4547 /* An equality constraint must have been found */
4548 free (rS);
4549 free (iS);
4550 return omega_solve_problem (pb, desired_res);
4554 if (desired_res != omega_false)
4556 int j;
4557 int lower_bounds = 0;
4558 int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
4560 if (possible_easy_int_solution)
4562 conservative++;
4563 result = omega_solve_geq (iS, desired_res);
4564 conservative--;
4566 if (result != omega_false)
4568 free (rS);
4569 free (iS);
4570 free (lower_bound);
4571 return result;
4575 if (!exact && best_parallel_eqn >= 0
4576 && parallel_difference <= max_splinters)
4578 free (rS);
4579 free (iS);
4580 free (lower_bound);
4581 return parallel_splinter (pb, best_parallel_eqn,
4582 parallel_difference,
4583 desired_res);
4586 if (dump_file && (dump_flags & TDF_DETAILS))
4587 fprintf (dump_file, "have to do exact analysis\n");
4589 conservative++;
4591 for (e = 0; e < pb->num_geqs; e++)
4592 if (pb->geqs[e].coef[i] > 1)
4593 lower_bound[lower_bounds++] = e;
4595 /* Sort array LOWER_BOUND. */
4596 for (j = 0; j < lower_bounds; j++)
4598 int k, smallest = j;
4600 for (k = j + 1; k < lower_bounds; k++)
4601 if (pb->geqs[lower_bound[smallest]].coef[i] >
4602 pb->geqs[lower_bound[k]].coef[i])
4603 smallest = k;
4605 k = lower_bound[smallest];
4606 lower_bound[smallest] = lower_bound[j];
4607 lower_bound[j] = k;
4610 if (dump_file && (dump_flags & TDF_DETAILS))
4612 fprintf (dump_file, "lower bound coefficients = ");
4614 for (j = 0; j < lower_bounds; j++)
4615 fprintf (dump_file, " %d",
4616 pb->geqs[lower_bound[j]].coef[i]);
4618 fprintf (dump_file, "\n");
4621 for (j = 0; j < lower_bounds; j++)
4623 int max_incr;
4624 int c;
4625 int worst_lower_bound_constant = -minC;
4627 e = lower_bound[j];
4628 max_incr = (((pb->geqs[e].coef[i] - 1) *
4629 (worst_lower_bound_constant - 1) - 1)
4630 / worst_lower_bound_constant);
4631 /* max_incr += 2; */
4633 if (dump_file && (dump_flags & TDF_DETAILS))
4635 fprintf (dump_file, "for equation ");
4636 omega_print_geq (dump_file, pb, &pb->geqs[e]);
4637 fprintf (dump_file,
4638 "\ntry decrements from 0 to %d\n",
4639 max_incr);
4640 omega_print_problem (dump_file, pb);
4643 if (max_incr > 50 && !smoothed
4644 && smooth_weird_equations (pb))
4646 conservative--;
4647 free (rS);
4648 free (iS);
4649 smoothed = true;
4650 goto solve_geq_start;
4653 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4654 pb->num_vars);
4655 pb->eqs[0].color = omega_black;
4656 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4657 pb->geqs[e].touched = 1;
4658 pb->num_eqs = 1;
4660 for (c = max_incr; c >= 0; c--)
4662 if (dump_file && (dump_flags & TDF_DETAILS))
4664 fprintf (dump_file,
4665 "trying next decrement of %d\n",
4666 max_incr - c);
4667 omega_print_problem (dump_file, pb);
4670 omega_copy_problem (rS, pb);
4672 if (dump_file && (dump_flags & TDF_DETAILS))
4673 omega_print_problem (dump_file, rS);
4675 result = omega_solve_problem (rS, desired_res);
4677 if (result == omega_true)
4679 free (rS);
4680 free (iS);
4681 free (lower_bound);
4682 conservative--;
4683 return omega_true;
4686 pb->eqs[0].coef[0]--;
4689 if (j + 1 < lower_bounds)
4691 pb->num_eqs = 0;
4692 omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4693 pb->num_vars);
4694 pb->geqs[e].touched = 1;
4695 pb->geqs[e].color = omega_black;
4696 omega_copy_problem (rS, pb);
4698 if (dump_file && (dump_flags & TDF_DETAILS))
4699 fprintf (dump_file,
4700 "exhausted lower bound, "
4701 "checking if still feasible ");
4703 result = omega_solve_problem (rS, omega_false);
4705 if (result == omega_false)
4706 break;
4710 if (dump_file && (dump_flags & TDF_DETAILS))
4711 fprintf (dump_file, "fall-off the end\n");
4713 free (rS);
4714 free (iS);
4715 free (lower_bound);
4716 conservative--;
4717 return omega_false;
4720 free (rS);
4721 free (iS);
4723 return omega_unknown;
4724 } while (eliminate_again);
4725 } while (1);
4728 /* Because the omega solver is recursive, this counter limits the
4729 recursion depth. */
4730 static int omega_solve_depth = 0;
4732 /* Return omega_true when the problem PB has a solution following the
4733 DESIRED_RES. */
4735 enum omega_result
4736 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4738 enum omega_result result;
4740 gcc_assert (pb->num_vars >= pb->safe_vars);
4741 omega_solve_depth++;
4743 if (desired_res != omega_simplify)
4744 pb->safe_vars = 0;
4746 if (omega_solve_depth > 50)
4748 if (dump_file && (dump_flags & TDF_DETAILS))
4750 fprintf (dump_file,
4751 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4752 omega_solve_depth, in_approximate_mode);
4753 omega_print_problem (dump_file, pb);
4755 gcc_assert (0);
4758 if (omega_solve_eq (pb, desired_res) == omega_false)
4760 omega_solve_depth--;
4761 return omega_false;
4764 if (in_approximate_mode && !pb->num_geqs)
4766 result = omega_true;
4767 pb->num_vars = pb->safe_vars;
4768 omega_problem_reduced (pb);
4770 else
4771 result = omega_solve_geq (pb, desired_res);
4773 omega_solve_depth--;
4775 if (!omega_reduce_with_subs)
4777 resurrect_subs (pb);
4778 gcc_assert (please_no_equalities_in_simplified_problems
4779 || !result || pb->num_subs == 0);
4782 return result;
4785 /* Return true if red equations constrain the set of possible solutions.
4786 We assume that there are solutions to the black equations by
4787 themselves, so if there is no solution to the combined problem, we
4788 return true. */
4790 bool
4791 omega_problem_has_red_equations (omega_pb pb)
4793 bool result;
4794 int e;
4795 int i;
4797 if (dump_file && (dump_flags & TDF_DETAILS))
4799 fprintf (dump_file, "Checking for red equations:\n");
4800 omega_print_problem (dump_file, pb);
4803 please_no_equalities_in_simplified_problems++;
4804 may_be_red++;
4806 if (omega_single_result)
4807 return_single_result++;
4809 create_color = true;
4810 result = (omega_simplify_problem (pb) == omega_false);
4812 if (omega_single_result)
4813 return_single_result--;
4815 may_be_red--;
4816 please_no_equalities_in_simplified_problems--;
4818 if (result)
4820 if (dump_file && (dump_flags & TDF_DETAILS))
4821 fprintf (dump_file, "Gist is FALSE\n");
4823 pb->num_subs = 0;
4824 pb->num_geqs = 0;
4825 pb->num_eqs = 1;
4826 pb->eqs[0].color = omega_red;
4828 for (i = pb->num_vars; i > 0; i--)
4829 pb->eqs[0].coef[i] = 0;
4831 pb->eqs[0].coef[0] = 1;
4832 return true;
4835 free_red_eliminations (pb);
4836 gcc_assert (pb->num_eqs == 0);
4838 for (e = pb->num_geqs - 1; e >= 0; e--)
4839 if (pb->geqs[e].color == omega_red)
4840 result = true;
4842 if (!result)
4843 return false;
4845 for (i = pb->safe_vars; i >= 1; i--)
4847 int ub = 0;
4848 int lb = 0;
4850 for (e = pb->num_geqs - 1; e >= 0; e--)
4852 if (pb->geqs[e].coef[i])
4854 if (pb->geqs[e].coef[i] > 0)
4855 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4857 else
4858 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4862 if (ub == 2 || lb == 2)
4865 if (dump_file && (dump_flags & TDF_DETAILS))
4866 fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4868 if (!omega_reduce_with_subs)
4870 resurrect_subs (pb);
4871 gcc_assert (pb->num_subs == 0);
4874 return true;
4879 if (dump_file && (dump_flags & TDF_DETAILS))
4880 fprintf (dump_file,
4881 "*** Doing potentially expensive elimination tests "
4882 "for red equations\n");
4884 please_no_equalities_in_simplified_problems++;
4885 omega_eliminate_red (pb, true);
4886 please_no_equalities_in_simplified_problems--;
4888 result = false;
4889 gcc_assert (pb->num_eqs == 0);
4891 for (e = pb->num_geqs - 1; e >= 0; e--)
4892 if (pb->geqs[e].color == omega_red)
4893 result = true;
4895 if (dump_file && (dump_flags & TDF_DETAILS))
4897 if (!result)
4898 fprintf (dump_file,
4899 "******************** Redundant Red Equations eliminated!!\n");
4900 else
4901 fprintf (dump_file,
4902 "******************** Red Equations remain\n");
4904 omega_print_problem (dump_file, pb);
4907 if (!omega_reduce_with_subs)
4909 normalize_return_type r;
4911 resurrect_subs (pb);
4912 r = normalize_omega_problem (pb);
4913 gcc_assert (r != normalize_false);
4915 coalesce (pb);
4916 cleanout_wildcards (pb);
4917 gcc_assert (pb->num_subs == 0);
4920 return result;
4923 /* Calls omega_simplify_problem in approximate mode. */
4925 enum omega_result
4926 omega_simplify_approximate (omega_pb pb)
4928 enum omega_result result;
4930 if (dump_file && (dump_flags & TDF_DETAILS))
4931 fprintf (dump_file, "(Entering approximate mode\n");
4933 in_approximate_mode = true;
4934 result = omega_simplify_problem (pb);
4935 in_approximate_mode = false;
4937 gcc_assert (pb->num_vars == pb->safe_vars);
4938 if (!omega_reduce_with_subs)
4939 gcc_assert (pb->num_subs == 0);
4941 if (dump_file && (dump_flags & TDF_DETAILS))
4942 fprintf (dump_file, "Leaving approximate mode)\n");
4944 return result;
4948 /* Simplifies problem PB by eliminating redundant constraints and
4949 reducing the constraints system to a minimal form. Returns
4950 omega_true when the problem was successfully reduced, omega_unknown
4951 when the solver is unable to determine an answer. */
4953 enum omega_result
4954 omega_simplify_problem (omega_pb pb)
4956 int i;
4958 omega_found_reduction = omega_false;
4960 if (!pb->variables_initialized)
4961 omega_initialize_variables (pb);
4963 if (next_key * 3 > MAX_KEYS)
4965 int e;
4967 hash_version++;
4968 next_key = OMEGA_MAX_VARS + 1;
4970 for (e = pb->num_geqs - 1; e >= 0; e--)
4971 pb->geqs[e].touched = 1;
4973 for (i = 0; i < HASH_TABLE_SIZE; i++)
4974 hash_master[i].touched = -1;
4976 pb->hash_version = hash_version;
4979 else if (pb->hash_version != hash_version)
4981 int e;
4983 for (e = pb->num_geqs - 1; e >= 0; e--)
4984 pb->geqs[e].touched = 1;
4986 pb->hash_version = hash_version;
4989 if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
4990 omega_free_eliminations (pb, pb->safe_vars);
4992 if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
4994 omega_found_reduction = omega_solve_problem (pb, omega_unknown);
4996 if (omega_found_reduction != omega_false
4997 && !return_single_result)
4999 pb->num_geqs = 0;
5000 pb->num_eqs = 0;
5001 (*omega_when_reduced) (pb);
5004 return omega_found_reduction;
5007 omega_solve_problem (pb, omega_simplify);
5009 if (omega_found_reduction != omega_false)
5011 for (i = 1; omega_safe_var_p (pb, i); i++)
5012 pb->forwarding_address[pb->var[i]] = i;
5014 for (i = 0; i < pb->num_subs; i++)
5015 pb->forwarding_address[pb->subs[i].key] = -i - 1;
5018 if (!omega_reduce_with_subs)
5019 gcc_assert (please_no_equalities_in_simplified_problems
5020 || omega_found_reduction == omega_false
5021 || pb->num_subs == 0);
5023 return omega_found_reduction;
5026 /* Make variable VAR unprotected: it then can be eliminated. */
5028 void
5029 omega_unprotect_variable (omega_pb pb, int var)
5031 int e, idx;
5032 idx = pb->forwarding_address[var];
5034 if (idx < 0)
5036 idx = -1 - idx;
5037 pb->num_subs--;
5039 if (idx < pb->num_subs)
5041 omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5042 pb->num_vars);
5043 pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5046 else
5048 int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5049 int e2;
5051 for (e = pb->num_subs - 1; e >= 0; e--)
5052 bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5054 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5055 if (bring_to_life[e2])
5057 pb->num_vars++;
5058 pb->safe_vars++;
5060 if (pb->safe_vars < pb->num_vars)
5062 for (e = pb->num_geqs - 1; e >= 0; e--)
5064 pb->geqs[e].coef[pb->num_vars] =
5065 pb->geqs[e].coef[pb->safe_vars];
5067 pb->geqs[e].coef[pb->safe_vars] = 0;
5070 for (e = pb->num_eqs - 1; e >= 0; e--)
5072 pb->eqs[e].coef[pb->num_vars] =
5073 pb->eqs[e].coef[pb->safe_vars];
5075 pb->eqs[e].coef[pb->safe_vars] = 0;
5078 for (e = pb->num_subs - 1; e >= 0; e--)
5080 pb->subs[e].coef[pb->num_vars] =
5081 pb->subs[e].coef[pb->safe_vars];
5083 pb->subs[e].coef[pb->safe_vars] = 0;
5086 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5087 pb->forwarding_address[pb->var[pb->num_vars]] =
5088 pb->num_vars;
5090 else
5092 for (e = pb->num_geqs - 1; e >= 0; e--)
5093 pb->geqs[e].coef[pb->safe_vars] = 0;
5095 for (e = pb->num_eqs - 1; e >= 0; e--)
5096 pb->eqs[e].coef[pb->safe_vars] = 0;
5098 for (e = pb->num_subs - 1; e >= 0; e--)
5099 pb->subs[e].coef[pb->safe_vars] = 0;
5102 pb->var[pb->safe_vars] = pb->subs[e2].key;
5103 pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5105 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5106 pb->num_vars);
5107 pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5108 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5110 if (e2 < pb->num_subs - 1)
5111 omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5112 pb->num_vars);
5114 pb->num_subs--;
5117 omega_unprotect_1 (pb, &idx, NULL);
5118 free (bring_to_life);
5121 chain_unprotect (pb);
5124 /* Unprotects VAR and simplifies PB. */
5126 enum omega_result
5127 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5128 int var, int sign)
5130 int n_vars = pb->num_vars;
5131 int e, j;
5132 int k = pb->forwarding_address[var];
5134 if (k < 0)
5136 k = -1 - k;
5138 if (sign != 0)
5140 e = pb->num_geqs++;
5141 omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5143 for (j = 0; j <= n_vars; j++)
5144 pb->geqs[e].coef[j] *= sign;
5146 pb->geqs[e].coef[0]--;
5147 pb->geqs[e].touched = 1;
5148 pb->geqs[e].color = color;
5150 else
5152 e = pb->num_eqs++;
5153 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5154 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5155 pb->eqs[e].color = color;
5158 else if (sign != 0)
5160 e = pb->num_geqs++;
5161 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5162 pb->geqs[e].coef[k] = sign;
5163 pb->geqs[e].coef[0] = -1;
5164 pb->geqs[e].touched = 1;
5165 pb->geqs[e].color = color;
5167 else
5169 e = pb->num_eqs++;
5170 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5171 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5172 pb->eqs[e].coef[k] = 1;
5173 pb->eqs[e].color = color;
5176 omega_unprotect_variable (pb, var);
5177 return omega_simplify_problem (pb);
5180 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5182 void
5183 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5184 int var, int value)
5186 int e;
5187 int k = pb->forwarding_address[var];
5189 if (k < 0)
5191 k = -1 - k;
5192 e = pb->num_eqs++;
5193 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5194 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5195 pb->eqs[e].coef[0] -= value;
5197 else
5199 e = pb->num_eqs++;
5200 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5201 pb->eqs[e].coef[k] = 1;
5202 pb->eqs[e].coef[0] = -value;
5205 pb->eqs[e].color = color;
5208 /* Return false when the upper and lower bounds are not coupled.
5209 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5210 variable I. */
5212 bool
5213 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5215 int n_vars = pb->num_vars;
5216 int e, j;
5217 bool is_simple;
5218 bool coupled = false;
5220 *lower_bound = neg_infinity;
5221 *upper_bound = pos_infinity;
5222 i = pb->forwarding_address[i];
5224 if (i < 0)
5226 i = -i - 1;
5228 for (j = 1; j <= n_vars; j++)
5229 if (pb->subs[i].coef[j] != 0)
5230 return true;
5232 *upper_bound = *lower_bound = pb->subs[i].coef[0];
5233 return false;
5236 for (e = pb->num_subs - 1; e >= 0; e--)
5237 if (pb->subs[e].coef[i] != 0)
5238 coupled = true;
5240 for (e = pb->num_eqs - 1; e >= 0; e--)
5241 if (pb->eqs[e].coef[i] != 0)
5243 is_simple = true;
5245 for (j = 1; j <= n_vars; j++)
5246 if (i != j && pb->eqs[e].coef[j] != 0)
5248 is_simple = false;
5249 coupled = true;
5250 break;
5253 if (!is_simple)
5254 continue;
5255 else
5257 *lower_bound = *upper_bound =
5258 -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5259 return false;
5263 for (e = pb->num_geqs - 1; e >= 0; e--)
5264 if (pb->geqs[e].coef[i] != 0)
5266 if (pb->geqs[e].key == i)
5267 *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5269 else if (pb->geqs[e].key == -i)
5270 *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5272 else
5273 coupled = true;
5276 return coupled;
5279 /* Sets the lower bound L and upper bound U for the values of variable
5280 I, and sets COULD_BE_ZERO to true if variable I might take value
5281 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5282 variable I. */
5284 static void
5285 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5286 bool *could_be_zero, int lower_bound, int upper_bound)
5288 int e, b1, b2;
5289 eqn eqn;
5290 int sign;
5291 int v;
5293 /* Preconditions. */
5294 gcc_assert (abs (pb->forwarding_address[i]) == 1
5295 && pb->num_vars + pb->num_subs == 2
5296 && pb->num_eqs + pb->num_subs == 1);
5298 /* Define variable I in terms of variable V. */
5299 if (pb->forwarding_address[i] == -1)
5301 eqn = &pb->subs[0];
5302 sign = 1;
5303 v = 1;
5305 else
5307 eqn = &pb->eqs[0];
5308 sign = -eqn->coef[1];
5309 v = 2;
5312 for (e = pb->num_geqs - 1; e >= 0; e--)
5313 if (pb->geqs[e].coef[v] != 0)
5315 if (pb->geqs[e].coef[v] == 1)
5316 lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5318 else
5319 upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5322 if (lower_bound > upper_bound)
5324 *l = pos_infinity;
5325 *u = neg_infinity;
5326 *could_be_zero = 0;
5327 return;
5330 if (lower_bound == neg_infinity)
5332 if (eqn->coef[v] > 0)
5333 b1 = sign * neg_infinity;
5335 else
5336 b1 = -sign * neg_infinity;
5338 else
5339 b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5341 if (upper_bound == pos_infinity)
5343 if (eqn->coef[v] > 0)
5344 b2 = sign * pos_infinity;
5346 else
5347 b2 = -sign * pos_infinity;
5349 else
5350 b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5352 *l = MAX (*l, b1 <= b2 ? b1 : b2);
5353 *u = MIN (*u, b1 <= b2 ? b2 : b1);
5355 *could_be_zero = (*l <= 0 && 0 <= *u
5356 && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5359 /* Return false when a lower bound L and an upper bound U for variable
5360 I in problem PB have been initialized. */
5362 bool
5363 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5365 *l = neg_infinity;
5366 *u = pos_infinity;
5368 if (!omega_query_variable (pb, i, l, u)
5369 || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5370 return false;
5372 if (abs (pb->forwarding_address[i]) == 1
5373 && pb->num_vars + pb->num_subs == 2
5374 && pb->num_eqs + pb->num_subs == 1)
5376 bool could_be_zero;
5377 query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5378 pos_infinity);
5379 return false;
5382 return true;
5385 /* For problem PB, return an integer that represents the classic data
5386 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5387 masks that are added to the result. When DIST_KNOWN is true, DIST
5388 is set to the classic data dependence distance. LOWER_BOUND and
5389 UPPER_BOUND are bounds on the value of variable I, for example, it
5390 is possible to narrow the iteration domain with safe approximations
5391 of loop counts, and thus discard some data dependences that cannot
5392 occur. */
5395 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5396 int dd_eq, int dd_gt, int lower_bound,
5397 int upper_bound, bool *dist_known, int *dist)
5399 int result;
5400 int l, u;
5401 bool could_be_zero;
5403 l = neg_infinity;
5404 u = pos_infinity;
5406 omega_query_variable (pb, i, &l, &u);
5407 query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5408 upper_bound);
5409 result = 0;
5411 if (l < 0)
5412 result |= dd_gt;
5414 if (u > 0)
5415 result |= dd_lt;
5417 if (could_be_zero)
5418 result |= dd_eq;
5420 if (l == u)
5422 *dist_known = true;
5423 *dist = l;
5425 else
5426 *dist_known = false;
5428 return result;
5431 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5432 safe variables. Safe variables are not eliminated during the
5433 Fourier-Motzkin elimination. Safe variables are all those
5434 variables that are placed at the beginning of the array of
5435 variables: P->var[0, ..., NPROT - 1]. */
5437 omega_pb
5438 omega_alloc_problem (int nvars, int nprot)
5440 omega_pb pb;
5442 gcc_assert (nvars <= OMEGA_MAX_VARS);
5443 omega_initialize ();
5445 /* Allocate and initialize PB. */
5446 pb = XCNEW (struct omega_pb_d);
5447 pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5448 pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5449 pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5450 pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5451 pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5453 pb->hash_version = hash_version;
5454 pb->num_vars = nvars;
5455 pb->safe_vars = nprot;
5456 pb->variables_initialized = false;
5457 pb->variables_freed = false;
5458 pb->num_eqs = 0;
5459 pb->num_geqs = 0;
5460 pb->num_subs = 0;
5461 return pb;
5464 /* Keeps the state of the initialization. */
5465 static bool omega_initialized = false;
5467 /* Initialization of the Omega solver. */
5469 void
5470 omega_initialize (void)
5472 int i;
5474 if (omega_initialized)
5475 return;
5477 next_wild_card = 0;
5478 next_key = OMEGA_MAX_VARS + 1;
5479 packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5480 fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5481 fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5482 hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5484 for (i = 0; i < HASH_TABLE_SIZE; i++)
5485 hash_master[i].touched = -1;
5487 sprintf (wild_name[0], "1");
5488 sprintf (wild_name[1], "a");
5489 sprintf (wild_name[2], "b");
5490 sprintf (wild_name[3], "c");
5491 sprintf (wild_name[4], "d");
5492 sprintf (wild_name[5], "e");
5493 sprintf (wild_name[6], "f");
5494 sprintf (wild_name[7], "g");
5495 sprintf (wild_name[8], "h");
5496 sprintf (wild_name[9], "i");
5497 sprintf (wild_name[10], "j");
5498 sprintf (wild_name[11], "k");
5499 sprintf (wild_name[12], "l");
5500 sprintf (wild_name[13], "m");
5501 sprintf (wild_name[14], "n");
5502 sprintf (wild_name[15], "o");
5503 sprintf (wild_name[16], "p");
5504 sprintf (wild_name[17], "q");
5505 sprintf (wild_name[18], "r");
5506 sprintf (wild_name[19], "s");
5507 sprintf (wild_name[20], "t");
5508 sprintf (wild_name[40 - 1], "alpha");
5509 sprintf (wild_name[40 - 2], "beta");
5510 sprintf (wild_name[40 - 3], "gamma");
5511 sprintf (wild_name[40 - 4], "delta");
5512 sprintf (wild_name[40 - 5], "tau");
5513 sprintf (wild_name[40 - 6], "sigma");
5514 sprintf (wild_name[40 - 7], "chi");
5515 sprintf (wild_name[40 - 8], "omega");
5516 sprintf (wild_name[40 - 9], "pi");
5517 sprintf (wild_name[40 - 10], "ni");
5518 sprintf (wild_name[40 - 11], "Alpha");
5519 sprintf (wild_name[40 - 12], "Beta");
5520 sprintf (wild_name[40 - 13], "Gamma");
5521 sprintf (wild_name[40 - 14], "Delta");
5522 sprintf (wild_name[40 - 15], "Tau");
5523 sprintf (wild_name[40 - 16], "Sigma");
5524 sprintf (wild_name[40 - 17], "Chi");
5525 sprintf (wild_name[40 - 18], "Omega");
5526 sprintf (wild_name[40 - 19], "xxx");
5528 omega_initialized = true;