don't compare ARG_FRAME_POINTER_REGNUM and FRAME_POINTER_REGNUM with the preprocessor
[official-gcc.git] / gcc / omega.c
blob436d9f7178b974085f6223156677d6a3d5c80fcf
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-2015 Free Software Foundation, Inc.
9 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
11 This file is part of GCC.
13 GCC is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free
15 Software Foundation; either version 3, or (at your option) any later
16 version.
18 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
19 WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
23 You should have received a copy of the GNU General Public License
24 along with GCC; see the file COPYING3. If not see
25 <http://www.gnu.org/licenses/>. */
27 /* For a detailed description, see "Constraint-Based Array Dependence
28 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
29 Wonnacott's thesis:
30 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
33 #include "config.h"
34 #include "system.h"
35 #include "coretypes.h"
36 #include "hash-set.h"
37 #include "machmode.h"
38 #include "vec.h"
39 #include "double-int.h"
40 #include "input.h"
41 #include "alias.h"
42 #include "symtab.h"
43 #include "options.h"
44 #include "wide-int.h"
45 #include "inchash.h"
46 #include "tree.h"
47 #include "diagnostic-core.h"
48 #include "dumpfile.h"
49 #include "omega.h"
51 /* When set to true, keep substitution variables. When set to false,
52 resurrect substitution variables (convert substitutions back to EQs). */
53 static bool omega_reduce_with_subs = true;
55 /* When set to true, omega_simplify_problem checks for problem with no
56 solutions, calling verify_omega_pb. */
57 static bool omega_verify_simplification = false;
59 /* When set to true, only produce a single simplified result. */
60 static bool omega_single_result = false;
62 /* Set return_single_result to 1 when omega_single_result is true. */
63 static int return_single_result = 0;
65 /* Hash table for equations generated by the solver. */
66 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
67 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
68 static eqn hash_master;
69 static int next_key;
70 static int hash_version = 0;
72 /* Set to true for making the solver enter in approximation mode. */
73 static bool in_approximate_mode = false;
75 /* When set to zero, the solver is allowed to add new equalities to
76 the problem to be solved. */
77 static int conservative = 0;
79 /* Set to omega_true when the problem was successfully reduced, set to
80 omega_unknown when the solver is unable to determine an answer. */
81 static enum omega_result omega_found_reduction;
83 /* Set to true when the solver is allowed to add omega_red equations. */
84 static bool create_color = false;
86 /* Set to nonzero when the problem to be solved can be reduced. */
87 static int may_be_red = 0;
89 /* When false, there should be no substitution equations in the
90 simplified problem. */
91 static int please_no_equalities_in_simplified_problems = 0;
93 /* Variables names for pretty printing. */
94 static char wild_name[200][40];
96 /* Pointer to the void problem. */
97 static omega_pb no_problem = (omega_pb) 0;
99 /* Pointer to the problem to be solved. */
100 static omega_pb original_problem = (omega_pb) 0;
103 /* Return the integer A divided by B. */
105 static inline int
106 int_div (int a, int b)
108 if (a > 0)
109 return a/b;
110 else
111 return -((-a + b - 1)/b);
114 /* Return the integer A modulo B. */
116 static inline int
117 int_mod (int a, int b)
119 return a - b * int_div (a, b);
122 /* Test whether equation E is red. */
124 static inline bool
125 omega_eqn_is_red (eqn e, int desired_res)
127 return (desired_res == omega_simplify && e->color == omega_red);
130 /* Return a string for VARIABLE. */
132 static inline char *
133 omega_var_to_str (int variable)
135 if (0 <= variable && variable <= 20)
136 return wild_name[variable];
138 if (-20 < variable && variable < 0)
139 return wild_name[40 + variable];
141 /* Collapse all the entries that would have overflowed. */
142 return wild_name[21];
145 /* Return a string for variable I in problem PB. */
147 static inline char *
148 omega_variable_to_str (omega_pb pb, int i)
150 return omega_var_to_str (pb->var[i]);
153 /* Do nothing function: used for default initializations. */
155 void
156 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
160 void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
162 /* Print to FILE from PB equation E with all its coefficients
163 multiplied by C. */
165 static void
166 omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
168 int i;
169 bool first = true;
170 int n = pb->num_vars;
171 int went_first = -1;
173 for (i = 1; i <= n; i++)
174 if (c * e->coef[i] > 0)
176 first = false;
177 went_first = i;
179 if (c * e->coef[i] == 1)
180 fprintf (file, "%s", omega_variable_to_str (pb, i));
181 else
182 fprintf (file, "%d * %s", c * e->coef[i],
183 omega_variable_to_str (pb, i));
184 break;
187 for (i = 1; i <= n; i++)
188 if (i != went_first && c * e->coef[i] != 0)
190 if (!first && c * e->coef[i] > 0)
191 fprintf (file, " + ");
193 first = false;
195 if (c * e->coef[i] == 1)
196 fprintf (file, "%s", omega_variable_to_str (pb, i));
197 else if (c * e->coef[i] == -1)
198 fprintf (file, " - %s", omega_variable_to_str (pb, i));
199 else
200 fprintf (file, "%d * %s", c * e->coef[i],
201 omega_variable_to_str (pb, i));
204 if (!first && c * e->coef[0] > 0)
205 fprintf (file, " + ");
207 if (first || c * e->coef[0] != 0)
208 fprintf (file, "%d", c * e->coef[0]);
211 /* Print to FILE the equation E of problem PB. */
213 void
214 omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
216 int i;
217 int n = pb->num_vars + extra;
218 bool is_lt = test && e->coef[0] == -1;
219 bool first;
221 if (test)
223 if (e->touched)
224 fprintf (file, "!");
226 else if (e->key != 0)
227 fprintf (file, "%d: ", e->key);
230 if (e->color == omega_red)
231 fprintf (file, "[");
233 first = true;
235 for (i = is_lt ? 1 : 0; i <= n; i++)
236 if (e->coef[i] < 0)
238 if (!first)
239 fprintf (file, " + ");
240 else
241 first = false;
243 if (i == 0)
244 fprintf (file, "%d", -e->coef[i]);
245 else if (e->coef[i] == -1)
246 fprintf (file, "%s", omega_variable_to_str (pb, i));
247 else
248 fprintf (file, "%d * %s", -e->coef[i],
249 omega_variable_to_str (pb, i));
252 if (first)
254 if (is_lt)
256 fprintf (file, "1");
257 is_lt = false;
259 else
260 fprintf (file, "0");
263 if (test == 0)
264 fprintf (file, " = ");
265 else if (is_lt)
266 fprintf (file, " < ");
267 else
268 fprintf (file, " <= ");
270 first = true;
272 for (i = 0; i <= n; i++)
273 if (e->coef[i] > 0)
275 if (!first)
276 fprintf (file, " + ");
277 else
278 first = false;
280 if (i == 0)
281 fprintf (file, "%d", e->coef[i]);
282 else if (e->coef[i] == 1)
283 fprintf (file, "%s", omega_variable_to_str (pb, i));
284 else
285 fprintf (file, "%d * %s", e->coef[i],
286 omega_variable_to_str (pb, i));
289 if (first)
290 fprintf (file, "0");
292 if (e->color == omega_red)
293 fprintf (file, "]");
296 /* Print to FILE all the variables of problem PB. */
298 static void
299 omega_print_vars (FILE *file, omega_pb pb)
301 int i;
303 fprintf (file, "variables = ");
305 if (pb->safe_vars > 0)
306 fprintf (file, "protected (");
308 for (i = 1; i <= pb->num_vars; i++)
310 fprintf (file, "%s", omega_variable_to_str (pb, i));
312 if (i == pb->safe_vars)
313 fprintf (file, ")");
315 if (i < pb->num_vars)
316 fprintf (file, ", ");
319 fprintf (file, "\n");
322 /* Dump problem PB. */
324 DEBUG_FUNCTION void
325 debug (omega_pb_d &ref)
327 omega_print_problem (stderr, &ref);
330 DEBUG_FUNCTION void
331 debug (omega_pb_d *ptr)
333 if (ptr)
334 debug (*ptr);
335 else
336 fprintf (stderr, "<nil>\n");
339 /* Debug problem PB. */
341 DEBUG_FUNCTION void
342 debug_omega_problem (omega_pb pb)
344 omega_print_problem (stderr, pb);
347 /* Print to FILE problem PB. */
349 void
350 omega_print_problem (FILE *file, omega_pb pb)
352 int e;
354 if (!pb->variables_initialized)
355 omega_initialize_variables (pb);
357 omega_print_vars (file, pb);
359 for (e = 0; e < pb->num_eqs; e++)
361 omega_print_eq (file, pb, &pb->eqs[e]);
362 fprintf (file, "\n");
365 fprintf (file, "Done with EQ\n");
367 for (e = 0; e < pb->num_geqs; e++)
369 omega_print_geq (file, pb, &pb->geqs[e]);
370 fprintf (file, "\n");
373 fprintf (file, "Done with GEQ\n");
375 for (e = 0; e < pb->num_subs; e++)
377 eqn eq = &pb->subs[e];
379 if (eq->color == omega_red)
380 fprintf (file, "[");
382 if (eq->key > 0)
383 fprintf (file, "%s := ", omega_var_to_str (eq->key));
384 else
385 fprintf (file, "#%d := ", eq->key);
387 omega_print_term (file, pb, eq, 1);
389 if (eq->color == omega_red)
390 fprintf (file, "]");
392 fprintf (file, "\n");
396 /* Return the number of equations in PB tagged omega_red. */
399 omega_count_red_equations (omega_pb pb)
401 int e, i;
402 int result = 0;
404 for (e = 0; e < pb->num_eqs; e++)
405 if (pb->eqs[e].color == omega_red)
407 for (i = pb->num_vars; i > 0; i--)
408 if (pb->geqs[e].coef[i])
409 break;
411 if (i == 0 && pb->geqs[e].coef[0] == 1)
412 return 0;
413 else
414 result += 2;
417 for (e = 0; e < pb->num_geqs; e++)
418 if (pb->geqs[e].color == omega_red)
419 result += 1;
421 for (e = 0; e < pb->num_subs; e++)
422 if (pb->subs[e].color == omega_red)
423 result += 2;
425 return result;
428 /* Print to FILE all the equations in PB that are tagged omega_red. */
430 void
431 omega_print_red_equations (FILE *file, omega_pb pb)
433 int e;
435 if (!pb->variables_initialized)
436 omega_initialize_variables (pb);
438 omega_print_vars (file, pb);
440 for (e = 0; e < pb->num_eqs; e++)
441 if (pb->eqs[e].color == omega_red)
443 omega_print_eq (file, pb, &pb->eqs[e]);
444 fprintf (file, "\n");
447 for (e = 0; e < pb->num_geqs; e++)
448 if (pb->geqs[e].color == omega_red)
450 omega_print_geq (file, pb, &pb->geqs[e]);
451 fprintf (file, "\n");
454 for (e = 0; e < pb->num_subs; e++)
455 if (pb->subs[e].color == omega_red)
457 eqn eq = &pb->subs[e];
458 fprintf (file, "[");
460 if (eq->key > 0)
461 fprintf (file, "%s := ", omega_var_to_str (eq->key));
462 else
463 fprintf (file, "#%d := ", eq->key);
465 omega_print_term (file, pb, eq, 1);
466 fprintf (file, "]\n");
470 /* Pretty print PB to FILE. */
472 void
473 omega_pretty_print_problem (FILE *file, omega_pb pb)
475 int e, v, v1, v2, v3, t;
476 bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
477 int stuffPrinted = 0;
478 bool change;
480 typedef enum {
481 none, le, lt
482 } partial_order_type;
484 partial_order_type **po = XNEWVEC (partial_order_type *,
485 OMEGA_MAX_VARS * OMEGA_MAX_VARS);
486 int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
487 int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
488 int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
489 int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
490 int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
491 int i, m;
492 bool multiprint;
494 if (!pb->variables_initialized)
495 omega_initialize_variables (pb);
497 if (pb->num_vars > 0)
499 omega_eliminate_redundant (pb, false);
501 for (e = 0; e < pb->num_eqs; e++)
503 if (stuffPrinted)
504 fprintf (file, "; ");
506 stuffPrinted = 1;
507 omega_print_eq (file, pb, &pb->eqs[e]);
510 for (e = 0; e < pb->num_geqs; e++)
511 live[e] = true;
513 while (1)
515 for (v = 1; v <= pb->num_vars; v++)
517 last_links[v] = first_links[v] = 0;
518 chain_length[v] = 0;
520 for (v2 = 1; v2 <= pb->num_vars; v2++)
521 po[v][v2] = none;
524 for (e = 0; e < pb->num_geqs; e++)
525 if (live[e])
527 for (v = 1; v <= pb->num_vars; v++)
528 if (pb->geqs[e].coef[v] == 1)
529 first_links[v]++;
530 else if (pb->geqs[e].coef[v] == -1)
531 last_links[v]++;
533 v1 = pb->num_vars;
535 while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
536 v1--;
538 v2 = v1 - 1;
540 while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
541 v2--;
543 v3 = v2 - 1;
545 while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
546 v3--;
548 if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
549 || v2 <= 0 || v3 > 0
550 || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
552 /* Not a partial order relation. */
554 else
556 if (pb->geqs[e].coef[v1] == 1)
558 v3 = v2;
559 v2 = v1;
560 v1 = v3;
563 /* Relation is v1 <= v2 or v1 < v2. */
564 po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
565 po_eq[v1][v2] = e;
568 for (v = 1; v <= pb->num_vars; v++)
569 chain_length[v] = last_links[v];
571 /* Just in case pb->num_vars <= 0. */
572 change = false;
573 for (t = 0; t < pb->num_vars; t++)
575 change = false;
577 for (v1 = 1; v1 <= pb->num_vars; v1++)
578 for (v2 = 1; v2 <= pb->num_vars; v2++)
579 if (po[v1][v2] != none &&
580 chain_length[v1] <= chain_length[v2])
582 chain_length[v1] = chain_length[v2] + 1;
583 change = true;
587 /* Caught in cycle. */
588 gcc_assert (!change);
590 for (v1 = 1; v1 <= pb->num_vars; v1++)
591 if (chain_length[v1] == 0)
592 first_links[v1] = 0;
594 v = 1;
596 for (v1 = 2; v1 <= pb->num_vars; v1++)
597 if (chain_length[v1] + first_links[v1] >
598 chain_length[v] + first_links[v])
599 v = v1;
601 if (chain_length[v] + first_links[v] == 0)
602 break;
604 if (stuffPrinted)
605 fprintf (file, "; ");
607 stuffPrinted = 1;
609 /* Chain starts at v. */
611 int tmp;
612 bool first = true;
614 for (e = 0; e < pb->num_geqs; e++)
615 if (live[e] && pb->geqs[e].coef[v] == 1)
617 if (!first)
618 fprintf (file, ", ");
620 tmp = pb->geqs[e].coef[v];
621 pb->geqs[e].coef[v] = 0;
622 omega_print_term (file, pb, &pb->geqs[e], -1);
623 pb->geqs[e].coef[v] = tmp;
624 live[e] = false;
625 first = false;
628 if (!first)
629 fprintf (file, " <= ");
632 /* Find chain. */
633 chain[0] = v;
634 m = 1;
635 while (1)
637 /* Print chain. */
638 for (v2 = 1; v2 <= pb->num_vars; v2++)
639 if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
640 break;
642 if (v2 > pb->num_vars)
643 break;
645 chain[m++] = v2;
646 v = v2;
649 fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
651 for (multiprint = false, i = 1; i < m; i++)
653 v = chain[i - 1];
654 v2 = chain[i];
656 if (po[v][v2] == le)
657 fprintf (file, " <= ");
658 else
659 fprintf (file, " < ");
661 fprintf (file, "%s", omega_variable_to_str (pb, v2));
662 live[po_eq[v][v2]] = false;
664 if (!multiprint && i < m - 1)
665 for (v3 = 1; v3 <= pb->num_vars; v3++)
667 if (v == v3 || v2 == v3
668 || po[v][v2] != po[v][v3]
669 || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
670 continue;
672 fprintf (file, ",%s", omega_variable_to_str (pb, v3));
673 live[po_eq[v][v3]] = false;
674 live[po_eq[v3][chain[i + 1]]] = false;
675 multiprint = true;
677 else
678 multiprint = false;
681 v = chain[m - 1];
682 /* Print last_links. */
684 int tmp;
685 bool first = true;
687 for (e = 0; e < pb->num_geqs; e++)
688 if (live[e] && pb->geqs[e].coef[v] == -1)
690 if (!first)
691 fprintf (file, ", ");
692 else
693 fprintf (file, " <= ");
695 tmp = pb->geqs[e].coef[v];
696 pb->geqs[e].coef[v] = 0;
697 omega_print_term (file, pb, &pb->geqs[e], 1);
698 pb->geqs[e].coef[v] = tmp;
699 live[e] = false;
700 first = false;
705 for (e = 0; e < pb->num_geqs; e++)
706 if (live[e])
708 if (stuffPrinted)
709 fprintf (file, "; ");
710 stuffPrinted = 1;
711 omega_print_geq (file, pb, &pb->geqs[e]);
714 for (e = 0; e < pb->num_subs; e++)
716 eqn eq = &pb->subs[e];
718 if (stuffPrinted)
719 fprintf (file, "; ");
721 stuffPrinted = 1;
723 if (eq->key > 0)
724 fprintf (file, "%s := ", omega_var_to_str (eq->key));
725 else
726 fprintf (file, "#%d := ", eq->key);
728 omega_print_term (file, pb, eq, 1);
732 free (live);
733 free (po);
734 free (po_eq);
735 free (last_links);
736 free (first_links);
737 free (chain_length);
738 free (chain);
741 /* Assign to variable I in PB the next wildcard name. The name of a
742 wildcard is a negative number. */
743 static int next_wild_card = 0;
745 static void
746 omega_name_wild_card (omega_pb pb, int i)
748 --next_wild_card;
749 if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
750 next_wild_card = -1;
751 pb->var[i] = next_wild_card;
754 /* Return the index of the last protected (or safe) variable in PB,
755 after having added a new wildcard variable. */
757 static int
758 omega_add_new_wild_card (omega_pb pb)
760 int e;
761 int i = ++pb->safe_vars;
762 pb->num_vars++;
764 /* Make a free place in the protected (safe) variables, by moving
765 the non protected variable pointed by "I" at the end, ie. at
766 offset pb->num_vars. */
767 if (pb->num_vars != i)
769 /* Move "I" for all the inequalities. */
770 for (e = pb->num_geqs - 1; e >= 0; e--)
772 if (pb->geqs[e].coef[i])
773 pb->geqs[e].touched = 1;
775 pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
778 /* Move "I" for all the equalities. */
779 for (e = pb->num_eqs - 1; e >= 0; e--)
780 pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
782 /* Move "I" for all the substitutions. */
783 for (e = pb->num_subs - 1; e >= 0; e--)
784 pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
786 /* Move the identifier. */
787 pb->var[pb->num_vars] = pb->var[i];
790 /* Initialize at zero all the coefficients */
791 for (e = pb->num_geqs - 1; e >= 0; e--)
792 pb->geqs[e].coef[i] = 0;
794 for (e = pb->num_eqs - 1; e >= 0; e--)
795 pb->eqs[e].coef[i] = 0;
797 for (e = pb->num_subs - 1; e >= 0; e--)
798 pb->subs[e].coef[i] = 0;
800 /* And give it a name. */
801 omega_name_wild_card (pb, i);
802 return i;
805 /* Delete inequality E from problem PB that has N_VARS variables. */
807 static void
808 omega_delete_geq (omega_pb pb, int e, int n_vars)
810 if (dump_file && (dump_flags & TDF_DETAILS))
812 fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
813 omega_print_geq (dump_file, pb, &pb->geqs[e]);
814 fprintf (dump_file, "\n");
817 if (e < pb->num_geqs - 1)
818 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
820 pb->num_geqs--;
823 /* Delete extra inequality E from problem PB that has N_VARS
824 variables. */
826 static void
827 omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
829 if (dump_file && (dump_flags & TDF_DETAILS))
831 fprintf (dump_file, "Deleting %d: ",e);
832 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
833 fprintf (dump_file, "\n");
836 if (e < pb->num_geqs - 1)
837 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
839 pb->num_geqs--;
843 /* Remove variable I from problem PB. */
845 static void
846 omega_delete_variable (omega_pb pb, int i)
848 int n_vars = pb->num_vars;
849 int e;
851 if (omega_safe_var_p (pb, i))
853 int j = pb->safe_vars;
855 for (e = pb->num_geqs - 1; e >= 0; e--)
857 pb->geqs[e].touched = 1;
858 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
859 pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
862 for (e = pb->num_eqs - 1; e >= 0; e--)
864 pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
865 pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
868 for (e = pb->num_subs - 1; e >= 0; e--)
870 pb->subs[e].coef[i] = pb->subs[e].coef[j];
871 pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
874 pb->var[i] = pb->var[j];
875 pb->var[j] = pb->var[n_vars];
877 else if (i < n_vars)
879 for (e = pb->num_geqs - 1; e >= 0; e--)
880 if (pb->geqs[e].coef[n_vars])
882 pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
883 pb->geqs[e].touched = 1;
886 for (e = pb->num_eqs - 1; e >= 0; e--)
887 pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
889 for (e = pb->num_subs - 1; e >= 0; e--)
890 pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
892 pb->var[i] = pb->var[n_vars];
895 if (omega_safe_var_p (pb, i))
896 pb->safe_vars--;
898 pb->num_vars--;
901 /* Because the coefficients of an equation are sparse, PACKING records
902 indices for non null coefficients. */
903 static int *packing;
905 /* Set up the coefficients of PACKING, following the coefficients of
906 equation EQN that has NUM_VARS variables. */
908 static inline int
909 setup_packing (eqn eqn, int num_vars)
911 int k;
912 int n = 0;
914 for (k = num_vars; k >= 0; k--)
915 if (eqn->coef[k])
916 packing[n++] = k;
918 return n;
921 /* Computes a linear combination of EQ and SUB at VAR with coefficient
922 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
923 non null indices of SUB stored in PACKING. */
925 static inline void
926 omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
927 int top_var)
929 if (eq->coef[var] != 0)
931 if (eq->color == omega_black)
932 *found_black = true;
933 else
935 int j, k = eq->coef[var];
937 eq->coef[var] = 0;
939 for (j = top_var; j >= 0; j--)
940 eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
945 /* Substitute in PB variable VAR with "C * SUB". */
947 static void
948 omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
950 int e, top_var = setup_packing (sub, pb->num_vars);
952 *found_black = false;
954 if (dump_file && (dump_flags & TDF_DETAILS))
956 if (sub->color == omega_red)
957 fprintf (dump_file, "[");
959 fprintf (dump_file, "substituting using %s := ",
960 omega_variable_to_str (pb, var));
961 omega_print_term (dump_file, pb, sub, -c);
963 if (sub->color == omega_red)
964 fprintf (dump_file, "]");
966 fprintf (dump_file, "\n");
967 omega_print_vars (dump_file, pb);
970 for (e = pb->num_eqs - 1; e >= 0; e--)
972 eqn eqn = &(pb->eqs[e]);
974 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
976 if (dump_file && (dump_flags & TDF_DETAILS))
978 omega_print_eq (dump_file, pb, eqn);
979 fprintf (dump_file, "\n");
983 for (e = pb->num_geqs - 1; e >= 0; e--)
985 eqn eqn = &(pb->geqs[e]);
987 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
989 if (eqn->coef[var] && eqn->color == omega_red)
990 eqn->touched = 1;
992 if (dump_file && (dump_flags & TDF_DETAILS))
994 omega_print_geq (dump_file, pb, eqn);
995 fprintf (dump_file, "\n");
999 for (e = pb->num_subs - 1; e >= 0; e--)
1001 eqn eqn = &(pb->subs[e]);
1003 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
1005 if (dump_file && (dump_flags & TDF_DETAILS))
1007 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1008 omega_print_term (dump_file, pb, eqn, 1);
1009 fprintf (dump_file, "\n");
1013 if (dump_file && (dump_flags & TDF_DETAILS))
1014 fprintf (dump_file, "---\n\n");
1016 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1017 *found_black = true;
1020 /* Substitute in PB variable VAR with "C * SUB". */
1022 static void
1023 omega_substitute (omega_pb pb, eqn sub, int var, int c)
1025 int e, j, j0;
1026 int top_var = setup_packing (sub, pb->num_vars);
1028 if (dump_file && (dump_flags & TDF_DETAILS))
1030 fprintf (dump_file, "substituting using %s := ",
1031 omega_variable_to_str (pb, var));
1032 omega_print_term (dump_file, pb, sub, -c);
1033 fprintf (dump_file, "\n");
1034 omega_print_vars (dump_file, pb);
1037 if (top_var < 0)
1039 for (e = pb->num_eqs - 1; e >= 0; e--)
1040 pb->eqs[e].coef[var] = 0;
1042 for (e = pb->num_geqs - 1; e >= 0; e--)
1043 if (pb->geqs[e].coef[var] != 0)
1045 pb->geqs[e].touched = 1;
1046 pb->geqs[e].coef[var] = 0;
1049 for (e = pb->num_subs - 1; e >= 0; e--)
1050 pb->subs[e].coef[var] = 0;
1052 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1054 int k;
1055 eqn eqn = &(pb->subs[pb->num_subs++]);
1057 for (k = pb->num_vars; k >= 0; k--)
1058 eqn->coef[k] = 0;
1060 eqn->key = pb->var[var];
1061 eqn->color = omega_black;
1064 else if (top_var == 0 && packing[0] == 0)
1066 c = -sub->coef[0] * c;
1068 for (e = pb->num_eqs - 1; e >= 0; e--)
1070 pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
1071 pb->eqs[e].coef[var] = 0;
1074 for (e = pb->num_geqs - 1; e >= 0; e--)
1075 if (pb->geqs[e].coef[var] != 0)
1077 pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
1078 pb->geqs[e].coef[var] = 0;
1079 pb->geqs[e].touched = 1;
1082 for (e = pb->num_subs - 1; e >= 0; e--)
1084 pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
1085 pb->subs[e].coef[var] = 0;
1088 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1090 int k;
1091 eqn eqn = &(pb->subs[pb->num_subs++]);
1093 for (k = pb->num_vars; k >= 1; k--)
1094 eqn->coef[k] = 0;
1096 eqn->coef[0] = c;
1097 eqn->key = pb->var[var];
1098 eqn->color = omega_black;
1101 if (dump_file && (dump_flags & TDF_DETAILS))
1103 fprintf (dump_file, "---\n\n");
1104 omega_print_problem (dump_file, pb);
1105 fprintf (dump_file, "===\n\n");
1108 else
1110 for (e = pb->num_eqs - 1; e >= 0; e--)
1112 eqn eqn = &(pb->eqs[e]);
1113 int k = eqn->coef[var];
1115 if (k != 0)
1117 k = c * k;
1118 eqn->coef[var] = 0;
1120 for (j = top_var; j >= 0; j--)
1122 j0 = packing[j];
1123 eqn->coef[j0] -= sub->coef[j0] * k;
1127 if (dump_file && (dump_flags & TDF_DETAILS))
1129 omega_print_eq (dump_file, pb, eqn);
1130 fprintf (dump_file, "\n");
1134 for (e = pb->num_geqs - 1; e >= 0; e--)
1136 eqn eqn = &(pb->geqs[e]);
1137 int k = eqn->coef[var];
1139 if (k != 0)
1141 k = c * k;
1142 eqn->touched = 1;
1143 eqn->coef[var] = 0;
1145 for (j = top_var; j >= 0; j--)
1147 j0 = packing[j];
1148 eqn->coef[j0] -= sub->coef[j0] * k;
1152 if (dump_file && (dump_flags & TDF_DETAILS))
1154 omega_print_geq (dump_file, pb, eqn);
1155 fprintf (dump_file, "\n");
1159 for (e = pb->num_subs - 1; e >= 0; e--)
1161 eqn eqn = &(pb->subs[e]);
1162 int k = eqn->coef[var];
1164 if (k != 0)
1166 k = c * k;
1167 eqn->coef[var] = 0;
1169 for (j = top_var; j >= 0; j--)
1171 j0 = packing[j];
1172 eqn->coef[j0] -= sub->coef[j0] * k;
1176 if (dump_file && (dump_flags & TDF_DETAILS))
1178 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1179 omega_print_term (dump_file, pb, eqn, 1);
1180 fprintf (dump_file, "\n");
1184 if (dump_file && (dump_flags & TDF_DETAILS))
1186 fprintf (dump_file, "---\n\n");
1187 omega_print_problem (dump_file, pb);
1188 fprintf (dump_file, "===\n\n");
1191 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1193 int k;
1194 eqn eqn = &(pb->subs[pb->num_subs++]);
1195 c = -c;
1197 for (k = pb->num_vars; k >= 0; k--)
1198 eqn->coef[k] = c * (sub->coef[k]);
1200 eqn->key = pb->var[var];
1201 eqn->color = sub->color;
1206 /* Solve e = factor alpha for x_j and substitute. */
1208 static void
1209 omega_do_mod (omega_pb pb, int factor, int e, int j)
1211 int k, i;
1212 eqn eq = omega_alloc_eqns (0, 1);
1213 int nfactor;
1214 bool kill_j = false;
1216 omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
1218 for (k = pb->num_vars; k >= 0; k--)
1220 eq->coef[k] = int_mod (eq->coef[k], factor);
1222 if (2 * eq->coef[k] >= factor)
1223 eq->coef[k] -= factor;
1226 nfactor = eq->coef[j];
1228 if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
1230 i = omega_add_new_wild_card (pb);
1231 eq->coef[pb->num_vars] = eq->coef[i];
1232 eq->coef[j] = 0;
1233 eq->coef[i] = -factor;
1234 kill_j = true;
1236 else
1238 eq->coef[j] = -factor;
1239 if (!omega_wildcard_p (pb, j))
1240 omega_name_wild_card (pb, j);
1243 omega_substitute (pb, eq, j, nfactor);
1245 for (k = pb->num_vars; k >= 0; k--)
1246 pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
1248 if (kill_j)
1249 omega_delete_variable (pb, j);
1251 if (dump_file && (dump_flags & TDF_DETAILS))
1253 fprintf (dump_file, "Mod-ing and normalizing produces:\n");
1254 omega_print_problem (dump_file, pb);
1257 omega_free_eqns (eq, 1);
1260 /* Multiplies by -1 inequality E. */
1262 void
1263 omega_negate_geq (omega_pb pb, int e)
1265 int i;
1267 for (i = pb->num_vars; i >= 0; i--)
1268 pb->geqs[e].coef[i] *= -1;
1270 pb->geqs[e].coef[0]--;
1271 pb->geqs[e].touched = 1;
1274 /* Returns OMEGA_TRUE when problem PB has a solution. */
1276 static enum omega_result
1277 verify_omega_pb (omega_pb pb)
1279 enum omega_result result;
1280 int e;
1281 bool any_color = false;
1282 omega_pb tmp_problem = XNEW (struct omega_pb_d);
1284 omega_copy_problem (tmp_problem, pb);
1285 tmp_problem->safe_vars = 0;
1286 tmp_problem->num_subs = 0;
1288 for (e = pb->num_geqs - 1; e >= 0; e--)
1289 if (pb->geqs[e].color == omega_red)
1291 any_color = true;
1292 break;
1295 if (please_no_equalities_in_simplified_problems)
1296 any_color = true;
1298 if (any_color)
1299 original_problem = no_problem;
1300 else
1301 original_problem = pb;
1303 if (dump_file && (dump_flags & TDF_DETAILS))
1305 fprintf (dump_file, "verifying problem");
1307 if (any_color)
1308 fprintf (dump_file, " (color mode)");
1310 fprintf (dump_file, " :\n");
1311 omega_print_problem (dump_file, pb);
1314 result = omega_solve_problem (tmp_problem, omega_unknown);
1315 original_problem = no_problem;
1316 free (tmp_problem);
1318 if (dump_file && (dump_flags & TDF_DETAILS))
1320 if (result != omega_false)
1321 fprintf (dump_file, "verified problem\n");
1322 else
1323 fprintf (dump_file, "disproved problem\n");
1324 omega_print_problem (dump_file, pb);
1327 return result;
1330 /* Add a new equality to problem PB at last position E. */
1332 static void
1333 adding_equality_constraint (omega_pb pb, int e)
1335 if (original_problem != no_problem
1336 && original_problem != pb
1337 && !conservative)
1339 int i, j;
1340 int e2 = original_problem->num_eqs++;
1342 if (dump_file && (dump_flags & TDF_DETAILS))
1343 fprintf (dump_file,
1344 "adding equality constraint %d to outer problem\n", e2);
1345 omega_init_eqn_zero (&original_problem->eqs[e2],
1346 original_problem->num_vars);
1348 for (i = pb->num_vars; i >= 1; i--)
1350 for (j = original_problem->num_vars; j >= 1; j--)
1351 if (original_problem->var[j] == pb->var[i])
1352 break;
1354 if (j <= 0)
1356 if (dump_file && (dump_flags & TDF_DETAILS))
1357 fprintf (dump_file, "retracting\n");
1358 original_problem->num_eqs--;
1359 return;
1361 original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
1364 original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
1366 if (dump_file && (dump_flags & TDF_DETAILS))
1367 omega_print_problem (dump_file, original_problem);
1371 static int *fast_lookup;
1372 static int *fast_lookup_red;
1374 typedef enum {
1375 normalize_false,
1376 normalize_uncoupled,
1377 normalize_coupled
1378 } normalize_return_type;
1380 /* Normalizes PB by removing redundant constraints. Returns
1381 normalize_false when the constraints system has no solution,
1382 otherwise returns normalize_coupled or normalize_uncoupled. */
1384 static normalize_return_type
1385 normalize_omega_problem (omega_pb pb)
1387 int e, i, j, k, n_vars;
1388 int coupled_subscripts = 0;
1390 n_vars = pb->num_vars;
1392 for (e = 0; e < pb->num_geqs; e++)
1394 if (!pb->geqs[e].touched)
1396 if (!single_var_geq (&pb->geqs[e], n_vars))
1397 coupled_subscripts = 1;
1399 else
1401 int g, top_var, i0, hashCode;
1402 int *p = &packing[0];
1404 for (k = 1; k <= n_vars; k++)
1405 if (pb->geqs[e].coef[k])
1406 *(p++) = k;
1408 top_var = (p - &packing[0]) - 1;
1410 if (top_var == -1)
1412 if (pb->geqs[e].coef[0] < 0)
1414 if (dump_file && (dump_flags & TDF_DETAILS))
1416 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1417 fprintf (dump_file, "\nequations have no solution \n");
1419 return normalize_false;
1422 omega_delete_geq (pb, e, n_vars);
1423 e--;
1424 continue;
1426 else if (top_var == 0)
1428 int singlevar = packing[0];
1430 g = pb->geqs[e].coef[singlevar];
1432 if (g > 0)
1434 pb->geqs[e].coef[singlevar] = 1;
1435 pb->geqs[e].key = singlevar;
1437 else
1439 g = -g;
1440 pb->geqs[e].coef[singlevar] = -1;
1441 pb->geqs[e].key = -singlevar;
1444 if (g > 1)
1445 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1447 else
1449 int g2;
1450 int hash_key_multiplier = 31;
1452 coupled_subscripts = 1;
1453 i0 = top_var;
1454 i = packing[i0--];
1455 g = pb->geqs[e].coef[i];
1456 hashCode = g * (i + 3);
1458 if (g < 0)
1459 g = -g;
1461 for (; i0 >= 0; i0--)
1463 int x;
1465 i = packing[i0];
1466 x = pb->geqs[e].coef[i];
1467 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1469 if (x < 0)
1470 x = -x;
1472 if (x == 1)
1474 g = 1;
1475 i0--;
1476 break;
1478 else
1479 g = gcd (x, g);
1482 for (; i0 >= 0; i0--)
1484 int x;
1485 i = packing[i0];
1486 x = pb->geqs[e].coef[i];
1487 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1490 if (g > 1)
1492 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1493 i0 = top_var;
1494 i = packing[i0--];
1495 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1496 hashCode = pb->geqs[e].coef[i] * (i + 3);
1498 for (; i0 >= 0; i0--)
1500 i = packing[i0];
1501 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1502 hashCode = hashCode * hash_key_multiplier * (i + 3)
1503 + pb->geqs[e].coef[i];
1507 g2 = abs (hashCode);
1509 if (dump_file && (dump_flags & TDF_DETAILS))
1511 fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
1512 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1513 fprintf (dump_file, "\n");
1516 j = g2 % HASH_TABLE_SIZE;
1518 do {
1519 eqn proto = &(hash_master[j]);
1521 if (proto->touched == g2)
1523 if (proto->coef[0] == top_var)
1525 if (hashCode >= 0)
1526 for (i0 = top_var; i0 >= 0; i0--)
1528 i = packing[i0];
1530 if (pb->geqs[e].coef[i] != proto->coef[i])
1531 break;
1533 else
1534 for (i0 = top_var; i0 >= 0; i0--)
1536 i = packing[i0];
1538 if (pb->geqs[e].coef[i] != -proto->coef[i])
1539 break;
1542 if (i0 < 0)
1544 if (hashCode >= 0)
1545 pb->geqs[e].key = proto->key;
1546 else
1547 pb->geqs[e].key = -proto->key;
1548 break;
1552 else if (proto->touched < 0)
1554 omega_init_eqn_zero (proto, pb->num_vars);
1555 if (hashCode >= 0)
1556 for (i0 = top_var; i0 >= 0; i0--)
1558 i = packing[i0];
1559 proto->coef[i] = pb->geqs[e].coef[i];
1561 else
1562 for (i0 = top_var; i0 >= 0; i0--)
1564 i = packing[i0];
1565 proto->coef[i] = -pb->geqs[e].coef[i];
1568 proto->coef[0] = top_var;
1569 proto->touched = g2;
1571 if (dump_file && (dump_flags & TDF_DETAILS))
1572 fprintf (dump_file, " constraint key = %d\n",
1573 next_key);
1575 proto->key = next_key++;
1577 /* Too many hash keys generated. */
1578 gcc_assert (proto->key <= MAX_KEYS);
1580 if (hashCode >= 0)
1581 pb->geqs[e].key = proto->key;
1582 else
1583 pb->geqs[e].key = -proto->key;
1585 break;
1588 j = (j + 1) % HASH_TABLE_SIZE;
1589 } while (1);
1592 pb->geqs[e].touched = 0;
1596 int eKey = pb->geqs[e].key;
1597 int e2;
1598 if (e > 0)
1600 int cTerm = pb->geqs[e].coef[0];
1601 e2 = fast_lookup[MAX_KEYS - eKey];
1603 if (e2 < e && pb->geqs[e2].key == -eKey
1604 && pb->geqs[e2].color == omega_black)
1606 if (pb->geqs[e2].coef[0] < -cTerm)
1608 if (dump_file && (dump_flags & TDF_DETAILS))
1610 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1611 fprintf (dump_file, "\n");
1612 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1613 fprintf (dump_file,
1614 "\nequations have no solution \n");
1616 return normalize_false;
1619 if (pb->geqs[e2].coef[0] == -cTerm
1620 && (create_color
1621 || pb->geqs[e].color == omega_black))
1623 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1624 pb->num_vars);
1625 if (pb->geqs[e].color == omega_black)
1626 adding_equality_constraint (pb, pb->num_eqs);
1627 pb->num_eqs++;
1628 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1632 e2 = fast_lookup_red[MAX_KEYS - eKey];
1634 if (e2 < e && pb->geqs[e2].key == -eKey
1635 && pb->geqs[e2].color == omega_red)
1637 if (pb->geqs[e2].coef[0] < -cTerm)
1639 if (dump_file && (dump_flags & TDF_DETAILS))
1641 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1642 fprintf (dump_file, "\n");
1643 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1644 fprintf (dump_file,
1645 "\nequations have no solution \n");
1647 return normalize_false;
1650 if (pb->geqs[e2].coef[0] == -cTerm && create_color)
1652 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1653 pb->num_vars);
1654 pb->eqs[pb->num_eqs].color = omega_red;
1655 pb->num_eqs++;
1656 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1660 e2 = fast_lookup[MAX_KEYS + eKey];
1662 if (e2 < e && pb->geqs[e2].key == eKey
1663 && pb->geqs[e2].color == omega_black)
1665 if (pb->geqs[e2].coef[0] > cTerm)
1667 if (pb->geqs[e].color == omega_black)
1669 if (dump_file && (dump_flags & TDF_DETAILS))
1671 fprintf (dump_file,
1672 "Removing Redundant Equation: ");
1673 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1674 fprintf (dump_file, "\n");
1675 fprintf (dump_file,
1676 "[a] Made Redundant by: ");
1677 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1678 fprintf (dump_file, "\n");
1680 pb->geqs[e2].coef[0] = cTerm;
1681 omega_delete_geq (pb, e, n_vars);
1682 e--;
1683 continue;
1686 else
1688 if (dump_file && (dump_flags & TDF_DETAILS))
1690 fprintf (dump_file, "Removing Redundant Equation: ");
1691 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1692 fprintf (dump_file, "\n");
1693 fprintf (dump_file, "[b] Made Redundant by: ");
1694 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1695 fprintf (dump_file, "\n");
1697 omega_delete_geq (pb, e, n_vars);
1698 e--;
1699 continue;
1703 e2 = fast_lookup_red[MAX_KEYS + eKey];
1705 if (e2 < e && pb->geqs[e2].key == eKey
1706 && pb->geqs[e2].color == omega_red)
1708 if (pb->geqs[e2].coef[0] >= cTerm)
1710 if (dump_file && (dump_flags & TDF_DETAILS))
1712 fprintf (dump_file, "Removing Redundant Equation: ");
1713 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1714 fprintf (dump_file, "\n");
1715 fprintf (dump_file, "[c] Made Redundant by: ");
1716 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1717 fprintf (dump_file, "\n");
1719 pb->geqs[e2].coef[0] = cTerm;
1720 pb->geqs[e2].color = pb->geqs[e].color;
1722 else if (pb->geqs[e].color == omega_red)
1724 if (dump_file && (dump_flags & TDF_DETAILS))
1726 fprintf (dump_file, "Removing Redundant Equation: ");
1727 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1728 fprintf (dump_file, "\n");
1729 fprintf (dump_file, "[d] Made Redundant by: ");
1730 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1731 fprintf (dump_file, "\n");
1734 omega_delete_geq (pb, e, n_vars);
1735 e--;
1736 continue;
1741 if (pb->geqs[e].color == omega_red)
1742 fast_lookup_red[MAX_KEYS + eKey] = e;
1743 else
1744 fast_lookup[MAX_KEYS + eKey] = e;
1748 create_color = false;
1749 return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
1752 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1753 of variables in EQN. */
1755 static inline void
1756 divide_eqn_by_gcd (eqn eqn, int n_vars)
1758 int var, g = 0;
1760 for (var = n_vars; var >= 0; var--)
1761 g = gcd (abs (eqn->coef[var]), g);
1763 if (g)
1764 for (var = n_vars; var >= 0; var--)
1765 eqn->coef[var] = eqn->coef[var] / g;
1768 /* Rewrite some non-safe variables in function of protected
1769 wildcard variables. */
1771 static void
1772 cleanout_wildcards (omega_pb pb)
1774 int e, i, j;
1775 int n_vars = pb->num_vars;
1776 bool renormalize = false;
1778 for (e = pb->num_eqs - 1; e >= 0; e--)
1779 for (i = n_vars; !omega_safe_var_p (pb, i); i--)
1780 if (pb->eqs[e].coef[i] != 0)
1782 /* i is the last nonzero non-safe variable. */
1784 for (j = i - 1; !omega_safe_var_p (pb, j); j--)
1785 if (pb->eqs[e].coef[j] != 0)
1786 break;
1788 /* j is the next nonzero non-safe variable, or points
1789 to a safe variable: it is then a wildcard variable. */
1791 /* Clean it out. */
1792 if (omega_safe_var_p (pb, j))
1794 eqn sub = &(pb->eqs[e]);
1795 int c = pb->eqs[e].coef[i];
1796 int a = abs (c);
1797 int e2;
1799 if (dump_file && (dump_flags & TDF_DETAILS))
1801 fprintf (dump_file,
1802 "Found a single wild card equality: ");
1803 omega_print_eq (dump_file, pb, &pb->eqs[e]);
1804 fprintf (dump_file, "\n");
1805 omega_print_problem (dump_file, pb);
1808 for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
1809 if (e != e2 && pb->eqs[e2].coef[i]
1810 && (pb->eqs[e2].color == omega_red
1811 || (pb->eqs[e2].color == omega_black
1812 && pb->eqs[e].color == omega_black)))
1814 eqn eqn = &(pb->eqs[e2]);
1815 int var, k;
1817 for (var = n_vars; var >= 0; var--)
1818 eqn->coef[var] *= a;
1820 k = eqn->coef[i];
1822 for (var = n_vars; var >= 0; var--)
1823 eqn->coef[var] -= sub->coef[var] * k / c;
1825 eqn->coef[i] = 0;
1826 divide_eqn_by_gcd (eqn, n_vars);
1829 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
1830 if (pb->geqs[e2].coef[i]
1831 && (pb->geqs[e2].color == omega_red
1832 || (pb->eqs[e].color == omega_black
1833 && pb->geqs[e2].color == omega_black)))
1835 eqn eqn = &(pb->geqs[e2]);
1836 int var, k;
1838 for (var = n_vars; var >= 0; var--)
1839 eqn->coef[var] *= a;
1841 k = eqn->coef[i];
1843 for (var = n_vars; var >= 0; var--)
1844 eqn->coef[var] -= sub->coef[var] * k / c;
1846 eqn->coef[i] = 0;
1847 eqn->touched = 1;
1848 renormalize = true;
1851 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
1852 if (pb->subs[e2].coef[i]
1853 && (pb->subs[e2].color == omega_red
1854 || (pb->subs[e2].color == omega_black
1855 && pb->eqs[e].color == omega_black)))
1857 eqn eqn = &(pb->subs[e2]);
1858 int var, k;
1860 for (var = n_vars; var >= 0; var--)
1861 eqn->coef[var] *= a;
1863 k = eqn->coef[i];
1865 for (var = n_vars; var >= 0; var--)
1866 eqn->coef[var] -= sub->coef[var] * k / c;
1868 eqn->coef[i] = 0;
1869 divide_eqn_by_gcd (eqn, n_vars);
1872 if (dump_file && (dump_flags & TDF_DETAILS))
1874 fprintf (dump_file, "cleaned-out wildcard: ");
1875 omega_print_problem (dump_file, pb);
1877 break;
1881 if (renormalize)
1882 normalize_omega_problem (pb);
1885 /* Make variable IDX unprotected in PB, by swapping its index at the
1886 PB->safe_vars rank. */
1888 static inline void
1889 omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
1891 /* If IDX is protected... */
1892 if (*idx < pb->safe_vars)
1894 /* ... swap its index with the last non protected index. */
1895 int j = pb->safe_vars;
1896 int e;
1898 for (e = pb->num_geqs - 1; e >= 0; e--)
1900 pb->geqs[e].touched = 1;
1901 std::swap (pb->geqs[e].coef[*idx], pb->geqs[e].coef[j]);
1904 for (e = pb->num_eqs - 1; e >= 0; e--)
1905 std::swap (pb->eqs[e].coef[*idx], pb->eqs[e].coef[j]);
1907 for (e = pb->num_subs - 1; e >= 0; e--)
1908 std::swap (pb->subs[e].coef[*idx], pb->subs[e].coef[j]);
1910 if (unprotect)
1911 std::swap (unprotect[*idx], unprotect[j]);
1913 std::swap (pb->var[*idx], pb->var[j]);
1914 pb->forwarding_address[pb->var[*idx]] = *idx;
1915 pb->forwarding_address[pb->var[j]] = j;
1916 (*idx)--;
1919 /* The variable at pb->safe_vars is also unprotected now. */
1920 pb->safe_vars--;
1923 /* During the Fourier-Motzkin elimination some variables are
1924 substituted with other variables. This function resurrects the
1925 substituted variables in PB. */
1927 static void
1928 resurrect_subs (omega_pb pb)
1930 if (pb->num_subs > 0
1931 && please_no_equalities_in_simplified_problems == 0)
1933 int i, e, m;
1935 if (dump_file && (dump_flags & TDF_DETAILS))
1937 fprintf (dump_file,
1938 "problem reduced, bringing variables back to life\n");
1939 omega_print_problem (dump_file, pb);
1942 for (i = 1; omega_safe_var_p (pb, i); i++)
1943 if (omega_wildcard_p (pb, i))
1944 omega_unprotect_1 (pb, &i, NULL);
1946 m = pb->num_subs;
1948 for (e = pb->num_geqs - 1; e >= 0; e--)
1949 if (single_var_geq (&pb->geqs[e], pb->num_vars))
1951 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
1952 pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
1954 else
1956 pb->geqs[e].touched = 1;
1957 pb->geqs[e].key = 0;
1960 for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
1962 pb->var[i + m] = pb->var[i];
1964 for (e = pb->num_geqs - 1; e >= 0; e--)
1965 pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
1967 for (e = pb->num_eqs - 1; e >= 0; e--)
1968 pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
1970 for (e = pb->num_subs - 1; e >= 0; e--)
1971 pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
1974 for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
1976 for (e = pb->num_geqs - 1; e >= 0; e--)
1977 pb->geqs[e].coef[i] = 0;
1979 for (e = pb->num_eqs - 1; e >= 0; e--)
1980 pb->eqs[e].coef[i] = 0;
1982 for (e = pb->num_subs - 1; e >= 0; e--)
1983 pb->subs[e].coef[i] = 0;
1986 pb->num_vars += m;
1988 for (e = pb->num_subs - 1; e >= 0; e--)
1990 pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
1991 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
1992 pb->num_vars);
1993 pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
1994 pb->eqs[pb->num_eqs].color = omega_black;
1996 if (dump_file && (dump_flags & TDF_DETAILS))
1998 fprintf (dump_file, "brought back: ");
1999 omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
2000 fprintf (dump_file, "\n");
2003 pb->num_eqs++;
2004 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2007 pb->safe_vars += m;
2008 pb->num_subs = 0;
2010 if (dump_file && (dump_flags & TDF_DETAILS))
2012 fprintf (dump_file, "variables brought back to life\n");
2013 omega_print_problem (dump_file, pb);
2016 cleanout_wildcards (pb);
2020 static inline bool
2021 implies (unsigned int a, unsigned int b)
2023 return (a == (a & b));
2026 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2027 extra step is performed. Returns omega_false when there exist no
2028 solution, omega_true otherwise. */
2030 enum omega_result
2031 omega_eliminate_redundant (omega_pb pb, bool expensive)
2033 int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
2034 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2035 omega_pb tmp_problem;
2037 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2038 unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2039 unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2040 unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2042 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2043 unsigned int pp, pz, pn;
2045 if (dump_file && (dump_flags & TDF_DETAILS))
2047 fprintf (dump_file, "in eliminate Redundant:\n");
2048 omega_print_problem (dump_file, pb);
2051 for (e = pb->num_geqs - 1; e >= 0; e--)
2053 int tmp = 1;
2055 is_dead[e] = false;
2056 peqs[e] = zeqs[e] = neqs[e] = 0;
2058 for (i = pb->num_vars; i >= 1; i--)
2060 if (pb->geqs[e].coef[i] > 0)
2061 peqs[e] |= tmp;
2062 else if (pb->geqs[e].coef[i] < 0)
2063 neqs[e] |= tmp;
2064 else
2065 zeqs[e] |= tmp;
2067 tmp <<= 1;
2072 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2073 if (!is_dead[e1])
2074 for (e2 = e1 - 1; e2 >= 0; e2--)
2075 if (!is_dead[e2])
2077 for (p = pb->num_vars; p > 1; p--)
2078 for (q = p - 1; q > 0; q--)
2079 if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
2080 - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
2081 goto foundPQ;
2083 continue;
2085 foundPQ:
2086 pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
2087 | (neqs[e1] & peqs[e2]));
2088 pp = peqs[e1] | peqs[e2];
2089 pn = neqs[e1] | neqs[e2];
2091 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2092 if (e3 != e1 && e3 != e2)
2094 if (!implies (zeqs[e3], pz))
2095 goto nextE3;
2097 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2098 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2099 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2100 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2101 alpha3 = alpha;
2103 if (alpha1 * alpha2 <= 0)
2104 goto nextE3;
2106 if (alpha1 < 0)
2108 alpha1 = -alpha1;
2109 alpha2 = -alpha2;
2110 alpha3 = -alpha3;
2113 if (alpha3 > 0)
2115 /* Trying to prove e3 is redundant. */
2116 if (!implies (peqs[e3], pp)
2117 || !implies (neqs[e3], pn))
2118 goto nextE3;
2120 if (pb->geqs[e3].color == omega_black
2121 && (pb->geqs[e1].color == omega_red
2122 || pb->geqs[e2].color == omega_red))
2123 goto nextE3;
2125 for (k = pb->num_vars; k >= 1; k--)
2126 if (alpha3 * pb->geqs[e3].coef[k]
2127 != (alpha1 * pb->geqs[e1].coef[k]
2128 + alpha2 * pb->geqs[e2].coef[k]))
2129 goto nextE3;
2131 c = (alpha1 * pb->geqs[e1].coef[0]
2132 + alpha2 * pb->geqs[e2].coef[0]);
2134 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2136 if (dump_file && (dump_flags & TDF_DETAILS))
2138 fprintf (dump_file,
2139 "found redundant inequality\n");
2140 fprintf (dump_file,
2141 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2142 alpha1, alpha2, alpha3);
2144 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2145 fprintf (dump_file, "\n");
2146 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2147 fprintf (dump_file, "\n=> ");
2148 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2149 fprintf (dump_file, "\n\n");
2152 is_dead[e3] = true;
2155 else
2157 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2158 or trying to prove e3 < 0, and therefore the
2159 problem has no solutions. */
2160 if (!implies (peqs[e3], pn)
2161 || !implies (neqs[e3], pp))
2162 goto nextE3;
2164 if (pb->geqs[e1].color == omega_red
2165 || pb->geqs[e2].color == omega_red
2166 || pb->geqs[e3].color == omega_red)
2167 goto nextE3;
2169 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2170 for (k = pb->num_vars; k >= 1; k--)
2171 if (alpha3 * pb->geqs[e3].coef[k]
2172 != (alpha1 * pb->geqs[e1].coef[k]
2173 + alpha2 * pb->geqs[e2].coef[k]))
2174 goto nextE3;
2176 c = (alpha1 * pb->geqs[e1].coef[0]
2177 + alpha2 * pb->geqs[e2].coef[0]);
2179 if (c < alpha3 * (pb->geqs[e3].coef[0]))
2181 /* We just proved e3 < 0, so no solutions exist. */
2182 if (dump_file && (dump_flags & TDF_DETAILS))
2184 fprintf (dump_file,
2185 "found implied over tight inequality\n");
2186 fprintf (dump_file,
2187 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2188 alpha1, alpha2, -alpha3);
2189 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2190 fprintf (dump_file, "\n");
2191 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2192 fprintf (dump_file, "\n=> not ");
2193 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2194 fprintf (dump_file, "\n\n");
2196 free (is_dead);
2197 free (peqs);
2198 free (zeqs);
2199 free (neqs);
2200 return omega_false;
2202 else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2204 /* We just proved that e3 <=0, so e3 = 0. */
2205 if (dump_file && (dump_flags & TDF_DETAILS))
2207 fprintf (dump_file,
2208 "found implied tight inequality\n");
2209 fprintf (dump_file,
2210 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2211 alpha1, alpha2, -alpha3);
2212 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2213 fprintf (dump_file, "\n");
2214 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2215 fprintf (dump_file, "\n=> inverse ");
2216 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2217 fprintf (dump_file, "\n\n");
2220 omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2221 &pb->geqs[e3], pb->num_vars);
2222 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2223 adding_equality_constraint (pb, pb->num_eqs - 1);
2224 is_dead[e3] = true;
2227 nextE3:;
2231 /* Delete the inequalities that were marked as dead. */
2232 for (e = pb->num_geqs - 1; e >= 0; e--)
2233 if (is_dead[e])
2234 omega_delete_geq (pb, e, pb->num_vars);
2236 if (!expensive)
2237 goto eliminate_redundant_done;
2239 tmp_problem = XNEW (struct omega_pb_d);
2240 conservative++;
2242 for (e = pb->num_geqs - 1; e >= 0; e--)
2244 if (dump_file && (dump_flags & TDF_DETAILS))
2246 fprintf (dump_file,
2247 "checking equation %d to see if it is redundant: ", e);
2248 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2249 fprintf (dump_file, "\n");
2252 omega_copy_problem (tmp_problem, pb);
2253 omega_negate_geq (tmp_problem, e);
2254 tmp_problem->safe_vars = 0;
2255 tmp_problem->variables_freed = false;
2257 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2258 omega_delete_geq (pb, e, pb->num_vars);
2261 free (tmp_problem);
2262 conservative--;
2264 if (!omega_reduce_with_subs)
2266 resurrect_subs (pb);
2267 gcc_assert (please_no_equalities_in_simplified_problems
2268 || pb->num_subs == 0);
2271 eliminate_redundant_done:
2272 free (is_dead);
2273 free (peqs);
2274 free (zeqs);
2275 free (neqs);
2276 return omega_true;
2279 /* For each inequality that has coefficients bigger than 20, try to
2280 create a new constraint that cannot be derived from the original
2281 constraint and that has smaller coefficients. Add the new
2282 constraint at the end of geqs. Return the number of inequalities
2283 that have been added to PB. */
2285 static int
2286 smooth_weird_equations (omega_pb pb)
2288 int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2289 int c;
2290 int v;
2291 int result = 0;
2293 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2294 if (pb->geqs[e1].color == omega_black)
2296 int g = 999999;
2298 for (v = pb->num_vars; v >= 1; v--)
2299 if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2300 g = abs (pb->geqs[e1].coef[v]);
2302 /* Magic number. */
2303 if (g > 20)
2305 e3 = pb->num_geqs;
2307 for (v = pb->num_vars; v >= 1; v--)
2308 pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2311 pb->geqs[e3].color = omega_black;
2312 pb->geqs[e3].touched = 1;
2313 /* Magic number. */
2314 pb->geqs[e3].coef[0] = 9997;
2316 if (dump_file && (dump_flags & TDF_DETAILS))
2318 fprintf (dump_file, "Checking to see if we can derive: ");
2319 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2320 fprintf (dump_file, "\n from: ");
2321 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2322 fprintf (dump_file, "\n");
2325 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2326 if (e1 != e2 && pb->geqs[e2].color == omega_black)
2328 for (p = pb->num_vars; p > 1; p--)
2330 for (q = p - 1; q > 0; q--)
2332 alpha =
2333 (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2334 pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2335 if (alpha != 0)
2336 goto foundPQ;
2339 continue;
2341 foundPQ:
2343 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2344 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2345 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2346 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2347 alpha3 = alpha;
2349 if (alpha1 * alpha2 <= 0)
2350 continue;
2352 if (alpha1 < 0)
2354 alpha1 = -alpha1;
2355 alpha2 = -alpha2;
2356 alpha3 = -alpha3;
2359 if (alpha3 > 0)
2361 /* Try to prove e3 is redundant: verify
2362 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2363 for (k = pb->num_vars; k >= 1; k--)
2364 if (alpha3 * pb->geqs[e3].coef[k]
2365 != (alpha1 * pb->geqs[e1].coef[k]
2366 + alpha2 * pb->geqs[e2].coef[k]))
2367 goto nextE2;
2369 c = alpha1 * pb->geqs[e1].coef[0]
2370 + alpha2 * pb->geqs[e2].coef[0];
2372 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2373 pb->geqs[e3].coef[0] = int_div (c, alpha3);
2375 nextE2:;
2378 if (pb->geqs[e3].coef[0] < 9997)
2380 result++;
2381 pb->num_geqs++;
2383 if (dump_file && (dump_flags & TDF_DETAILS))
2385 fprintf (dump_file,
2386 "Smoothing weird equations; adding:\n");
2387 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2388 fprintf (dump_file, "\nto:\n");
2389 omega_print_problem (dump_file, pb);
2390 fprintf (dump_file, "\n\n");
2395 return result;
2398 /* Replace tuples of inequalities, that define upper and lower half
2399 spaces, with an equation. */
2401 static void
2402 coalesce (omega_pb pb)
2404 int e, e2;
2405 int colors = 0;
2406 bool *is_dead;
2407 int found_something = 0;
2409 for (e = 0; e < pb->num_geqs; e++)
2410 if (pb->geqs[e].color == omega_red)
2411 colors++;
2413 if (colors < 2)
2414 return;
2416 is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2418 for (e = 0; e < pb->num_geqs; e++)
2419 is_dead[e] = false;
2421 for (e = 0; e < pb->num_geqs; e++)
2422 if (pb->geqs[e].color == omega_red
2423 && !pb->geqs[e].touched)
2424 for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2425 if (!pb->geqs[e2].touched
2426 && pb->geqs[e].key == -pb->geqs[e2].key
2427 && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2428 && pb->geqs[e2].color == omega_red)
2430 omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2431 pb->num_vars);
2432 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2433 found_something++;
2434 is_dead[e] = true;
2435 is_dead[e2] = true;
2438 for (e = pb->num_geqs - 1; e >= 0; e--)
2439 if (is_dead[e])
2440 omega_delete_geq (pb, e, pb->num_vars);
2442 if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2444 fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2445 found_something);
2446 omega_print_problem (dump_file, pb);
2449 free (is_dead);
2452 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2453 true, continue to eliminate all the red inequalities. */
2455 void
2456 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2458 int e, e2, e3, i, j, k, a, alpha1, alpha2;
2459 int c = 0;
2460 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2461 int dead_count = 0;
2462 int red_found;
2463 omega_pb tmp_problem;
2465 if (dump_file && (dump_flags & TDF_DETAILS))
2467 fprintf (dump_file, "in eliminate RED:\n");
2468 omega_print_problem (dump_file, pb);
2471 if (pb->num_eqs > 0)
2472 omega_simplify_problem (pb);
2474 for (e = pb->num_geqs - 1; e >= 0; e--)
2475 is_dead[e] = false;
2477 for (e = pb->num_geqs - 1; e >= 0; e--)
2478 if (pb->geqs[e].color == omega_black && !is_dead[e])
2479 for (e2 = e - 1; e2 >= 0; e2--)
2480 if (pb->geqs[e2].color == omega_black
2481 && !is_dead[e2])
2483 a = 0;
2485 for (i = pb->num_vars; i > 1; i--)
2486 for (j = i - 1; j > 0; j--)
2487 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2488 - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2489 goto found_pair;
2491 continue;
2493 found_pair:
2494 if (dump_file && (dump_flags & TDF_DETAILS))
2496 fprintf (dump_file,
2497 "found two equations to combine, i = %s, ",
2498 omega_variable_to_str (pb, i));
2499 fprintf (dump_file, "j = %s, alpha = %d\n",
2500 omega_variable_to_str (pb, j), a);
2501 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2502 fprintf (dump_file, "\n");
2503 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2504 fprintf (dump_file, "\n");
2507 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2508 if (pb->geqs[e3].color == omega_red)
2510 alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2511 - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2512 alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2513 - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2515 if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2516 || (a < 0 && alpha1 < 0 && alpha2 < 0))
2518 if (dump_file && (dump_flags & TDF_DETAILS))
2520 fprintf (dump_file,
2521 "alpha1 = %d, alpha2 = %d;"
2522 "comparing against: ",
2523 alpha1, alpha2);
2524 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2525 fprintf (dump_file, "\n");
2528 for (k = pb->num_vars; k >= 0; k--)
2530 c = (alpha1 * pb->geqs[e].coef[k]
2531 + alpha2 * pb->geqs[e2].coef[k]);
2533 if (c != a * pb->geqs[e3].coef[k])
2534 break;
2536 if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2537 fprintf (dump_file, " %s: %d, %d\n",
2538 omega_variable_to_str (pb, k), c,
2539 a * pb->geqs[e3].coef[k]);
2542 if (k < 0
2543 || (k == 0 &&
2544 ((a > 0 && c < a * pb->geqs[e3].coef[k])
2545 || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2547 if (dump_file && (dump_flags & TDF_DETAILS))
2549 dead_count++;
2550 fprintf (dump_file,
2551 "red equation#%d is dead "
2552 "(%d dead so far, %d remain)\n",
2553 e3, dead_count,
2554 pb->num_geqs - dead_count);
2555 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2556 fprintf (dump_file, "\n");
2557 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2558 fprintf (dump_file, "\n");
2559 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2560 fprintf (dump_file, "\n");
2562 is_dead[e3] = true;
2568 for (e = pb->num_geqs - 1; e >= 0; e--)
2569 if (is_dead[e])
2570 omega_delete_geq (pb, e, pb->num_vars);
2572 free (is_dead);
2574 if (dump_file && (dump_flags & TDF_DETAILS))
2576 fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2577 omega_print_problem (dump_file, pb);
2580 for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2581 if (pb->geqs[e].color == omega_red)
2583 red_found = 1;
2584 break;
2587 if (!red_found)
2589 if (dump_file && (dump_flags & TDF_DETAILS))
2590 fprintf (dump_file, "fast checks worked\n");
2592 if (!omega_reduce_with_subs)
2593 gcc_assert (please_no_equalities_in_simplified_problems
2594 || pb->num_subs == 0);
2596 return;
2599 if (!omega_verify_simplification
2600 && verify_omega_pb (pb) == omega_false)
2601 return;
2603 conservative++;
2604 tmp_problem = XNEW (struct omega_pb_d);
2606 for (e = pb->num_geqs - 1; e >= 0; e--)
2607 if (pb->geqs[e].color == omega_red)
2609 if (dump_file && (dump_flags & TDF_DETAILS))
2611 fprintf (dump_file,
2612 "checking equation %d to see if it is redundant: ", e);
2613 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2614 fprintf (dump_file, "\n");
2617 omega_copy_problem (tmp_problem, pb);
2618 omega_negate_geq (tmp_problem, e);
2619 tmp_problem->safe_vars = 0;
2620 tmp_problem->variables_freed = false;
2621 tmp_problem->num_subs = 0;
2623 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2625 if (dump_file && (dump_flags & TDF_DETAILS))
2626 fprintf (dump_file, "it is redundant\n");
2627 omega_delete_geq (pb, e, pb->num_vars);
2629 else
2631 if (dump_file && (dump_flags & TDF_DETAILS))
2632 fprintf (dump_file, "it is not redundant\n");
2634 if (!eliminate_all)
2636 if (dump_file && (dump_flags & TDF_DETAILS))
2637 fprintf (dump_file, "no need to check other red equations\n");
2638 break;
2643 conservative--;
2644 free (tmp_problem);
2645 /* omega_simplify_problem (pb); */
2647 if (!omega_reduce_with_subs)
2648 gcc_assert (please_no_equalities_in_simplified_problems
2649 || pb->num_subs == 0);
2652 /* Transform some wildcard variables to non-safe variables. */
2654 static void
2655 chain_unprotect (omega_pb pb)
2657 int i, e;
2658 bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2660 for (i = 1; omega_safe_var_p (pb, i); i++)
2662 unprotect[i] = omega_wildcard_p (pb, i);
2664 for (e = pb->num_subs - 1; e >= 0; e--)
2665 if (pb->subs[e].coef[i])
2666 unprotect[i] = false;
2669 if (dump_file && (dump_flags & TDF_DETAILS))
2671 fprintf (dump_file, "Doing chain reaction unprotection\n");
2672 omega_print_problem (dump_file, pb);
2674 for (i = 1; omega_safe_var_p (pb, i); i++)
2675 if (unprotect[i])
2676 fprintf (dump_file, "unprotecting %s\n",
2677 omega_variable_to_str (pb, i));
2680 for (i = 1; omega_safe_var_p (pb, i); i++)
2681 if (unprotect[i])
2682 omega_unprotect_1 (pb, &i, unprotect);
2684 if (dump_file && (dump_flags & TDF_DETAILS))
2686 fprintf (dump_file, "After chain reactions\n");
2687 omega_print_problem (dump_file, pb);
2690 free (unprotect);
2693 /* Reduce problem PB. */
2695 static void
2696 omega_problem_reduced (omega_pb pb)
2698 if (omega_verify_simplification
2699 && !in_approximate_mode
2700 && verify_omega_pb (pb) == omega_false)
2701 return;
2703 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2704 && !omega_eliminate_redundant (pb, true))
2705 return;
2707 omega_found_reduction = omega_true;
2709 if (!please_no_equalities_in_simplified_problems)
2710 coalesce (pb);
2712 if (omega_reduce_with_subs
2713 || please_no_equalities_in_simplified_problems)
2714 chain_unprotect (pb);
2715 else
2716 resurrect_subs (pb);
2718 if (!return_single_result)
2720 int i;
2722 for (i = 1; omega_safe_var_p (pb, i); i++)
2723 pb->forwarding_address[pb->var[i]] = i;
2725 for (i = 0; i < pb->num_subs; i++)
2726 pb->forwarding_address[pb->subs[i].key] = -i - 1;
2728 (*omega_when_reduced) (pb);
2731 if (dump_file && (dump_flags & TDF_DETAILS))
2733 fprintf (dump_file, "-------------------------------------------\n");
2734 fprintf (dump_file, "problem reduced:\n");
2735 omega_print_problem (dump_file, pb);
2736 fprintf (dump_file, "-------------------------------------------\n");
2740 /* Eliminates all the free variables for problem PB, that is all the
2741 variables from FV to PB->NUM_VARS. */
2743 static void
2744 omega_free_eliminations (omega_pb pb, int fv)
2746 bool try_again = true;
2747 int i, e, e2;
2748 int n_vars = pb->num_vars;
2750 while (try_again)
2752 try_again = false;
2754 for (i = n_vars; i > fv; i--)
2756 for (e = pb->num_geqs - 1; e >= 0; e--)
2757 if (pb->geqs[e].coef[i])
2758 break;
2760 if (e < 0)
2761 e2 = e;
2762 else if (pb->geqs[e].coef[i] > 0)
2764 for (e2 = e - 1; e2 >= 0; e2--)
2765 if (pb->geqs[e2].coef[i] < 0)
2766 break;
2768 else
2770 for (e2 = e - 1; e2 >= 0; e2--)
2771 if (pb->geqs[e2].coef[i] > 0)
2772 break;
2775 if (e2 < 0)
2777 int e3;
2778 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2779 if (pb->subs[e3].coef[i])
2780 break;
2782 if (e3 >= 0)
2783 continue;
2785 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2786 if (pb->eqs[e3].coef[i])
2787 break;
2789 if (e3 >= 0)
2790 continue;
2792 if (dump_file && (dump_flags & TDF_DETAILS))
2793 fprintf (dump_file, "a free elimination of %s\n",
2794 omega_variable_to_str (pb, i));
2796 if (e >= 0)
2798 omega_delete_geq (pb, e, n_vars);
2800 for (e--; e >= 0; e--)
2801 if (pb->geqs[e].coef[i])
2802 omega_delete_geq (pb, e, n_vars);
2804 try_again = (i < n_vars);
2807 omega_delete_variable (pb, i);
2808 n_vars = pb->num_vars;
2813 if (dump_file && (dump_flags & TDF_DETAILS))
2815 fprintf (dump_file, "\nafter free eliminations:\n");
2816 omega_print_problem (dump_file, pb);
2817 fprintf (dump_file, "\n");
2821 /* Do free red eliminations. */
2823 static void
2824 free_red_eliminations (omega_pb pb)
2826 bool try_again = true;
2827 int i, e, e2;
2828 int n_vars = pb->num_vars;
2829 bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2830 bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2831 bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2833 for (i = n_vars; i > 0; i--)
2835 is_red_var[i] = false;
2836 is_dead_var[i] = false;
2839 for (e = pb->num_geqs - 1; e >= 0; e--)
2841 is_dead_geq[e] = false;
2843 if (pb->geqs[e].color == omega_red)
2844 for (i = n_vars; i > 0; i--)
2845 if (pb->geqs[e].coef[i] != 0)
2846 is_red_var[i] = true;
2849 while (try_again)
2851 try_again = false;
2852 for (i = n_vars; i > 0; i--)
2853 if (!is_red_var[i] && !is_dead_var[i])
2855 for (e = pb->num_geqs - 1; e >= 0; e--)
2856 if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2857 break;
2859 if (e < 0)
2860 e2 = e;
2861 else if (pb->geqs[e].coef[i] > 0)
2863 for (e2 = e - 1; e2 >= 0; e2--)
2864 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2865 break;
2867 else
2869 for (e2 = e - 1; e2 >= 0; e2--)
2870 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2871 break;
2874 if (e2 < 0)
2876 int e3;
2877 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2878 if (pb->subs[e3].coef[i])
2879 break;
2881 if (e3 >= 0)
2882 continue;
2884 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2885 if (pb->eqs[e3].coef[i])
2886 break;
2888 if (e3 >= 0)
2889 continue;
2891 if (dump_file && (dump_flags & TDF_DETAILS))
2892 fprintf (dump_file, "a free red elimination of %s\n",
2893 omega_variable_to_str (pb, i));
2895 for (; e >= 0; e--)
2896 if (pb->geqs[e].coef[i])
2897 is_dead_geq[e] = true;
2899 try_again = true;
2900 is_dead_var[i] = true;
2905 for (e = pb->num_geqs - 1; e >= 0; e--)
2906 if (is_dead_geq[e])
2907 omega_delete_geq (pb, e, n_vars);
2909 for (i = n_vars; i > 0; i--)
2910 if (is_dead_var[i])
2911 omega_delete_variable (pb, i);
2913 if (dump_file && (dump_flags & TDF_DETAILS))
2915 fprintf (dump_file, "\nafter free red eliminations:\n");
2916 omega_print_problem (dump_file, pb);
2917 fprintf (dump_file, "\n");
2920 free (is_red_var);
2921 free (is_dead_var);
2922 free (is_dead_geq);
2925 /* For equation EQ of the form "0 = EQN", insert in PB two
2926 inequalities "0 <= EQN" and "0 <= -EQN". */
2928 void
2929 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2931 int i;
2933 if (dump_file && (dump_flags & TDF_DETAILS))
2934 fprintf (dump_file, "Converting Eq to Geqs\n");
2936 /* Insert "0 <= EQN". */
2937 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2938 pb->geqs[pb->num_geqs].touched = 1;
2939 pb->num_geqs++;
2941 /* Insert "0 <= -EQN". */
2942 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2943 pb->geqs[pb->num_geqs].touched = 1;
2945 for (i = 0; i <= pb->num_vars; i++)
2946 pb->geqs[pb->num_geqs].coef[i] *= -1;
2948 pb->num_geqs++;
2950 if (dump_file && (dump_flags & TDF_DETAILS))
2951 omega_print_problem (dump_file, pb);
2954 /* Eliminates variable I from PB. */
2956 static void
2957 omega_do_elimination (omega_pb pb, int e, int i)
2959 eqn sub = omega_alloc_eqns (0, 1);
2960 int c;
2961 int n_vars = pb->num_vars;
2963 if (dump_file && (dump_flags & TDF_DETAILS))
2964 fprintf (dump_file, "eliminating variable %s\n",
2965 omega_variable_to_str (pb, i));
2967 omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
2968 c = sub->coef[i];
2969 sub->coef[i] = 0;
2970 if (c == 1 || c == -1)
2972 if (pb->eqs[e].color == omega_red)
2974 bool fB;
2975 omega_substitute_red (pb, sub, i, c, &fB);
2976 if (fB)
2977 omega_convert_eq_to_geqs (pb, e);
2978 else
2979 omega_delete_variable (pb, i);
2981 else
2983 omega_substitute (pb, sub, i, c);
2984 omega_delete_variable (pb, i);
2987 else
2989 int a = abs (c);
2990 int e2 = e;
2992 if (dump_file && (dump_flags & TDF_DETAILS))
2993 fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
2995 for (e = pb->num_eqs - 1; e >= 0; e--)
2996 if (pb->eqs[e].coef[i])
2998 eqn eqn = &(pb->eqs[e]);
2999 int j, k;
3000 for (j = n_vars; j >= 0; j--)
3001 eqn->coef[j] *= a;
3002 k = eqn->coef[i];
3003 eqn->coef[i] = 0;
3004 if (sub->color == omega_red)
3005 eqn->color = omega_red;
3006 for (j = n_vars; j >= 0; j--)
3007 eqn->coef[j] -= sub->coef[j] * k / c;
3010 for (e = pb->num_geqs - 1; e >= 0; e--)
3011 if (pb->geqs[e].coef[i])
3013 eqn eqn = &(pb->geqs[e]);
3014 int j, k;
3016 if (sub->color == omega_red)
3017 eqn->color = omega_red;
3019 for (j = n_vars; j >= 0; j--)
3020 eqn->coef[j] *= a;
3022 eqn->touched = 1;
3023 k = eqn->coef[i];
3024 eqn->coef[i] = 0;
3026 for (j = n_vars; j >= 0; j--)
3027 eqn->coef[j] -= sub->coef[j] * k / c;
3031 for (e = pb->num_subs - 1; e >= 0; e--)
3032 if (pb->subs[e].coef[i])
3034 eqn eqn = &(pb->subs[e]);
3035 int j, k;
3036 gcc_assert (0);
3037 gcc_assert (sub->color == omega_black);
3038 for (j = n_vars; j >= 0; j--)
3039 eqn->coef[j] *= a;
3040 k = eqn->coef[i];
3041 eqn->coef[i] = 0;
3042 for (j = n_vars; j >= 0; j--)
3043 eqn->coef[j] -= sub->coef[j] * k / c;
3046 if (in_approximate_mode)
3047 omega_delete_variable (pb, i);
3048 else
3049 omega_convert_eq_to_geqs (pb, e2);
3052 omega_free_eqns (sub, 1);
3055 /* Helper function for printing "sorry, no solution". */
3057 static inline enum omega_result
3058 omega_problem_has_no_solution (void)
3060 if (dump_file && (dump_flags & TDF_DETAILS))
3061 fprintf (dump_file, "\nequations have no solution \n");
3063 return omega_false;
3066 /* Helper function: solve equations in PB one at a time, following the
3067 DESIRED_RES result. */
3069 static enum omega_result
3070 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3072 int i, j, e;
3073 int g, g2;
3074 g = 0;
3077 if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3079 fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3080 desired_res, may_be_red);
3081 omega_print_problem (dump_file, pb);
3082 fprintf (dump_file, "\n");
3085 if (may_be_red)
3087 i = 0;
3088 j = pb->num_eqs - 1;
3090 while (1)
3092 eqn eq;
3094 while (i <= j && pb->eqs[i].color == omega_red)
3095 i++;
3097 while (i <= j && pb->eqs[j].color == omega_black)
3098 j--;
3100 if (i >= j)
3101 break;
3103 eq = omega_alloc_eqns (0, 1);
3104 omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3105 omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3106 omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3107 omega_free_eqns (eq, 1);
3108 i++;
3109 j--;
3113 /* Eliminate all EQ equations */
3114 for (e = pb->num_eqs - 1; e >= 0; e--)
3116 eqn eqn = &(pb->eqs[e]);
3117 int sv;
3119 if (dump_file && (dump_flags & TDF_DETAILS))
3120 fprintf (dump_file, "----\n");
3122 for (i = pb->num_vars; i > 0; i--)
3123 if (eqn->coef[i])
3124 break;
3126 g = eqn->coef[i];
3128 for (j = i - 1; j > 0; j--)
3129 if (eqn->coef[j])
3130 break;
3132 /* i is the position of last nonzero coefficient,
3133 g is the coefficient of i,
3134 j is the position of next nonzero coefficient. */
3136 if (j == 0)
3138 if (eqn->coef[0] % g != 0)
3139 return omega_problem_has_no_solution ();
3141 eqn->coef[0] = eqn->coef[0] / g;
3142 eqn->coef[i] = 1;
3143 pb->num_eqs--;
3144 omega_do_elimination (pb, e, i);
3145 continue;
3148 else if (j == -1)
3150 if (eqn->coef[0] != 0)
3151 return omega_problem_has_no_solution ();
3153 pb->num_eqs--;
3154 continue;
3157 if (g < 0)
3158 g = -g;
3160 if (g == 1)
3162 pb->num_eqs--;
3163 omega_do_elimination (pb, e, i);
3166 else
3168 int k = j;
3169 bool promotion_possible =
3170 (omega_safe_var_p (pb, j)
3171 && pb->safe_vars + 1 == i
3172 && !omega_eqn_is_red (eqn, desired_res)
3173 && !in_approximate_mode);
3175 if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3176 fprintf (dump_file, " Promotion possible\n");
3178 normalizeEQ:
3179 if (!omega_safe_var_p (pb, j))
3181 for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3182 g = gcd (abs (eqn->coef[j]), g);
3183 g2 = g;
3185 else if (!omega_safe_var_p (pb, i))
3186 g2 = g;
3187 else
3188 g2 = 0;
3190 for (; g != 1 && j > 0; j--)
3191 g = gcd (abs (eqn->coef[j]), g);
3193 if (g > 1)
3195 if (eqn->coef[0] % g != 0)
3196 return omega_problem_has_no_solution ();
3198 for (j = 0; j <= pb->num_vars; j++)
3199 eqn->coef[j] /= g;
3201 g2 = g2 / g;
3204 if (g2 > 1)
3206 int e2;
3208 for (e2 = e - 1; e2 >= 0; e2--)
3209 if (pb->eqs[e2].coef[i])
3210 break;
3212 if (e2 == -1)
3213 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3214 if (pb->geqs[e2].coef[i])
3215 break;
3217 if (e2 == -1)
3218 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3219 if (pb->subs[e2].coef[i])
3220 break;
3222 if (e2 == -1)
3224 bool change = false;
3226 if (dump_file && (dump_flags & TDF_DETAILS))
3228 fprintf (dump_file, "Ha! We own it! \n");
3229 omega_print_eq (dump_file, pb, eqn);
3230 fprintf (dump_file, " \n");
3233 g = eqn->coef[i];
3234 g = abs (g);
3236 for (j = i - 1; j >= 0; j--)
3238 int t = int_mod (eqn->coef[j], g);
3240 if (2 * t >= g)
3241 t -= g;
3243 if (t != eqn->coef[j])
3245 eqn->coef[j] = t;
3246 change = true;
3250 if (!change)
3252 if (dump_file && (dump_flags & TDF_DETAILS))
3253 fprintf (dump_file, "So what?\n");
3256 else
3258 omega_name_wild_card (pb, i);
3260 if (dump_file && (dump_flags & TDF_DETAILS))
3262 omega_print_eq (dump_file, pb, eqn);
3263 fprintf (dump_file, " \n");
3266 e++;
3267 continue;
3272 if (promotion_possible)
3274 if (dump_file && (dump_flags & TDF_DETAILS))
3276 fprintf (dump_file, "promoting %s to safety\n",
3277 omega_variable_to_str (pb, i));
3278 omega_print_vars (dump_file, pb);
3281 pb->safe_vars++;
3283 if (!omega_wildcard_p (pb, i))
3284 omega_name_wild_card (pb, i);
3286 promotion_possible = false;
3287 j = k;
3288 goto normalizeEQ;
3291 if (g2 > 1 && !in_approximate_mode)
3293 if (pb->eqs[e].color == omega_red)
3295 if (dump_file && (dump_flags & TDF_DETAILS))
3296 fprintf (dump_file, "handling red equality\n");
3298 pb->num_eqs--;
3299 omega_do_elimination (pb, e, i);
3300 continue;
3303 if (dump_file && (dump_flags & TDF_DETAILS))
3305 fprintf (dump_file,
3306 "adding equation to handle safe variable \n");
3307 omega_print_eq (dump_file, pb, eqn);
3308 fprintf (dump_file, "\n----\n");
3309 omega_print_problem (dump_file, pb);
3310 fprintf (dump_file, "\n----\n");
3311 fprintf (dump_file, "\n----\n");
3314 i = omega_add_new_wild_card (pb);
3315 pb->num_eqs++;
3316 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3317 omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3318 omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3320 for (j = pb->num_vars; j >= 0; j--)
3322 pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3324 if (2 * pb->eqs[e + 1].coef[j] >= g2)
3325 pb->eqs[e + 1].coef[j] -= g2;
3328 pb->eqs[e + 1].coef[i] = g2;
3329 e += 2;
3331 if (dump_file && (dump_flags & TDF_DETAILS))
3332 omega_print_problem (dump_file, pb);
3334 continue;
3337 sv = pb->safe_vars;
3338 if (g2 == 0)
3339 sv = 0;
3341 /* Find variable to eliminate. */
3342 if (g2 > 1)
3344 gcc_assert (in_approximate_mode);
3346 if (dump_file && (dump_flags & TDF_DETAILS))
3348 fprintf (dump_file, "non-exact elimination: ");
3349 omega_print_eq (dump_file, pb, eqn);
3350 fprintf (dump_file, "\n");
3351 omega_print_problem (dump_file, pb);
3354 for (i = pb->num_vars; i > sv; i--)
3355 if (pb->eqs[e].coef[i] != 0)
3356 break;
3358 else
3359 for (i = pb->num_vars; i > sv; i--)
3360 if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3361 break;
3363 if (i > sv)
3365 pb->num_eqs--;
3366 omega_do_elimination (pb, e, i);
3368 if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3370 fprintf (dump_file, "result of non-exact elimination:\n");
3371 omega_print_problem (dump_file, pb);
3374 else
3376 int factor = (INT_MAX);
3377 j = 0;
3379 if (dump_file && (dump_flags & TDF_DETAILS))
3380 fprintf (dump_file, "doing moding\n");
3382 for (i = pb->num_vars; i != sv; i--)
3383 if ((pb->eqs[e].coef[i] & 1) != 0)
3385 j = i;
3386 i--;
3388 for (; i != sv; i--)
3389 if ((pb->eqs[e].coef[i] & 1) != 0)
3390 break;
3392 break;
3395 if (j != 0 && i == sv)
3397 omega_do_mod (pb, 2, e, j);
3398 e++;
3399 continue;
3402 j = 0;
3403 for (i = pb->num_vars; i != sv; i--)
3404 if (pb->eqs[e].coef[i] != 0
3405 && factor > abs (pb->eqs[e].coef[i]) + 1)
3407 factor = abs (pb->eqs[e].coef[i]) + 1;
3408 j = i;
3411 if (j == sv)
3413 if (dump_file && (dump_flags & TDF_DETAILS))
3414 fprintf (dump_file, "should not have happened\n");
3415 gcc_assert (0);
3418 omega_do_mod (pb, factor, e, j);
3419 /* Go back and try this equation again. */
3420 e++;
3425 pb->num_eqs = 0;
3426 return omega_unknown;
3429 /* Transform an inequation E to an equality, then solve DIFF problems
3430 based on PB, and only differing by the constant part that is
3431 diminished by one, trying to figure out which of the constants
3432 satisfies PB. */
3434 static enum omega_result
3435 parallel_splinter (omega_pb pb, int e, int diff,
3436 enum omega_result desired_res)
3438 omega_pb tmp_problem;
3439 int i;
3441 if (dump_file && (dump_flags & TDF_DETAILS))
3443 fprintf (dump_file, "Using parallel splintering\n");
3444 omega_print_problem (dump_file, pb);
3447 tmp_problem = XNEW (struct omega_pb_d);
3448 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3449 pb->num_eqs = 1;
3451 for (i = 0; i <= diff; i++)
3453 omega_copy_problem (tmp_problem, pb);
3455 if (dump_file && (dump_flags & TDF_DETAILS))
3457 fprintf (dump_file, "Splinter # %i\n", i);
3458 omega_print_problem (dump_file, pb);
3461 if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3463 free (tmp_problem);
3464 return omega_true;
3467 pb->eqs[0].coef[0]--;
3470 free (tmp_problem);
3471 return omega_false;
3474 /* Helper function: solve equations one at a time. */
3476 static enum omega_result
3477 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3479 int i, e;
3480 int n_vars, fv;
3481 enum omega_result result;
3482 bool coupled_subscripts = false;
3483 bool smoothed = false;
3484 bool eliminate_again;
3485 bool tried_eliminating_redundant = false;
3487 if (desired_res != omega_simplify)
3489 pb->num_subs = 0;
3490 pb->safe_vars = 0;
3493 solve_geq_start:
3494 do {
3495 gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3497 /* Verify that there are not too many inequalities. */
3498 gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3500 if (dump_file && (dump_flags & TDF_DETAILS))
3502 fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3503 desired_res, please_no_equalities_in_simplified_problems);
3504 omega_print_problem (dump_file, pb);
3505 fprintf (dump_file, "\n");
3508 n_vars = pb->num_vars;
3510 if (n_vars == 1)
3512 enum omega_eqn_color u_color = omega_black;
3513 enum omega_eqn_color l_color = omega_black;
3514 int upper_bound = pos_infinity;
3515 int lower_bound = neg_infinity;
3517 for (e = pb->num_geqs - 1; e >= 0; e--)
3519 int a = pb->geqs[e].coef[1];
3520 int c = pb->geqs[e].coef[0];
3522 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3523 if (a == 0)
3525 if (c < 0)
3526 return omega_problem_has_no_solution ();
3528 else if (a > 0)
3530 if (a != 1)
3531 c = int_div (c, a);
3533 if (lower_bound < -c
3534 || (lower_bound == -c
3535 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3537 lower_bound = -c;
3538 l_color = pb->geqs[e].color;
3541 else
3543 if (a != -1)
3544 c = int_div (c, -a);
3546 if (upper_bound > c
3547 || (upper_bound == c
3548 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3550 upper_bound = c;
3551 u_color = pb->geqs[e].color;
3556 if (dump_file && (dump_flags & TDF_DETAILS))
3558 fprintf (dump_file, "upper bound = %d\n", upper_bound);
3559 fprintf (dump_file, "lower bound = %d\n", lower_bound);
3562 if (lower_bound > upper_bound)
3563 return omega_problem_has_no_solution ();
3565 if (desired_res == omega_simplify)
3567 pb->num_geqs = 0;
3568 if (pb->safe_vars == 1)
3571 if (lower_bound == upper_bound
3572 && u_color == omega_black
3573 && l_color == omega_black)
3575 pb->eqs[0].coef[0] = -lower_bound;
3576 pb->eqs[0].coef[1] = 1;
3577 pb->eqs[0].color = omega_black;
3578 pb->num_eqs = 1;
3579 return omega_solve_problem (pb, desired_res);
3581 else
3583 if (lower_bound > neg_infinity)
3585 pb->geqs[0].coef[0] = -lower_bound;
3586 pb->geqs[0].coef[1] = 1;
3587 pb->geqs[0].key = 1;
3588 pb->geqs[0].color = l_color;
3589 pb->geqs[0].touched = 0;
3590 pb->num_geqs = 1;
3593 if (upper_bound < pos_infinity)
3595 pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3596 pb->geqs[pb->num_geqs].coef[1] = -1;
3597 pb->geqs[pb->num_geqs].key = -1;
3598 pb->geqs[pb->num_geqs].color = u_color;
3599 pb->geqs[pb->num_geqs].touched = 0;
3600 pb->num_geqs++;
3604 else
3605 pb->num_vars = 0;
3607 omega_problem_reduced (pb);
3608 return omega_false;
3611 if (original_problem != no_problem
3612 && l_color == omega_black
3613 && u_color == omega_black
3614 && !conservative
3615 && lower_bound == upper_bound)
3617 pb->eqs[0].coef[0] = -lower_bound;
3618 pb->eqs[0].coef[1] = 1;
3619 pb->num_eqs = 1;
3620 adding_equality_constraint (pb, 0);
3623 return omega_true;
3626 if (!pb->variables_freed)
3628 pb->variables_freed = true;
3630 if (desired_res != omega_simplify)
3631 omega_free_eliminations (pb, 0);
3632 else
3633 omega_free_eliminations (pb, pb->safe_vars);
3635 n_vars = pb->num_vars;
3637 if (n_vars == 1)
3638 continue;
3641 switch (normalize_omega_problem (pb))
3643 case normalize_false:
3644 return omega_false;
3645 break;
3647 case normalize_coupled:
3648 coupled_subscripts = true;
3649 break;
3651 case normalize_uncoupled:
3652 coupled_subscripts = false;
3653 break;
3655 default:
3656 gcc_unreachable ();
3659 n_vars = pb->num_vars;
3661 if (dump_file && (dump_flags & TDF_DETAILS))
3663 fprintf (dump_file, "\nafter normalization:\n");
3664 omega_print_problem (dump_file, pb);
3665 fprintf (dump_file, "\n");
3666 fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3669 do {
3670 int parallel_difference = INT_MAX;
3671 int best_parallel_eqn = -1;
3672 int minC, maxC, minCj = 0;
3673 int lower_bound_count = 0;
3674 int e2, Le = 0, Ue;
3675 bool possible_easy_int_solution;
3676 int max_splinters = 1;
3677 bool exact = false;
3678 bool lucky_exact = false;
3679 int best = (INT_MAX);
3680 int j = 0, jLe = 0, jLowerBoundCount = 0;
3683 eliminate_again = false;
3685 if (pb->num_eqs > 0)
3686 return omega_solve_problem (pb, desired_res);
3688 if (!coupled_subscripts)
3690 if (pb->safe_vars == 0)
3691 pb->num_geqs = 0;
3692 else
3693 for (e = pb->num_geqs - 1; e >= 0; e--)
3694 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3695 omega_delete_geq (pb, e, n_vars);
3697 pb->num_vars = pb->safe_vars;
3699 if (desired_res == omega_simplify)
3701 omega_problem_reduced (pb);
3702 return omega_false;
3705 return omega_true;
3708 if (desired_res != omega_simplify)
3709 fv = 0;
3710 else
3711 fv = pb->safe_vars;
3713 if (pb->num_geqs == 0)
3715 if (desired_res == omega_simplify)
3717 pb->num_vars = pb->safe_vars;
3718 omega_problem_reduced (pb);
3719 return omega_false;
3721 return omega_true;
3724 if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3726 omega_problem_reduced (pb);
3727 return omega_false;
3730 if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3731 || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3733 if (dump_file && (dump_flags & TDF_DETAILS))
3734 fprintf (dump_file,
3735 "TOO MANY EQUATIONS; "
3736 "%d equations, %d variables, "
3737 "ELIMINATING REDUNDANT ONES\n",
3738 pb->num_geqs, n_vars);
3740 if (!omega_eliminate_redundant (pb, false))
3741 return omega_false;
3743 n_vars = pb->num_vars;
3745 if (pb->num_eqs > 0)
3746 return omega_solve_problem (pb, desired_res);
3748 if (dump_file && (dump_flags & TDF_DETAILS))
3749 fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3752 if (desired_res != omega_simplify)
3753 fv = 0;
3754 else
3755 fv = pb->safe_vars;
3757 for (i = n_vars; i != fv; i--)
3759 int score;
3760 int ub = -2;
3761 int lb = -2;
3762 bool lucky = false;
3763 int upper_bound_count = 0;
3765 lower_bound_count = 0;
3766 minC = maxC = 0;
3768 for (e = pb->num_geqs - 1; e >= 0; e--)
3769 if (pb->geqs[e].coef[i] < 0)
3771 minC = MIN (minC, pb->geqs[e].coef[i]);
3772 upper_bound_count++;
3773 if (pb->geqs[e].coef[i] < -1)
3775 if (ub == -2)
3776 ub = e;
3777 else
3778 ub = -1;
3781 else if (pb->geqs[e].coef[i] > 0)
3783 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3784 lower_bound_count++;
3785 Le = e;
3786 if (pb->geqs[e].coef[i] > 1)
3788 if (lb == -2)
3789 lb = e;
3790 else
3791 lb = -1;
3795 if (lower_bound_count == 0
3796 || upper_bound_count == 0)
3798 lower_bound_count = 0;
3799 break;
3802 if (ub >= 0 && lb >= 0
3803 && pb->geqs[lb].key == -pb->geqs[ub].key)
3805 int Lc = pb->geqs[lb].coef[i];
3806 int Uc = -pb->geqs[ub].coef[i];
3807 int diff =
3808 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3809 lucky = (diff >= (Uc - 1) * (Lc - 1));
3812 if (maxC == 1
3813 || minC == -1
3814 || lucky
3815 || in_approximate_mode)
3817 score = upper_bound_count * lower_bound_count;
3819 if (dump_file && (dump_flags & TDF_DETAILS))
3820 fprintf (dump_file,
3821 "For %s, exact, score = %d*%d, range = %d ... %d,"
3822 "\nlucky = %d, in_approximate_mode=%d \n",
3823 omega_variable_to_str (pb, i),
3824 upper_bound_count,
3825 lower_bound_count, minC, maxC, lucky,
3826 in_approximate_mode);
3828 if (!exact
3829 || score < best)
3832 best = score;
3833 j = i;
3834 minCj = minC;
3835 jLe = Le;
3836 jLowerBoundCount = lower_bound_count;
3837 exact = true;
3838 lucky_exact = lucky;
3839 if (score == 1)
3840 break;
3843 else if (!exact)
3845 if (dump_file && (dump_flags & TDF_DETAILS))
3846 fprintf (dump_file,
3847 "For %s, non-exact, score = %d*%d,"
3848 "range = %d ... %d \n",
3849 omega_variable_to_str (pb, i),
3850 upper_bound_count,
3851 lower_bound_count, minC, maxC);
3853 score = maxC - minC;
3855 if (best > score)
3857 best = score;
3858 j = i;
3859 minCj = minC;
3860 jLe = Le;
3861 jLowerBoundCount = lower_bound_count;
3866 if (lower_bound_count == 0)
3868 omega_free_eliminations (pb, pb->safe_vars);
3869 n_vars = pb->num_vars;
3870 eliminate_again = true;
3871 continue;
3874 i = j;
3875 minC = minCj;
3876 Le = jLe;
3877 lower_bound_count = jLowerBoundCount;
3879 for (e = pb->num_geqs - 1; e >= 0; e--)
3880 if (pb->geqs[e].coef[i] > 0)
3882 if (pb->geqs[e].coef[i] == -minC)
3883 max_splinters += -minC - 1;
3884 else
3885 max_splinters +=
3886 pos_mul_hwi ((pb->geqs[e].coef[i] - 1),
3887 (-minC - 1)) / (-minC) + 1;
3890 /* #ifdef Omega3 */
3891 /* Trying to produce exact elimination by finding redundant
3892 constraints. */
3893 if (!exact && !tried_eliminating_redundant)
3895 omega_eliminate_redundant (pb, false);
3896 tried_eliminating_redundant = true;
3897 eliminate_again = true;
3898 continue;
3900 tried_eliminating_redundant = false;
3901 /* #endif */
3903 if (return_single_result && desired_res == omega_simplify && !exact)
3905 omega_problem_reduced (pb);
3906 return omega_true;
3909 /* #ifndef Omega3 */
3910 /* Trying to produce exact elimination by finding redundant
3911 constraints. */
3912 if (!exact && !tried_eliminating_redundant)
3914 omega_eliminate_redundant (pb, false);
3915 tried_eliminating_redundant = true;
3916 continue;
3918 tried_eliminating_redundant = false;
3919 /* #endif */
3921 if (!exact)
3923 int e1, e2;
3925 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3926 if (pb->geqs[e1].color == omega_black)
3927 for (e2 = e1 - 1; e2 >= 0; e2--)
3928 if (pb->geqs[e2].color == omega_black
3929 && pb->geqs[e1].key == -pb->geqs[e2].key
3930 && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3931 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3932 / 2 < parallel_difference))
3934 parallel_difference =
3935 (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3936 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3937 / 2;
3938 best_parallel_eqn = e1;
3941 if (dump_file && (dump_flags & TDF_DETAILS)
3942 && best_parallel_eqn >= 0)
3944 fprintf (dump_file,
3945 "Possible parallel projection, diff = %d, in ",
3946 parallel_difference);
3947 omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3948 fprintf (dump_file, "\n");
3949 omega_print_problem (dump_file, pb);
3953 if (dump_file && (dump_flags & TDF_DETAILS))
3955 fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
3956 omega_variable_to_str (pb, i), i, minC,
3957 lower_bound_count);
3958 omega_print_problem (dump_file, pb);
3960 if (lucky_exact)
3961 fprintf (dump_file, "(a lucky exact elimination)\n");
3963 else if (exact)
3964 fprintf (dump_file, "(an exact elimination)\n");
3966 fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
3969 gcc_assert (max_splinters >= 1);
3971 if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
3972 && parallel_difference <= max_splinters)
3973 return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
3974 desired_res);
3976 smoothed = false;
3978 if (i != n_vars)
3980 int j = pb->num_vars;
3982 if (dump_file && (dump_flags & TDF_DETAILS))
3984 fprintf (dump_file, "Swapping %d and %d\n", i, j);
3985 omega_print_problem (dump_file, pb);
3988 std::swap (pb->var[i], pb->var[j]);
3990 for (e = pb->num_geqs - 1; e >= 0; e--)
3991 if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
3993 pb->geqs[e].touched = 1;
3994 std::swap (pb->geqs[e].coef[i], pb->geqs[e].coef[j]);
3997 for (e = pb->num_subs - 1; e >= 0; e--)
3998 if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
3999 std::swap (pb->subs[e].coef[i], pb->subs[e].coef[j]);
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 smallest = j;
4600 for (int 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 std::swap (lower_bound[smallest], lower_bound[j]);
4608 if (dump_file && (dump_flags & TDF_DETAILS))
4610 fprintf (dump_file, "lower bound coefficients = ");
4612 for (j = 0; j < lower_bounds; j++)
4613 fprintf (dump_file, " %d",
4614 pb->geqs[lower_bound[j]].coef[i]);
4616 fprintf (dump_file, "\n");
4619 for (j = 0; j < lower_bounds; j++)
4621 int max_incr;
4622 int c;
4623 int worst_lower_bound_constant = -minC;
4625 e = lower_bound[j];
4626 max_incr = (((pb->geqs[e].coef[i] - 1) *
4627 (worst_lower_bound_constant - 1) - 1)
4628 / worst_lower_bound_constant);
4629 /* max_incr += 2; */
4631 if (dump_file && (dump_flags & TDF_DETAILS))
4633 fprintf (dump_file, "for equation ");
4634 omega_print_geq (dump_file, pb, &pb->geqs[e]);
4635 fprintf (dump_file,
4636 "\ntry decrements from 0 to %d\n",
4637 max_incr);
4638 omega_print_problem (dump_file, pb);
4641 if (max_incr > 50 && !smoothed
4642 && smooth_weird_equations (pb))
4644 conservative--;
4645 free (rS);
4646 free (iS);
4647 smoothed = true;
4648 goto solve_geq_start;
4651 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4652 pb->num_vars);
4653 pb->eqs[0].color = omega_black;
4654 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4655 pb->geqs[e].touched = 1;
4656 pb->num_eqs = 1;
4658 for (c = max_incr; c >= 0; c--)
4660 if (dump_file && (dump_flags & TDF_DETAILS))
4662 fprintf (dump_file,
4663 "trying next decrement of %d\n",
4664 max_incr - c);
4665 omega_print_problem (dump_file, pb);
4668 omega_copy_problem (rS, pb);
4670 if (dump_file && (dump_flags & TDF_DETAILS))
4671 omega_print_problem (dump_file, rS);
4673 result = omega_solve_problem (rS, desired_res);
4675 if (result == omega_true)
4677 free (rS);
4678 free (iS);
4679 free (lower_bound);
4680 conservative--;
4681 return omega_true;
4684 pb->eqs[0].coef[0]--;
4687 if (j + 1 < lower_bounds)
4689 pb->num_eqs = 0;
4690 omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4691 pb->num_vars);
4692 pb->geqs[e].touched = 1;
4693 pb->geqs[e].color = omega_black;
4694 omega_copy_problem (rS, pb);
4696 if (dump_file && (dump_flags & TDF_DETAILS))
4697 fprintf (dump_file,
4698 "exhausted lower bound, "
4699 "checking if still feasible ");
4701 result = omega_solve_problem (rS, omega_false);
4703 if (result == omega_false)
4704 break;
4708 if (dump_file && (dump_flags & TDF_DETAILS))
4709 fprintf (dump_file, "fall-off the end\n");
4711 free (rS);
4712 free (iS);
4713 free (lower_bound);
4714 conservative--;
4715 return omega_false;
4718 free (rS);
4719 free (iS);
4721 return omega_unknown;
4722 } while (eliminate_again);
4723 } while (1);
4726 /* Because the omega solver is recursive, this counter limits the
4727 recursion depth. */
4728 static int omega_solve_depth = 0;
4730 /* Return omega_true when the problem PB has a solution following the
4731 DESIRED_RES. */
4733 enum omega_result
4734 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4736 enum omega_result result;
4738 gcc_assert (pb->num_vars >= pb->safe_vars);
4739 omega_solve_depth++;
4741 if (desired_res != omega_simplify)
4742 pb->safe_vars = 0;
4744 if (omega_solve_depth > 50)
4746 if (dump_file && (dump_flags & TDF_DETAILS))
4748 fprintf (dump_file,
4749 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4750 omega_solve_depth, in_approximate_mode);
4751 omega_print_problem (dump_file, pb);
4753 gcc_assert (0);
4756 if (omega_solve_eq (pb, desired_res) == omega_false)
4758 omega_solve_depth--;
4759 return omega_false;
4762 if (in_approximate_mode && !pb->num_geqs)
4764 result = omega_true;
4765 pb->num_vars = pb->safe_vars;
4766 omega_problem_reduced (pb);
4768 else
4769 result = omega_solve_geq (pb, desired_res);
4771 omega_solve_depth--;
4773 if (!omega_reduce_with_subs)
4775 resurrect_subs (pb);
4776 gcc_assert (please_no_equalities_in_simplified_problems
4777 || !result || pb->num_subs == 0);
4780 return result;
4783 /* Return true if red equations constrain the set of possible solutions.
4784 We assume that there are solutions to the black equations by
4785 themselves, so if there is no solution to the combined problem, we
4786 return true. */
4788 bool
4789 omega_problem_has_red_equations (omega_pb pb)
4791 bool result;
4792 int e;
4793 int i;
4795 if (dump_file && (dump_flags & TDF_DETAILS))
4797 fprintf (dump_file, "Checking for red equations:\n");
4798 omega_print_problem (dump_file, pb);
4801 please_no_equalities_in_simplified_problems++;
4802 may_be_red++;
4804 if (omega_single_result)
4805 return_single_result++;
4807 create_color = true;
4808 result = (omega_simplify_problem (pb) == omega_false);
4810 if (omega_single_result)
4811 return_single_result--;
4813 may_be_red--;
4814 please_no_equalities_in_simplified_problems--;
4816 if (result)
4818 if (dump_file && (dump_flags & TDF_DETAILS))
4819 fprintf (dump_file, "Gist is FALSE\n");
4821 pb->num_subs = 0;
4822 pb->num_geqs = 0;
4823 pb->num_eqs = 1;
4824 pb->eqs[0].color = omega_red;
4826 for (i = pb->num_vars; i > 0; i--)
4827 pb->eqs[0].coef[i] = 0;
4829 pb->eqs[0].coef[0] = 1;
4830 return true;
4833 free_red_eliminations (pb);
4834 gcc_assert (pb->num_eqs == 0);
4836 for (e = pb->num_geqs - 1; e >= 0; e--)
4837 if (pb->geqs[e].color == omega_red)
4839 result = true;
4840 break;
4843 if (!result)
4844 return false;
4846 for (i = pb->safe_vars; i >= 1; i--)
4848 int ub = 0;
4849 int lb = 0;
4851 for (e = pb->num_geqs - 1; e >= 0; e--)
4853 if (pb->geqs[e].coef[i])
4855 if (pb->geqs[e].coef[i] > 0)
4856 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4858 else
4859 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4863 if (ub == 2 || lb == 2)
4866 if (dump_file && (dump_flags & TDF_DETAILS))
4867 fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4869 if (!omega_reduce_with_subs)
4871 resurrect_subs (pb);
4872 gcc_assert (pb->num_subs == 0);
4875 return true;
4880 if (dump_file && (dump_flags & TDF_DETAILS))
4881 fprintf (dump_file,
4882 "*** Doing potentially expensive elimination tests "
4883 "for red equations\n");
4885 please_no_equalities_in_simplified_problems++;
4886 omega_eliminate_red (pb, true);
4887 please_no_equalities_in_simplified_problems--;
4889 result = false;
4890 gcc_assert (pb->num_eqs == 0);
4892 for (e = pb->num_geqs - 1; e >= 0; e--)
4893 if (pb->geqs[e].color == omega_red)
4895 result = true;
4896 break;
4899 if (dump_file && (dump_flags & TDF_DETAILS))
4901 if (!result)
4902 fprintf (dump_file,
4903 "******************** Redundant Red Equations eliminated!!\n");
4904 else
4905 fprintf (dump_file,
4906 "******************** Red Equations remain\n");
4908 omega_print_problem (dump_file, pb);
4911 if (!omega_reduce_with_subs)
4913 normalize_return_type r;
4915 resurrect_subs (pb);
4916 r = normalize_omega_problem (pb);
4917 gcc_assert (r != normalize_false);
4919 coalesce (pb);
4920 cleanout_wildcards (pb);
4921 gcc_assert (pb->num_subs == 0);
4924 return result;
4927 /* Calls omega_simplify_problem in approximate mode. */
4929 enum omega_result
4930 omega_simplify_approximate (omega_pb pb)
4932 enum omega_result result;
4934 if (dump_file && (dump_flags & TDF_DETAILS))
4935 fprintf (dump_file, "(Entering approximate mode\n");
4937 in_approximate_mode = true;
4938 result = omega_simplify_problem (pb);
4939 in_approximate_mode = false;
4941 gcc_assert (pb->num_vars == pb->safe_vars);
4942 if (!omega_reduce_with_subs)
4943 gcc_assert (pb->num_subs == 0);
4945 if (dump_file && (dump_flags & TDF_DETAILS))
4946 fprintf (dump_file, "Leaving approximate mode)\n");
4948 return result;
4952 /* Simplifies problem PB by eliminating redundant constraints and
4953 reducing the constraints system to a minimal form. Returns
4954 omega_true when the problem was successfully reduced, omega_unknown
4955 when the solver is unable to determine an answer. */
4957 enum omega_result
4958 omega_simplify_problem (omega_pb pb)
4960 int i;
4962 omega_found_reduction = omega_false;
4964 if (!pb->variables_initialized)
4965 omega_initialize_variables (pb);
4967 if (next_key * 3 > MAX_KEYS)
4969 int e;
4971 hash_version++;
4972 next_key = OMEGA_MAX_VARS + 1;
4974 for (e = pb->num_geqs - 1; e >= 0; e--)
4975 pb->geqs[e].touched = 1;
4977 for (i = 0; i < HASH_TABLE_SIZE; i++)
4978 hash_master[i].touched = -1;
4980 pb->hash_version = hash_version;
4983 else if (pb->hash_version != hash_version)
4985 int e;
4987 for (e = pb->num_geqs - 1; e >= 0; e--)
4988 pb->geqs[e].touched = 1;
4990 pb->hash_version = hash_version;
4993 if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
4994 omega_free_eliminations (pb, pb->safe_vars);
4996 if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
4998 omega_found_reduction = omega_solve_problem (pb, omega_unknown);
5000 if (omega_found_reduction != omega_false
5001 && !return_single_result)
5003 pb->num_geqs = 0;
5004 pb->num_eqs = 0;
5005 (*omega_when_reduced) (pb);
5008 return omega_found_reduction;
5011 omega_solve_problem (pb, omega_simplify);
5013 if (omega_found_reduction != omega_false)
5015 for (i = 1; omega_safe_var_p (pb, i); i++)
5016 pb->forwarding_address[pb->var[i]] = i;
5018 for (i = 0; i < pb->num_subs; i++)
5019 pb->forwarding_address[pb->subs[i].key] = -i - 1;
5022 if (!omega_reduce_with_subs)
5023 gcc_assert (please_no_equalities_in_simplified_problems
5024 || omega_found_reduction == omega_false
5025 || pb->num_subs == 0);
5027 return omega_found_reduction;
5030 /* Make variable VAR unprotected: it then can be eliminated. */
5032 void
5033 omega_unprotect_variable (omega_pb pb, int var)
5035 int e, idx;
5036 idx = pb->forwarding_address[var];
5038 if (idx < 0)
5040 idx = -1 - idx;
5041 pb->num_subs--;
5043 if (idx < pb->num_subs)
5045 omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5046 pb->num_vars);
5047 pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5050 else
5052 int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5053 int e2;
5055 for (e = pb->num_subs - 1; e >= 0; e--)
5056 bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5058 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5059 if (bring_to_life[e2])
5061 pb->num_vars++;
5062 pb->safe_vars++;
5064 if (pb->safe_vars < pb->num_vars)
5066 for (e = pb->num_geqs - 1; e >= 0; e--)
5068 pb->geqs[e].coef[pb->num_vars] =
5069 pb->geqs[e].coef[pb->safe_vars];
5071 pb->geqs[e].coef[pb->safe_vars] = 0;
5074 for (e = pb->num_eqs - 1; e >= 0; e--)
5076 pb->eqs[e].coef[pb->num_vars] =
5077 pb->eqs[e].coef[pb->safe_vars];
5079 pb->eqs[e].coef[pb->safe_vars] = 0;
5082 for (e = pb->num_subs - 1; e >= 0; e--)
5084 pb->subs[e].coef[pb->num_vars] =
5085 pb->subs[e].coef[pb->safe_vars];
5087 pb->subs[e].coef[pb->safe_vars] = 0;
5090 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5091 pb->forwarding_address[pb->var[pb->num_vars]] =
5092 pb->num_vars;
5094 else
5096 for (e = pb->num_geqs - 1; e >= 0; e--)
5097 pb->geqs[e].coef[pb->safe_vars] = 0;
5099 for (e = pb->num_eqs - 1; e >= 0; e--)
5100 pb->eqs[e].coef[pb->safe_vars] = 0;
5102 for (e = pb->num_subs - 1; e >= 0; e--)
5103 pb->subs[e].coef[pb->safe_vars] = 0;
5106 pb->var[pb->safe_vars] = pb->subs[e2].key;
5107 pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5109 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5110 pb->num_vars);
5111 pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5112 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5114 if (e2 < pb->num_subs - 1)
5115 omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5116 pb->num_vars);
5118 pb->num_subs--;
5121 omega_unprotect_1 (pb, &idx, NULL);
5122 free (bring_to_life);
5125 chain_unprotect (pb);
5128 /* Unprotects VAR and simplifies PB. */
5130 enum omega_result
5131 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5132 int var, int sign)
5134 int n_vars = pb->num_vars;
5135 int e, j;
5136 int k = pb->forwarding_address[var];
5138 if (k < 0)
5140 k = -1 - k;
5142 if (sign != 0)
5144 e = pb->num_geqs++;
5145 omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5147 for (j = 0; j <= n_vars; j++)
5148 pb->geqs[e].coef[j] *= sign;
5150 pb->geqs[e].coef[0]--;
5151 pb->geqs[e].touched = 1;
5152 pb->geqs[e].color = color;
5154 else
5156 e = pb->num_eqs++;
5157 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5158 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5159 pb->eqs[e].color = color;
5162 else if (sign != 0)
5164 e = pb->num_geqs++;
5165 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5166 pb->geqs[e].coef[k] = sign;
5167 pb->geqs[e].coef[0] = -1;
5168 pb->geqs[e].touched = 1;
5169 pb->geqs[e].color = color;
5171 else
5173 e = pb->num_eqs++;
5174 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5175 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5176 pb->eqs[e].coef[k] = 1;
5177 pb->eqs[e].color = color;
5180 omega_unprotect_variable (pb, var);
5181 return omega_simplify_problem (pb);
5184 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5186 void
5187 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5188 int var, int value)
5190 int e;
5191 int k = pb->forwarding_address[var];
5193 if (k < 0)
5195 k = -1 - k;
5196 e = pb->num_eqs++;
5197 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5198 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5199 pb->eqs[e].coef[0] -= value;
5201 else
5203 e = pb->num_eqs++;
5204 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5205 pb->eqs[e].coef[k] = 1;
5206 pb->eqs[e].coef[0] = -value;
5209 pb->eqs[e].color = color;
5212 /* Return false when the upper and lower bounds are not coupled.
5213 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5214 variable I. */
5216 bool
5217 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5219 int n_vars = pb->num_vars;
5220 int e, j;
5221 bool is_simple;
5222 bool coupled = false;
5224 *lower_bound = neg_infinity;
5225 *upper_bound = pos_infinity;
5226 i = pb->forwarding_address[i];
5228 if (i < 0)
5230 i = -i - 1;
5232 for (j = 1; j <= n_vars; j++)
5233 if (pb->subs[i].coef[j] != 0)
5234 return true;
5236 *upper_bound = *lower_bound = pb->subs[i].coef[0];
5237 return false;
5240 for (e = pb->num_subs - 1; e >= 0; e--)
5241 if (pb->subs[e].coef[i] != 0)
5243 coupled = true;
5244 break;
5247 for (e = pb->num_eqs - 1; e >= 0; e--)
5248 if (pb->eqs[e].coef[i] != 0)
5250 is_simple = true;
5252 for (j = 1; j <= n_vars; j++)
5253 if (i != j && pb->eqs[e].coef[j] != 0)
5255 is_simple = false;
5256 coupled = true;
5257 break;
5260 if (!is_simple)
5261 continue;
5262 else
5264 *lower_bound = *upper_bound =
5265 -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5266 return false;
5270 for (e = pb->num_geqs - 1; e >= 0; e--)
5271 if (pb->geqs[e].coef[i] != 0)
5273 if (pb->geqs[e].key == i)
5274 *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5276 else if (pb->geqs[e].key == -i)
5277 *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5279 else
5280 coupled = true;
5283 return coupled;
5286 /* Sets the lower bound L and upper bound U for the values of variable
5287 I, and sets COULD_BE_ZERO to true if variable I might take value
5288 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5289 variable I. */
5291 static void
5292 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5293 bool *could_be_zero, int lower_bound, int upper_bound)
5295 int e, b1, b2;
5296 eqn eqn;
5297 int sign;
5298 int v;
5300 /* Preconditions. */
5301 gcc_assert (abs (pb->forwarding_address[i]) == 1
5302 && pb->num_vars + pb->num_subs == 2
5303 && pb->num_eqs + pb->num_subs == 1);
5305 /* Define variable I in terms of variable V. */
5306 if (pb->forwarding_address[i] == -1)
5308 eqn = &pb->subs[0];
5309 sign = 1;
5310 v = 1;
5312 else
5314 eqn = &pb->eqs[0];
5315 sign = -eqn->coef[1];
5316 v = 2;
5319 for (e = pb->num_geqs - 1; e >= 0; e--)
5320 if (pb->geqs[e].coef[v] != 0)
5322 if (pb->geqs[e].coef[v] == 1)
5323 lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5325 else
5326 upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5329 if (lower_bound > upper_bound)
5331 *l = pos_infinity;
5332 *u = neg_infinity;
5333 *could_be_zero = 0;
5334 return;
5337 if (lower_bound == neg_infinity)
5339 if (eqn->coef[v] > 0)
5340 b1 = sign * neg_infinity;
5342 else
5343 b1 = -sign * neg_infinity;
5345 else
5346 b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5348 if (upper_bound == pos_infinity)
5350 if (eqn->coef[v] > 0)
5351 b2 = sign * pos_infinity;
5353 else
5354 b2 = -sign * pos_infinity;
5356 else
5357 b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5359 *l = MAX (*l, b1 <= b2 ? b1 : b2);
5360 *u = MIN (*u, b1 <= b2 ? b2 : b1);
5362 *could_be_zero = (*l <= 0 && 0 <= *u
5363 && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5366 /* Return false when a lower bound L and an upper bound U for variable
5367 I in problem PB have been initialized. */
5369 bool
5370 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5372 *l = neg_infinity;
5373 *u = pos_infinity;
5375 if (!omega_query_variable (pb, i, l, u)
5376 || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5377 return false;
5379 if (abs (pb->forwarding_address[i]) == 1
5380 && pb->num_vars + pb->num_subs == 2
5381 && pb->num_eqs + pb->num_subs == 1)
5383 bool could_be_zero;
5384 query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5385 pos_infinity);
5386 return false;
5389 return true;
5392 /* For problem PB, return an integer that represents the classic data
5393 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5394 masks that are added to the result. When DIST_KNOWN is true, DIST
5395 is set to the classic data dependence distance. LOWER_BOUND and
5396 UPPER_BOUND are bounds on the value of variable I, for example, it
5397 is possible to narrow the iteration domain with safe approximations
5398 of loop counts, and thus discard some data dependences that cannot
5399 occur. */
5402 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5403 int dd_eq, int dd_gt, int lower_bound,
5404 int upper_bound, bool *dist_known, int *dist)
5406 int result;
5407 int l, u;
5408 bool could_be_zero;
5410 l = neg_infinity;
5411 u = pos_infinity;
5413 omega_query_variable (pb, i, &l, &u);
5414 query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5415 upper_bound);
5416 result = 0;
5418 if (l < 0)
5419 result |= dd_gt;
5421 if (u > 0)
5422 result |= dd_lt;
5424 if (could_be_zero)
5425 result |= dd_eq;
5427 if (l == u)
5429 *dist_known = true;
5430 *dist = l;
5432 else
5433 *dist_known = false;
5435 return result;
5438 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5439 safe variables. Safe variables are not eliminated during the
5440 Fourier-Motzkin elimination. Safe variables are all those
5441 variables that are placed at the beginning of the array of
5442 variables: P->var[0, ..., NPROT - 1]. */
5444 omega_pb
5445 omega_alloc_problem (int nvars, int nprot)
5447 omega_pb pb;
5449 gcc_assert (nvars <= OMEGA_MAX_VARS);
5450 omega_initialize ();
5452 /* Allocate and initialize PB. */
5453 pb = XCNEW (struct omega_pb_d);
5454 pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5455 pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5456 pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5457 pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5458 pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5460 pb->hash_version = hash_version;
5461 pb->num_vars = nvars;
5462 pb->safe_vars = nprot;
5463 pb->variables_initialized = false;
5464 pb->variables_freed = false;
5465 pb->num_eqs = 0;
5466 pb->num_geqs = 0;
5467 pb->num_subs = 0;
5468 return pb;
5471 /* Keeps the state of the initialization. */
5472 static bool omega_initialized = false;
5474 /* Initialization of the Omega solver. */
5476 void
5477 omega_initialize (void)
5479 int i;
5481 if (omega_initialized)
5482 return;
5484 next_wild_card = 0;
5485 next_key = OMEGA_MAX_VARS + 1;
5486 packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5487 fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5488 fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5489 hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5491 for (i = 0; i < HASH_TABLE_SIZE; i++)
5492 hash_master[i].touched = -1;
5494 sprintf (wild_name[0], "1");
5495 sprintf (wild_name[1], "a");
5496 sprintf (wild_name[2], "b");
5497 sprintf (wild_name[3], "c");
5498 sprintf (wild_name[4], "d");
5499 sprintf (wild_name[5], "e");
5500 sprintf (wild_name[6], "f");
5501 sprintf (wild_name[7], "g");
5502 sprintf (wild_name[8], "h");
5503 sprintf (wild_name[9], "i");
5504 sprintf (wild_name[10], "j");
5505 sprintf (wild_name[11], "k");
5506 sprintf (wild_name[12], "l");
5507 sprintf (wild_name[13], "m");
5508 sprintf (wild_name[14], "n");
5509 sprintf (wild_name[15], "o");
5510 sprintf (wild_name[16], "p");
5511 sprintf (wild_name[17], "q");
5512 sprintf (wild_name[18], "r");
5513 sprintf (wild_name[19], "s");
5514 sprintf (wild_name[20], "t");
5515 sprintf (wild_name[40 - 1], "alpha");
5516 sprintf (wild_name[40 - 2], "beta");
5517 sprintf (wild_name[40 - 3], "gamma");
5518 sprintf (wild_name[40 - 4], "delta");
5519 sprintf (wild_name[40 - 5], "tau");
5520 sprintf (wild_name[40 - 6], "sigma");
5521 sprintf (wild_name[40 - 7], "chi");
5522 sprintf (wild_name[40 - 8], "omega");
5523 sprintf (wild_name[40 - 9], "pi");
5524 sprintf (wild_name[40 - 10], "ni");
5525 sprintf (wild_name[40 - 11], "Alpha");
5526 sprintf (wild_name[40 - 12], "Beta");
5527 sprintf (wild_name[40 - 13], "Gamma");
5528 sprintf (wild_name[40 - 14], "Delta");
5529 sprintf (wild_name[40 - 15], "Tau");
5530 sprintf (wild_name[40 - 16], "Sigma");
5531 sprintf (wild_name[40 - 17], "Chi");
5532 sprintf (wild_name[40 - 18], "Omega");
5533 sprintf (wild_name[40 - 19], "xxx");
5535 omega_initialized = true;