* de.po: Update.
[official-gcc.git] / gcc / omega.c
blob38c51dbac7b88eea5fafaccb15b9a795f6f1eb06
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-2013 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 "tree.h"
37 #include "diagnostic-core.h"
38 #include "dumpfile.h"
39 #include "omega.h"
41 /* When set to true, keep substitution variables. When set to false,
42 resurrect substitution variables (convert substitutions back to EQs). */
43 static bool omega_reduce_with_subs = true;
45 /* When set to true, omega_simplify_problem checks for problem with no
46 solutions, calling verify_omega_pb. */
47 static bool omega_verify_simplification = false;
49 /* When set to true, only produce a single simplified result. */
50 static bool omega_single_result = false;
52 /* Set return_single_result to 1 when omega_single_result is true. */
53 static int return_single_result = 0;
55 /* Hash table for equations generated by the solver. */
56 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
57 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
58 static eqn hash_master;
59 static int next_key;
60 static int hash_version = 0;
62 /* Set to true for making the solver enter in approximation mode. */
63 static bool in_approximate_mode = false;
65 /* When set to zero, the solver is allowed to add new equalities to
66 the problem to be solved. */
67 static int conservative = 0;
69 /* Set to omega_true when the problem was successfully reduced, set to
70 omega_unknown when the solver is unable to determine an answer. */
71 static enum omega_result omega_found_reduction;
73 /* Set to true when the solver is allowed to add omega_red equations. */
74 static bool create_color = false;
76 /* Set to nonzero when the problem to be solved can be reduced. */
77 static int may_be_red = 0;
79 /* When false, there should be no substitution equations in the
80 simplified problem. */
81 static int please_no_equalities_in_simplified_problems = 0;
83 /* Variables names for pretty printing. */
84 static char wild_name[200][40];
86 /* Pointer to the void problem. */
87 static omega_pb no_problem = (omega_pb) 0;
89 /* Pointer to the problem to be solved. */
90 static omega_pb original_problem = (omega_pb) 0;
93 /* Return the integer A divided by B. */
95 static inline int
96 int_div (int a, int b)
98 if (a > 0)
99 return a/b;
100 else
101 return -((-a + b - 1)/b);
104 /* Return the integer A modulo B. */
106 static inline int
107 int_mod (int a, int b)
109 return a - b * int_div (a, b);
112 /* Test whether equation E is red. */
114 static inline bool
115 omega_eqn_is_red (eqn e, int desired_res)
117 return (desired_res == omega_simplify && e->color == omega_red);
120 /* Return a string for VARIABLE. */
122 static inline char *
123 omega_var_to_str (int variable)
125 if (0 <= variable && variable <= 20)
126 return wild_name[variable];
128 if (-20 < variable && variable < 0)
129 return wild_name[40 + variable];
131 /* Collapse all the entries that would have overflowed. */
132 return wild_name[21];
135 /* Return a string for variable I in problem PB. */
137 static inline char *
138 omega_variable_to_str (omega_pb pb, int i)
140 return omega_var_to_str (pb->var[i]);
143 /* Do nothing function: used for default initializations. */
145 void
146 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
150 void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
152 /* Print to FILE from PB equation E with all its coefficients
153 multiplied by C. */
155 static void
156 omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
158 int i;
159 bool first = true;
160 int n = pb->num_vars;
161 int went_first = -1;
163 for (i = 1; i <= n; i++)
164 if (c * e->coef[i] > 0)
166 first = false;
167 went_first = i;
169 if (c * e->coef[i] == 1)
170 fprintf (file, "%s", omega_variable_to_str (pb, i));
171 else
172 fprintf (file, "%d * %s", c * e->coef[i],
173 omega_variable_to_str (pb, i));
174 break;
177 for (i = 1; i <= n; i++)
178 if (i != went_first && c * e->coef[i] != 0)
180 if (!first && c * e->coef[i] > 0)
181 fprintf (file, " + ");
183 first = false;
185 if (c * e->coef[i] == 1)
186 fprintf (file, "%s", omega_variable_to_str (pb, i));
187 else if (c * e->coef[i] == -1)
188 fprintf (file, " - %s", omega_variable_to_str (pb, i));
189 else
190 fprintf (file, "%d * %s", c * e->coef[i],
191 omega_variable_to_str (pb, i));
194 if (!first && c * e->coef[0] > 0)
195 fprintf (file, " + ");
197 if (first || c * e->coef[0] != 0)
198 fprintf (file, "%d", c * e->coef[0]);
201 /* Print to FILE the equation E of problem PB. */
203 void
204 omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
206 int i;
207 int n = pb->num_vars + extra;
208 bool is_lt = test && e->coef[0] == -1;
209 bool first;
211 if (test)
213 if (e->touched)
214 fprintf (file, "!");
216 else if (e->key != 0)
217 fprintf (file, "%d: ", e->key);
220 if (e->color == omega_red)
221 fprintf (file, "[");
223 first = true;
225 for (i = is_lt ? 1 : 0; i <= n; i++)
226 if (e->coef[i] < 0)
228 if (!first)
229 fprintf (file, " + ");
230 else
231 first = false;
233 if (i == 0)
234 fprintf (file, "%d", -e->coef[i]);
235 else if (e->coef[i] == -1)
236 fprintf (file, "%s", omega_variable_to_str (pb, i));
237 else
238 fprintf (file, "%d * %s", -e->coef[i],
239 omega_variable_to_str (pb, i));
242 if (first)
244 if (is_lt)
246 fprintf (file, "1");
247 is_lt = false;
249 else
250 fprintf (file, "0");
253 if (test == 0)
254 fprintf (file, " = ");
255 else if (is_lt)
256 fprintf (file, " < ");
257 else
258 fprintf (file, " <= ");
260 first = true;
262 for (i = 0; i <= n; i++)
263 if (e->coef[i] > 0)
265 if (!first)
266 fprintf (file, " + ");
267 else
268 first = false;
270 if (i == 0)
271 fprintf (file, "%d", e->coef[i]);
272 else if (e->coef[i] == 1)
273 fprintf (file, "%s", omega_variable_to_str (pb, i));
274 else
275 fprintf (file, "%d * %s", e->coef[i],
276 omega_variable_to_str (pb, i));
279 if (first)
280 fprintf (file, "0");
282 if (e->color == omega_red)
283 fprintf (file, "]");
286 /* Print to FILE all the variables of problem PB. */
288 static void
289 omega_print_vars (FILE *file, omega_pb pb)
291 int i;
293 fprintf (file, "variables = ");
295 if (pb->safe_vars > 0)
296 fprintf (file, "protected (");
298 for (i = 1; i <= pb->num_vars; i++)
300 fprintf (file, "%s", omega_variable_to_str (pb, i));
302 if (i == pb->safe_vars)
303 fprintf (file, ")");
305 if (i < pb->num_vars)
306 fprintf (file, ", ");
309 fprintf (file, "\n");
312 /* Debug problem PB. */
314 DEBUG_FUNCTION void
315 debug_omega_problem (omega_pb pb)
317 omega_print_problem (stderr, pb);
320 /* Print to FILE problem PB. */
322 void
323 omega_print_problem (FILE *file, omega_pb pb)
325 int e;
327 if (!pb->variables_initialized)
328 omega_initialize_variables (pb);
330 omega_print_vars (file, pb);
332 for (e = 0; e < pb->num_eqs; e++)
334 omega_print_eq (file, pb, &pb->eqs[e]);
335 fprintf (file, "\n");
338 fprintf (file, "Done with EQ\n");
340 for (e = 0; e < pb->num_geqs; e++)
342 omega_print_geq (file, pb, &pb->geqs[e]);
343 fprintf (file, "\n");
346 fprintf (file, "Done with GEQ\n");
348 for (e = 0; e < pb->num_subs; e++)
350 eqn eq = &pb->subs[e];
352 if (eq->color == omega_red)
353 fprintf (file, "[");
355 if (eq->key > 0)
356 fprintf (file, "%s := ", omega_var_to_str (eq->key));
357 else
358 fprintf (file, "#%d := ", eq->key);
360 omega_print_term (file, pb, eq, 1);
362 if (eq->color == omega_red)
363 fprintf (file, "]");
365 fprintf (file, "\n");
369 /* Return the number of equations in PB tagged omega_red. */
372 omega_count_red_equations (omega_pb pb)
374 int e, i;
375 int result = 0;
377 for (e = 0; e < pb->num_eqs; e++)
378 if (pb->eqs[e].color == omega_red)
380 for (i = pb->num_vars; i > 0; i--)
381 if (pb->geqs[e].coef[i])
382 break;
384 if (i == 0 && pb->geqs[e].coef[0] == 1)
385 return 0;
386 else
387 result += 2;
390 for (e = 0; e < pb->num_geqs; e++)
391 if (pb->geqs[e].color == omega_red)
392 result += 1;
394 for (e = 0; e < pb->num_subs; e++)
395 if (pb->subs[e].color == omega_red)
396 result += 2;
398 return result;
401 /* Print to FILE all the equations in PB that are tagged omega_red. */
403 void
404 omega_print_red_equations (FILE *file, omega_pb pb)
406 int e;
408 if (!pb->variables_initialized)
409 omega_initialize_variables (pb);
411 omega_print_vars (file, pb);
413 for (e = 0; e < pb->num_eqs; e++)
414 if (pb->eqs[e].color == omega_red)
416 omega_print_eq (file, pb, &pb->eqs[e]);
417 fprintf (file, "\n");
420 for (e = 0; e < pb->num_geqs; e++)
421 if (pb->geqs[e].color == omega_red)
423 omega_print_geq (file, pb, &pb->geqs[e]);
424 fprintf (file, "\n");
427 for (e = 0; e < pb->num_subs; e++)
428 if (pb->subs[e].color == omega_red)
430 eqn eq = &pb->subs[e];
431 fprintf (file, "[");
433 if (eq->key > 0)
434 fprintf (file, "%s := ", omega_var_to_str (eq->key));
435 else
436 fprintf (file, "#%d := ", eq->key);
438 omega_print_term (file, pb, eq, 1);
439 fprintf (file, "]\n");
443 /* Pretty print PB to FILE. */
445 void
446 omega_pretty_print_problem (FILE *file, omega_pb pb)
448 int e, v, v1, v2, v3, t;
449 bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
450 int stuffPrinted = 0;
451 bool change;
453 typedef enum {
454 none, le, lt
455 } partial_order_type;
457 partial_order_type **po = XNEWVEC (partial_order_type *,
458 OMEGA_MAX_VARS * OMEGA_MAX_VARS);
459 int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
460 int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
461 int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
462 int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
463 int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
464 int i, m;
465 bool multiprint;
467 if (!pb->variables_initialized)
468 omega_initialize_variables (pb);
470 if (pb->num_vars > 0)
472 omega_eliminate_redundant (pb, false);
474 for (e = 0; e < pb->num_eqs; e++)
476 if (stuffPrinted)
477 fprintf (file, "; ");
479 stuffPrinted = 1;
480 omega_print_eq (file, pb, &pb->eqs[e]);
483 for (e = 0; e < pb->num_geqs; e++)
484 live[e] = true;
486 while (1)
488 for (v = 1; v <= pb->num_vars; v++)
490 last_links[v] = first_links[v] = 0;
491 chain_length[v] = 0;
493 for (v2 = 1; v2 <= pb->num_vars; v2++)
494 po[v][v2] = none;
497 for (e = 0; e < pb->num_geqs; e++)
498 if (live[e])
500 for (v = 1; v <= pb->num_vars; v++)
501 if (pb->geqs[e].coef[v] == 1)
502 first_links[v]++;
503 else if (pb->geqs[e].coef[v] == -1)
504 last_links[v]++;
506 v1 = pb->num_vars;
508 while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
509 v1--;
511 v2 = v1 - 1;
513 while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
514 v2--;
516 v3 = v2 - 1;
518 while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
519 v3--;
521 if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
522 || v2 <= 0 || v3 > 0
523 || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
525 /* Not a partial order relation. */
527 else
529 if (pb->geqs[e].coef[v1] == 1)
531 v3 = v2;
532 v2 = v1;
533 v1 = v3;
536 /* Relation is v1 <= v2 or v1 < v2. */
537 po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
538 po_eq[v1][v2] = e;
541 for (v = 1; v <= pb->num_vars; v++)
542 chain_length[v] = last_links[v];
544 /* Just in case pb->num_vars <= 0. */
545 change = false;
546 for (t = 0; t < pb->num_vars; t++)
548 change = false;
550 for (v1 = 1; v1 <= pb->num_vars; v1++)
551 for (v2 = 1; v2 <= pb->num_vars; v2++)
552 if (po[v1][v2] != none &&
553 chain_length[v1] <= chain_length[v2])
555 chain_length[v1] = chain_length[v2] + 1;
556 change = true;
560 /* Caught in cycle. */
561 gcc_assert (!change);
563 for (v1 = 1; v1 <= pb->num_vars; v1++)
564 if (chain_length[v1] == 0)
565 first_links[v1] = 0;
567 v = 1;
569 for (v1 = 2; v1 <= pb->num_vars; v1++)
570 if (chain_length[v1] + first_links[v1] >
571 chain_length[v] + first_links[v])
572 v = v1;
574 if (chain_length[v] + first_links[v] == 0)
575 break;
577 if (stuffPrinted)
578 fprintf (file, "; ");
580 stuffPrinted = 1;
582 /* Chain starts at v. */
584 int tmp;
585 bool first = true;
587 for (e = 0; e < pb->num_geqs; e++)
588 if (live[e] && pb->geqs[e].coef[v] == 1)
590 if (!first)
591 fprintf (file, ", ");
593 tmp = pb->geqs[e].coef[v];
594 pb->geqs[e].coef[v] = 0;
595 omega_print_term (file, pb, &pb->geqs[e], -1);
596 pb->geqs[e].coef[v] = tmp;
597 live[e] = false;
598 first = false;
601 if (!first)
602 fprintf (file, " <= ");
605 /* Find chain. */
606 chain[0] = v;
607 m = 1;
608 while (1)
610 /* Print chain. */
611 for (v2 = 1; v2 <= pb->num_vars; v2++)
612 if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
613 break;
615 if (v2 > pb->num_vars)
616 break;
618 chain[m++] = v2;
619 v = v2;
622 fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
624 for (multiprint = false, i = 1; i < m; i++)
626 v = chain[i - 1];
627 v2 = chain[i];
629 if (po[v][v2] == le)
630 fprintf (file, " <= ");
631 else
632 fprintf (file, " < ");
634 fprintf (file, "%s", omega_variable_to_str (pb, v2));
635 live[po_eq[v][v2]] = false;
637 if (!multiprint && i < m - 1)
638 for (v3 = 1; v3 <= pb->num_vars; v3++)
640 if (v == v3 || v2 == v3
641 || po[v][v2] != po[v][v3]
642 || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
643 continue;
645 fprintf (file, ",%s", omega_variable_to_str (pb, v3));
646 live[po_eq[v][v3]] = false;
647 live[po_eq[v3][chain[i + 1]]] = false;
648 multiprint = true;
650 else
651 multiprint = false;
654 v = chain[m - 1];
655 /* Print last_links. */
657 int tmp;
658 bool first = true;
660 for (e = 0; e < pb->num_geqs; e++)
661 if (live[e] && pb->geqs[e].coef[v] == -1)
663 if (!first)
664 fprintf (file, ", ");
665 else
666 fprintf (file, " <= ");
668 tmp = pb->geqs[e].coef[v];
669 pb->geqs[e].coef[v] = 0;
670 omega_print_term (file, pb, &pb->geqs[e], 1);
671 pb->geqs[e].coef[v] = tmp;
672 live[e] = false;
673 first = false;
678 for (e = 0; e < pb->num_geqs; e++)
679 if (live[e])
681 if (stuffPrinted)
682 fprintf (file, "; ");
683 stuffPrinted = 1;
684 omega_print_geq (file, pb, &pb->geqs[e]);
687 for (e = 0; e < pb->num_subs; e++)
689 eqn eq = &pb->subs[e];
691 if (stuffPrinted)
692 fprintf (file, "; ");
694 stuffPrinted = 1;
696 if (eq->key > 0)
697 fprintf (file, "%s := ", omega_var_to_str (eq->key));
698 else
699 fprintf (file, "#%d := ", eq->key);
701 omega_print_term (file, pb, eq, 1);
705 free (live);
706 free (po);
707 free (po_eq);
708 free (last_links);
709 free (first_links);
710 free (chain_length);
711 free (chain);
714 /* Assign to variable I in PB the next wildcard name. The name of a
715 wildcard is a negative number. */
716 static int next_wild_card = 0;
718 static void
719 omega_name_wild_card (omega_pb pb, int i)
721 --next_wild_card;
722 if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
723 next_wild_card = -1;
724 pb->var[i] = next_wild_card;
727 /* Return the index of the last protected (or safe) variable in PB,
728 after having added a new wildcard variable. */
730 static int
731 omega_add_new_wild_card (omega_pb pb)
733 int e;
734 int i = ++pb->safe_vars;
735 pb->num_vars++;
737 /* Make a free place in the protected (safe) variables, by moving
738 the non protected variable pointed by "I" at the end, ie. at
739 offset pb->num_vars. */
740 if (pb->num_vars != i)
742 /* Move "I" for all the inequalities. */
743 for (e = pb->num_geqs - 1; e >= 0; e--)
745 if (pb->geqs[e].coef[i])
746 pb->geqs[e].touched = 1;
748 pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
751 /* Move "I" for all the equalities. */
752 for (e = pb->num_eqs - 1; e >= 0; e--)
753 pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
755 /* Move "I" for all the substitutions. */
756 for (e = pb->num_subs - 1; e >= 0; e--)
757 pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
759 /* Move the identifier. */
760 pb->var[pb->num_vars] = pb->var[i];
763 /* Initialize at zero all the coefficients */
764 for (e = pb->num_geqs - 1; e >= 0; e--)
765 pb->geqs[e].coef[i] = 0;
767 for (e = pb->num_eqs - 1; e >= 0; e--)
768 pb->eqs[e].coef[i] = 0;
770 for (e = pb->num_subs - 1; e >= 0; e--)
771 pb->subs[e].coef[i] = 0;
773 /* And give it a name. */
774 omega_name_wild_card (pb, i);
775 return i;
778 /* Delete inequality E from problem PB that has N_VARS variables. */
780 static void
781 omega_delete_geq (omega_pb pb, int e, int n_vars)
783 if (dump_file && (dump_flags & TDF_DETAILS))
785 fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
786 omega_print_geq (dump_file, pb, &pb->geqs[e]);
787 fprintf (dump_file, "\n");
790 if (e < pb->num_geqs - 1)
791 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
793 pb->num_geqs--;
796 /* Delete extra inequality E from problem PB that has N_VARS
797 variables. */
799 static void
800 omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
802 if (dump_file && (dump_flags & TDF_DETAILS))
804 fprintf (dump_file, "Deleting %d: ",e);
805 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
806 fprintf (dump_file, "\n");
809 if (e < pb->num_geqs - 1)
810 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
812 pb->num_geqs--;
816 /* Remove variable I from problem PB. */
818 static void
819 omega_delete_variable (omega_pb pb, int i)
821 int n_vars = pb->num_vars;
822 int e;
824 if (omega_safe_var_p (pb, i))
826 int j = pb->safe_vars;
828 for (e = pb->num_geqs - 1; e >= 0; e--)
830 pb->geqs[e].touched = 1;
831 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
832 pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
835 for (e = pb->num_eqs - 1; e >= 0; e--)
837 pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
838 pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
841 for (e = pb->num_subs - 1; e >= 0; e--)
843 pb->subs[e].coef[i] = pb->subs[e].coef[j];
844 pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
847 pb->var[i] = pb->var[j];
848 pb->var[j] = pb->var[n_vars];
850 else if (i < n_vars)
852 for (e = pb->num_geqs - 1; e >= 0; e--)
853 if (pb->geqs[e].coef[n_vars])
855 pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
856 pb->geqs[e].touched = 1;
859 for (e = pb->num_eqs - 1; e >= 0; e--)
860 pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
862 for (e = pb->num_subs - 1; e >= 0; e--)
863 pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
865 pb->var[i] = pb->var[n_vars];
868 if (omega_safe_var_p (pb, i))
869 pb->safe_vars--;
871 pb->num_vars--;
874 /* Because the coefficients of an equation are sparse, PACKING records
875 indices for non null coefficients. */
876 static int *packing;
878 /* Set up the coefficients of PACKING, following the coefficients of
879 equation EQN that has NUM_VARS variables. */
881 static inline int
882 setup_packing (eqn eqn, int num_vars)
884 int k;
885 int n = 0;
887 for (k = num_vars; k >= 0; k--)
888 if (eqn->coef[k])
889 packing[n++] = k;
891 return n;
894 /* Computes a linear combination of EQ and SUB at VAR with coefficient
895 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
896 non null indices of SUB stored in PACKING. */
898 static inline void
899 omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
900 int top_var)
902 if (eq->coef[var] != 0)
904 if (eq->color == omega_black)
905 *found_black = true;
906 else
908 int j, k = eq->coef[var];
910 eq->coef[var] = 0;
912 for (j = top_var; j >= 0; j--)
913 eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
918 /* Substitute in PB variable VAR with "C * SUB". */
920 static void
921 omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
923 int e, top_var = setup_packing (sub, pb->num_vars);
925 *found_black = false;
927 if (dump_file && (dump_flags & TDF_DETAILS))
929 if (sub->color == omega_red)
930 fprintf (dump_file, "[");
932 fprintf (dump_file, "substituting using %s := ",
933 omega_variable_to_str (pb, var));
934 omega_print_term (dump_file, pb, sub, -c);
936 if (sub->color == omega_red)
937 fprintf (dump_file, "]");
939 fprintf (dump_file, "\n");
940 omega_print_vars (dump_file, pb);
943 for (e = pb->num_eqs - 1; e >= 0; e--)
945 eqn eqn = &(pb->eqs[e]);
947 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
949 if (dump_file && (dump_flags & TDF_DETAILS))
951 omega_print_eq (dump_file, pb, eqn);
952 fprintf (dump_file, "\n");
956 for (e = pb->num_geqs - 1; e >= 0; e--)
958 eqn eqn = &(pb->geqs[e]);
960 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
962 if (eqn->coef[var] && eqn->color == omega_red)
963 eqn->touched = 1;
965 if (dump_file && (dump_flags & TDF_DETAILS))
967 omega_print_geq (dump_file, pb, eqn);
968 fprintf (dump_file, "\n");
972 for (e = pb->num_subs - 1; e >= 0; e--)
974 eqn eqn = &(pb->subs[e]);
976 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
978 if (dump_file && (dump_flags & TDF_DETAILS))
980 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
981 omega_print_term (dump_file, pb, eqn, 1);
982 fprintf (dump_file, "\n");
986 if (dump_file && (dump_flags & TDF_DETAILS))
987 fprintf (dump_file, "---\n\n");
989 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
990 *found_black = true;
993 /* Substitute in PB variable VAR with "C * SUB". */
995 static void
996 omega_substitute (omega_pb pb, eqn sub, int var, int c)
998 int e, j, j0;
999 int top_var = setup_packing (sub, pb->num_vars);
1001 if (dump_file && (dump_flags & TDF_DETAILS))
1003 fprintf (dump_file, "substituting using %s := ",
1004 omega_variable_to_str (pb, var));
1005 omega_print_term (dump_file, pb, sub, -c);
1006 fprintf (dump_file, "\n");
1007 omega_print_vars (dump_file, pb);
1010 if (top_var < 0)
1012 for (e = pb->num_eqs - 1; e >= 0; e--)
1013 pb->eqs[e].coef[var] = 0;
1015 for (e = pb->num_geqs - 1; e >= 0; e--)
1016 if (pb->geqs[e].coef[var] != 0)
1018 pb->geqs[e].touched = 1;
1019 pb->geqs[e].coef[var] = 0;
1022 for (e = pb->num_subs - 1; e >= 0; e--)
1023 pb->subs[e].coef[var] = 0;
1025 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1027 int k;
1028 eqn eqn = &(pb->subs[pb->num_subs++]);
1030 for (k = pb->num_vars; k >= 0; k--)
1031 eqn->coef[k] = 0;
1033 eqn->key = pb->var[var];
1034 eqn->color = omega_black;
1037 else if (top_var == 0 && packing[0] == 0)
1039 c = -sub->coef[0] * c;
1041 for (e = pb->num_eqs - 1; e >= 0; e--)
1043 pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
1044 pb->eqs[e].coef[var] = 0;
1047 for (e = pb->num_geqs - 1; e >= 0; e--)
1048 if (pb->geqs[e].coef[var] != 0)
1050 pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
1051 pb->geqs[e].coef[var] = 0;
1052 pb->geqs[e].touched = 1;
1055 for (e = pb->num_subs - 1; e >= 0; e--)
1057 pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
1058 pb->subs[e].coef[var] = 0;
1061 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1063 int k;
1064 eqn eqn = &(pb->subs[pb->num_subs++]);
1066 for (k = pb->num_vars; k >= 1; k--)
1067 eqn->coef[k] = 0;
1069 eqn->coef[0] = c;
1070 eqn->key = pb->var[var];
1071 eqn->color = omega_black;
1074 if (dump_file && (dump_flags & TDF_DETAILS))
1076 fprintf (dump_file, "---\n\n");
1077 omega_print_problem (dump_file, pb);
1078 fprintf (dump_file, "===\n\n");
1081 else
1083 for (e = pb->num_eqs - 1; e >= 0; e--)
1085 eqn eqn = &(pb->eqs[e]);
1086 int k = eqn->coef[var];
1088 if (k != 0)
1090 k = c * k;
1091 eqn->coef[var] = 0;
1093 for (j = top_var; j >= 0; j--)
1095 j0 = packing[j];
1096 eqn->coef[j0] -= sub->coef[j0] * k;
1100 if (dump_file && (dump_flags & TDF_DETAILS))
1102 omega_print_eq (dump_file, pb, eqn);
1103 fprintf (dump_file, "\n");
1107 for (e = pb->num_geqs - 1; e >= 0; e--)
1109 eqn eqn = &(pb->geqs[e]);
1110 int k = eqn->coef[var];
1112 if (k != 0)
1114 k = c * k;
1115 eqn->touched = 1;
1116 eqn->coef[var] = 0;
1118 for (j = top_var; j >= 0; j--)
1120 j0 = packing[j];
1121 eqn->coef[j0] -= sub->coef[j0] * k;
1125 if (dump_file && (dump_flags & TDF_DETAILS))
1127 omega_print_geq (dump_file, pb, eqn);
1128 fprintf (dump_file, "\n");
1132 for (e = pb->num_subs - 1; e >= 0; e--)
1134 eqn eqn = &(pb->subs[e]);
1135 int k = eqn->coef[var];
1137 if (k != 0)
1139 k = c * k;
1140 eqn->coef[var] = 0;
1142 for (j = top_var; j >= 0; j--)
1144 j0 = packing[j];
1145 eqn->coef[j0] -= sub->coef[j0] * k;
1149 if (dump_file && (dump_flags & TDF_DETAILS))
1151 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1152 omega_print_term (dump_file, pb, eqn, 1);
1153 fprintf (dump_file, "\n");
1157 if (dump_file && (dump_flags & TDF_DETAILS))
1159 fprintf (dump_file, "---\n\n");
1160 omega_print_problem (dump_file, pb);
1161 fprintf (dump_file, "===\n\n");
1164 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1166 int k;
1167 eqn eqn = &(pb->subs[pb->num_subs++]);
1168 c = -c;
1170 for (k = pb->num_vars; k >= 0; k--)
1171 eqn->coef[k] = c * (sub->coef[k]);
1173 eqn->key = pb->var[var];
1174 eqn->color = sub->color;
1179 /* Solve e = factor alpha for x_j and substitute. */
1181 static void
1182 omega_do_mod (omega_pb pb, int factor, int e, int j)
1184 int k, i;
1185 eqn eq = omega_alloc_eqns (0, 1);
1186 int nfactor;
1187 bool kill_j = false;
1189 omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
1191 for (k = pb->num_vars; k >= 0; k--)
1193 eq->coef[k] = int_mod (eq->coef[k], factor);
1195 if (2 * eq->coef[k] >= factor)
1196 eq->coef[k] -= factor;
1199 nfactor = eq->coef[j];
1201 if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
1203 i = omega_add_new_wild_card (pb);
1204 eq->coef[pb->num_vars] = eq->coef[i];
1205 eq->coef[j] = 0;
1206 eq->coef[i] = -factor;
1207 kill_j = true;
1209 else
1211 eq->coef[j] = -factor;
1212 if (!omega_wildcard_p (pb, j))
1213 omega_name_wild_card (pb, j);
1216 omega_substitute (pb, eq, j, nfactor);
1218 for (k = pb->num_vars; k >= 0; k--)
1219 pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
1221 if (kill_j)
1222 omega_delete_variable (pb, j);
1224 if (dump_file && (dump_flags & TDF_DETAILS))
1226 fprintf (dump_file, "Mod-ing and normalizing produces:\n");
1227 omega_print_problem (dump_file, pb);
1230 omega_free_eqns (eq, 1);
1233 /* Multiplies by -1 inequality E. */
1235 void
1236 omega_negate_geq (omega_pb pb, int e)
1238 int i;
1240 for (i = pb->num_vars; i >= 0; i--)
1241 pb->geqs[e].coef[i] *= -1;
1243 pb->geqs[e].coef[0]--;
1244 pb->geqs[e].touched = 1;
1247 /* Returns OMEGA_TRUE when problem PB has a solution. */
1249 static enum omega_result
1250 verify_omega_pb (omega_pb pb)
1252 enum omega_result result;
1253 int e;
1254 bool any_color = false;
1255 omega_pb tmp_problem = XNEW (struct omega_pb_d);
1257 omega_copy_problem (tmp_problem, pb);
1258 tmp_problem->safe_vars = 0;
1259 tmp_problem->num_subs = 0;
1261 for (e = pb->num_geqs - 1; e >= 0; e--)
1262 if (pb->geqs[e].color == omega_red)
1264 any_color = true;
1265 break;
1268 if (please_no_equalities_in_simplified_problems)
1269 any_color = true;
1271 if (any_color)
1272 original_problem = no_problem;
1273 else
1274 original_problem = pb;
1276 if (dump_file && (dump_flags & TDF_DETAILS))
1278 fprintf (dump_file, "verifying problem");
1280 if (any_color)
1281 fprintf (dump_file, " (color mode)");
1283 fprintf (dump_file, " :\n");
1284 omega_print_problem (dump_file, pb);
1287 result = omega_solve_problem (tmp_problem, omega_unknown);
1288 original_problem = no_problem;
1289 free (tmp_problem);
1291 if (dump_file && (dump_flags & TDF_DETAILS))
1293 if (result != omega_false)
1294 fprintf (dump_file, "verified problem\n");
1295 else
1296 fprintf (dump_file, "disproved problem\n");
1297 omega_print_problem (dump_file, pb);
1300 return result;
1303 /* Add a new equality to problem PB at last position E. */
1305 static void
1306 adding_equality_constraint (omega_pb pb, int e)
1308 if (original_problem != no_problem
1309 && original_problem != pb
1310 && !conservative)
1312 int i, j;
1313 int e2 = original_problem->num_eqs++;
1315 if (dump_file && (dump_flags & TDF_DETAILS))
1316 fprintf (dump_file,
1317 "adding equality constraint %d to outer problem\n", e2);
1318 omega_init_eqn_zero (&original_problem->eqs[e2],
1319 original_problem->num_vars);
1321 for (i = pb->num_vars; i >= 1; i--)
1323 for (j = original_problem->num_vars; j >= 1; j--)
1324 if (original_problem->var[j] == pb->var[i])
1325 break;
1327 if (j <= 0)
1329 if (dump_file && (dump_flags & TDF_DETAILS))
1330 fprintf (dump_file, "retracting\n");
1331 original_problem->num_eqs--;
1332 return;
1334 original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
1337 original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
1339 if (dump_file && (dump_flags & TDF_DETAILS))
1340 omega_print_problem (dump_file, original_problem);
1344 static int *fast_lookup;
1345 static int *fast_lookup_red;
1347 typedef enum {
1348 normalize_false,
1349 normalize_uncoupled,
1350 normalize_coupled
1351 } normalize_return_type;
1353 /* Normalizes PB by removing redundant constraints. Returns
1354 normalize_false when the constraints system has no solution,
1355 otherwise returns normalize_coupled or normalize_uncoupled. */
1357 static normalize_return_type
1358 normalize_omega_problem (omega_pb pb)
1360 int e, i, j, k, n_vars;
1361 int coupled_subscripts = 0;
1363 n_vars = pb->num_vars;
1365 for (e = 0; e < pb->num_geqs; e++)
1367 if (!pb->geqs[e].touched)
1369 if (!single_var_geq (&pb->geqs[e], n_vars))
1370 coupled_subscripts = 1;
1372 else
1374 int g, top_var, i0, hashCode;
1375 int *p = &packing[0];
1377 for (k = 1; k <= n_vars; k++)
1378 if (pb->geqs[e].coef[k])
1379 *(p++) = k;
1381 top_var = (p - &packing[0]) - 1;
1383 if (top_var == -1)
1385 if (pb->geqs[e].coef[0] < 0)
1387 if (dump_file && (dump_flags & TDF_DETAILS))
1389 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1390 fprintf (dump_file, "\nequations have no solution \n");
1392 return normalize_false;
1395 omega_delete_geq (pb, e, n_vars);
1396 e--;
1397 continue;
1399 else if (top_var == 0)
1401 int singlevar = packing[0];
1403 g = pb->geqs[e].coef[singlevar];
1405 if (g > 0)
1407 pb->geqs[e].coef[singlevar] = 1;
1408 pb->geqs[e].key = singlevar;
1410 else
1412 g = -g;
1413 pb->geqs[e].coef[singlevar] = -1;
1414 pb->geqs[e].key = -singlevar;
1417 if (g > 1)
1418 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1420 else
1422 int g2;
1423 int hash_key_multiplier = 31;
1425 coupled_subscripts = 1;
1426 i0 = top_var;
1427 i = packing[i0--];
1428 g = pb->geqs[e].coef[i];
1429 hashCode = g * (i + 3);
1431 if (g < 0)
1432 g = -g;
1434 for (; i0 >= 0; i0--)
1436 int x;
1438 i = packing[i0];
1439 x = pb->geqs[e].coef[i];
1440 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1442 if (x < 0)
1443 x = -x;
1445 if (x == 1)
1447 g = 1;
1448 i0--;
1449 break;
1451 else
1452 g = gcd (x, g);
1455 for (; i0 >= 0; i0--)
1457 int x;
1458 i = packing[i0];
1459 x = pb->geqs[e].coef[i];
1460 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1463 if (g > 1)
1465 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1466 i0 = top_var;
1467 i = packing[i0--];
1468 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1469 hashCode = pb->geqs[e].coef[i] * (i + 3);
1471 for (; i0 >= 0; i0--)
1473 i = packing[i0];
1474 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1475 hashCode = hashCode * hash_key_multiplier * (i + 3)
1476 + pb->geqs[e].coef[i];
1480 g2 = abs (hashCode);
1482 if (dump_file && (dump_flags & TDF_DETAILS))
1484 fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
1485 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1486 fprintf (dump_file, "\n");
1489 j = g2 % HASH_TABLE_SIZE;
1491 do {
1492 eqn proto = &(hash_master[j]);
1494 if (proto->touched == g2)
1496 if (proto->coef[0] == top_var)
1498 if (hashCode >= 0)
1499 for (i0 = top_var; i0 >= 0; i0--)
1501 i = packing[i0];
1503 if (pb->geqs[e].coef[i] != proto->coef[i])
1504 break;
1506 else
1507 for (i0 = top_var; i0 >= 0; i0--)
1509 i = packing[i0];
1511 if (pb->geqs[e].coef[i] != -proto->coef[i])
1512 break;
1515 if (i0 < 0)
1517 if (hashCode >= 0)
1518 pb->geqs[e].key = proto->key;
1519 else
1520 pb->geqs[e].key = -proto->key;
1521 break;
1525 else if (proto->touched < 0)
1527 omega_init_eqn_zero (proto, pb->num_vars);
1528 if (hashCode >= 0)
1529 for (i0 = top_var; i0 >= 0; i0--)
1531 i = packing[i0];
1532 proto->coef[i] = pb->geqs[e].coef[i];
1534 else
1535 for (i0 = top_var; i0 >= 0; i0--)
1537 i = packing[i0];
1538 proto->coef[i] = -pb->geqs[e].coef[i];
1541 proto->coef[0] = top_var;
1542 proto->touched = g2;
1544 if (dump_file && (dump_flags & TDF_DETAILS))
1545 fprintf (dump_file, " constraint key = %d\n",
1546 next_key);
1548 proto->key = next_key++;
1550 /* Too many hash keys generated. */
1551 gcc_assert (proto->key <= MAX_KEYS);
1553 if (hashCode >= 0)
1554 pb->geqs[e].key = proto->key;
1555 else
1556 pb->geqs[e].key = -proto->key;
1558 break;
1561 j = (j + 1) % HASH_TABLE_SIZE;
1562 } while (1);
1565 pb->geqs[e].touched = 0;
1569 int eKey = pb->geqs[e].key;
1570 int e2;
1571 if (e > 0)
1573 int cTerm = pb->geqs[e].coef[0];
1574 e2 = fast_lookup[MAX_KEYS - eKey];
1576 if (e2 < e && pb->geqs[e2].key == -eKey
1577 && pb->geqs[e2].color == omega_black)
1579 if (pb->geqs[e2].coef[0] < -cTerm)
1581 if (dump_file && (dump_flags & TDF_DETAILS))
1583 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1584 fprintf (dump_file, "\n");
1585 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1586 fprintf (dump_file,
1587 "\nequations have no solution \n");
1589 return normalize_false;
1592 if (pb->geqs[e2].coef[0] == -cTerm
1593 && (create_color
1594 || pb->geqs[e].color == omega_black))
1596 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1597 pb->num_vars);
1598 if (pb->geqs[e].color == omega_black)
1599 adding_equality_constraint (pb, pb->num_eqs);
1600 pb->num_eqs++;
1601 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1605 e2 = fast_lookup_red[MAX_KEYS - eKey];
1607 if (e2 < e && pb->geqs[e2].key == -eKey
1608 && pb->geqs[e2].color == omega_red)
1610 if (pb->geqs[e2].coef[0] < -cTerm)
1612 if (dump_file && (dump_flags & TDF_DETAILS))
1614 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1615 fprintf (dump_file, "\n");
1616 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1617 fprintf (dump_file,
1618 "\nequations have no solution \n");
1620 return normalize_false;
1623 if (pb->geqs[e2].coef[0] == -cTerm && create_color)
1625 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1626 pb->num_vars);
1627 pb->eqs[pb->num_eqs].color = omega_red;
1628 pb->num_eqs++;
1629 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1633 e2 = fast_lookup[MAX_KEYS + eKey];
1635 if (e2 < e && pb->geqs[e2].key == eKey
1636 && pb->geqs[e2].color == omega_black)
1638 if (pb->geqs[e2].coef[0] > cTerm)
1640 if (pb->geqs[e].color == omega_black)
1642 if (dump_file && (dump_flags & TDF_DETAILS))
1644 fprintf (dump_file,
1645 "Removing Redundant Equation: ");
1646 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1647 fprintf (dump_file, "\n");
1648 fprintf (dump_file,
1649 "[a] Made Redundant by: ");
1650 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1651 fprintf (dump_file, "\n");
1653 pb->geqs[e2].coef[0] = cTerm;
1654 omega_delete_geq (pb, e, n_vars);
1655 e--;
1656 continue;
1659 else
1661 if (dump_file && (dump_flags & TDF_DETAILS))
1663 fprintf (dump_file, "Removing Redundant Equation: ");
1664 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1665 fprintf (dump_file, "\n");
1666 fprintf (dump_file, "[b] Made Redundant by: ");
1667 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1668 fprintf (dump_file, "\n");
1670 omega_delete_geq (pb, e, n_vars);
1671 e--;
1672 continue;
1676 e2 = fast_lookup_red[MAX_KEYS + eKey];
1678 if (e2 < e && pb->geqs[e2].key == eKey
1679 && pb->geqs[e2].color == omega_red)
1681 if (pb->geqs[e2].coef[0] >= cTerm)
1683 if (dump_file && (dump_flags & TDF_DETAILS))
1685 fprintf (dump_file, "Removing Redundant Equation: ");
1686 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1687 fprintf (dump_file, "\n");
1688 fprintf (dump_file, "[c] Made Redundant by: ");
1689 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1690 fprintf (dump_file, "\n");
1692 pb->geqs[e2].coef[0] = cTerm;
1693 pb->geqs[e2].color = pb->geqs[e].color;
1695 else if (pb->geqs[e].color == omega_red)
1697 if (dump_file && (dump_flags & TDF_DETAILS))
1699 fprintf (dump_file, "Removing Redundant Equation: ");
1700 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1701 fprintf (dump_file, "\n");
1702 fprintf (dump_file, "[d] Made Redundant by: ");
1703 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1704 fprintf (dump_file, "\n");
1707 omega_delete_geq (pb, e, n_vars);
1708 e--;
1709 continue;
1714 if (pb->geqs[e].color == omega_red)
1715 fast_lookup_red[MAX_KEYS + eKey] = e;
1716 else
1717 fast_lookup[MAX_KEYS + eKey] = e;
1721 create_color = false;
1722 return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
1725 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1726 of variables in EQN. */
1728 static inline void
1729 divide_eqn_by_gcd (eqn eqn, int n_vars)
1731 int var, g = 0;
1733 for (var = n_vars; var >= 0; var--)
1734 g = gcd (abs (eqn->coef[var]), g);
1736 if (g)
1737 for (var = n_vars; var >= 0; var--)
1738 eqn->coef[var] = eqn->coef[var] / g;
1741 /* Rewrite some non-safe variables in function of protected
1742 wildcard variables. */
1744 static void
1745 cleanout_wildcards (omega_pb pb)
1747 int e, i, j;
1748 int n_vars = pb->num_vars;
1749 bool renormalize = false;
1751 for (e = pb->num_eqs - 1; e >= 0; e--)
1752 for (i = n_vars; !omega_safe_var_p (pb, i); i--)
1753 if (pb->eqs[e].coef[i] != 0)
1755 /* i is the last nonzero non-safe variable. */
1757 for (j = i - 1; !omega_safe_var_p (pb, j); j--)
1758 if (pb->eqs[e].coef[j] != 0)
1759 break;
1761 /* j is the next nonzero non-safe variable, or points
1762 to a safe variable: it is then a wildcard variable. */
1764 /* Clean it out. */
1765 if (omega_safe_var_p (pb, j))
1767 eqn sub = &(pb->eqs[e]);
1768 int c = pb->eqs[e].coef[i];
1769 int a = abs (c);
1770 int e2;
1772 if (dump_file && (dump_flags & TDF_DETAILS))
1774 fprintf (dump_file,
1775 "Found a single wild card equality: ");
1776 omega_print_eq (dump_file, pb, &pb->eqs[e]);
1777 fprintf (dump_file, "\n");
1778 omega_print_problem (dump_file, pb);
1781 for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
1782 if (e != e2 && pb->eqs[e2].coef[i]
1783 && (pb->eqs[e2].color == omega_red
1784 || (pb->eqs[e2].color == omega_black
1785 && pb->eqs[e].color == omega_black)))
1787 eqn eqn = &(pb->eqs[e2]);
1788 int var, k;
1790 for (var = n_vars; var >= 0; var--)
1791 eqn->coef[var] *= a;
1793 k = eqn->coef[i];
1795 for (var = n_vars; var >= 0; var--)
1796 eqn->coef[var] -= sub->coef[var] * k / c;
1798 eqn->coef[i] = 0;
1799 divide_eqn_by_gcd (eqn, n_vars);
1802 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
1803 if (pb->geqs[e2].coef[i]
1804 && (pb->geqs[e2].color == omega_red
1805 || (pb->eqs[e].color == omega_black
1806 && pb->geqs[e2].color == omega_black)))
1808 eqn eqn = &(pb->geqs[e2]);
1809 int var, k;
1811 for (var = n_vars; var >= 0; var--)
1812 eqn->coef[var] *= a;
1814 k = eqn->coef[i];
1816 for (var = n_vars; var >= 0; var--)
1817 eqn->coef[var] -= sub->coef[var] * k / c;
1819 eqn->coef[i] = 0;
1820 eqn->touched = 1;
1821 renormalize = true;
1824 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
1825 if (pb->subs[e2].coef[i]
1826 && (pb->subs[e2].color == omega_red
1827 || (pb->subs[e2].color == omega_black
1828 && pb->eqs[e].color == omega_black)))
1830 eqn eqn = &(pb->subs[e2]);
1831 int var, k;
1833 for (var = n_vars; var >= 0; var--)
1834 eqn->coef[var] *= a;
1836 k = eqn->coef[i];
1838 for (var = n_vars; var >= 0; var--)
1839 eqn->coef[var] -= sub->coef[var] * k / c;
1841 eqn->coef[i] = 0;
1842 divide_eqn_by_gcd (eqn, n_vars);
1845 if (dump_file && (dump_flags & TDF_DETAILS))
1847 fprintf (dump_file, "cleaned-out wildcard: ");
1848 omega_print_problem (dump_file, pb);
1850 break;
1854 if (renormalize)
1855 normalize_omega_problem (pb);
1858 /* Swap values contained in I and J. */
1860 static inline void
1861 swap (int *i, int *j)
1863 int tmp;
1864 tmp = *i;
1865 *i = *j;
1866 *j = tmp;
1869 /* Swap values contained in I and J. */
1871 static inline void
1872 bswap (bool *i, bool *j)
1874 bool tmp;
1875 tmp = *i;
1876 *i = *j;
1877 *j = tmp;
1880 /* Make variable IDX unprotected in PB, by swapping its index at the
1881 PB->safe_vars rank. */
1883 static inline void
1884 omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
1886 /* If IDX is protected... */
1887 if (*idx < pb->safe_vars)
1889 /* ... swap its index with the last non protected index. */
1890 int j = pb->safe_vars;
1891 int e;
1893 for (e = pb->num_geqs - 1; e >= 0; e--)
1895 pb->geqs[e].touched = 1;
1896 swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
1899 for (e = pb->num_eqs - 1; e >= 0; e--)
1900 swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
1902 for (e = pb->num_subs - 1; e >= 0; e--)
1903 swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
1905 if (unprotect)
1906 bswap (&unprotect[*idx], &unprotect[j]);
1908 swap (&pb->var[*idx], &pb->var[j]);
1909 pb->forwarding_address[pb->var[*idx]] = *idx;
1910 pb->forwarding_address[pb->var[j]] = j;
1911 (*idx)--;
1914 /* The variable at pb->safe_vars is also unprotected now. */
1915 pb->safe_vars--;
1918 /* During the Fourier-Motzkin elimination some variables are
1919 substituted with other variables. This function resurrects the
1920 substituted variables in PB. */
1922 static void
1923 resurrect_subs (omega_pb pb)
1925 if (pb->num_subs > 0
1926 && please_no_equalities_in_simplified_problems == 0)
1928 int i, e, m;
1930 if (dump_file && (dump_flags & TDF_DETAILS))
1932 fprintf (dump_file,
1933 "problem reduced, bringing variables back to life\n");
1934 omega_print_problem (dump_file, pb);
1937 for (i = 1; omega_safe_var_p (pb, i); i++)
1938 if (omega_wildcard_p (pb, i))
1939 omega_unprotect_1 (pb, &i, NULL);
1941 m = pb->num_subs;
1943 for (e = pb->num_geqs - 1; e >= 0; e--)
1944 if (single_var_geq (&pb->geqs[e], pb->num_vars))
1946 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
1947 pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
1949 else
1951 pb->geqs[e].touched = 1;
1952 pb->geqs[e].key = 0;
1955 for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
1957 pb->var[i + m] = pb->var[i];
1959 for (e = pb->num_geqs - 1; e >= 0; e--)
1960 pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
1962 for (e = pb->num_eqs - 1; e >= 0; e--)
1963 pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
1965 for (e = pb->num_subs - 1; e >= 0; e--)
1966 pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
1969 for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
1971 for (e = pb->num_geqs - 1; e >= 0; e--)
1972 pb->geqs[e].coef[i] = 0;
1974 for (e = pb->num_eqs - 1; e >= 0; e--)
1975 pb->eqs[e].coef[i] = 0;
1977 for (e = pb->num_subs - 1; e >= 0; e--)
1978 pb->subs[e].coef[i] = 0;
1981 pb->num_vars += m;
1983 for (e = pb->num_subs - 1; e >= 0; e--)
1985 pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
1986 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
1987 pb->num_vars);
1988 pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
1989 pb->eqs[pb->num_eqs].color = omega_black;
1991 if (dump_file && (dump_flags & TDF_DETAILS))
1993 fprintf (dump_file, "brought back: ");
1994 omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
1995 fprintf (dump_file, "\n");
1998 pb->num_eqs++;
1999 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2002 pb->safe_vars += m;
2003 pb->num_subs = 0;
2005 if (dump_file && (dump_flags & TDF_DETAILS))
2007 fprintf (dump_file, "variables brought back to life\n");
2008 omega_print_problem (dump_file, pb);
2011 cleanout_wildcards (pb);
2015 static inline bool
2016 implies (unsigned int a, unsigned int b)
2018 return (a == (a & b));
2021 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2022 extra step is performed. Returns omega_false when there exist no
2023 solution, omega_true otherwise. */
2025 enum omega_result
2026 omega_eliminate_redundant (omega_pb pb, bool expensive)
2028 int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
2029 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2030 omega_pb tmp_problem;
2032 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2033 unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2034 unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2035 unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2037 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2038 unsigned int pp, pz, pn;
2040 if (dump_file && (dump_flags & TDF_DETAILS))
2042 fprintf (dump_file, "in eliminate Redundant:\n");
2043 omega_print_problem (dump_file, pb);
2046 for (e = pb->num_geqs - 1; e >= 0; e--)
2048 int tmp = 1;
2050 is_dead[e] = false;
2051 peqs[e] = zeqs[e] = neqs[e] = 0;
2053 for (i = pb->num_vars; i >= 1; i--)
2055 if (pb->geqs[e].coef[i] > 0)
2056 peqs[e] |= tmp;
2057 else if (pb->geqs[e].coef[i] < 0)
2058 neqs[e] |= tmp;
2059 else
2060 zeqs[e] |= tmp;
2062 tmp <<= 1;
2067 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2068 if (!is_dead[e1])
2069 for (e2 = e1 - 1; e2 >= 0; e2--)
2070 if (!is_dead[e2])
2072 for (p = pb->num_vars; p > 1; p--)
2073 for (q = p - 1; q > 0; q--)
2074 if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
2075 - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
2076 goto foundPQ;
2078 continue;
2080 foundPQ:
2081 pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
2082 | (neqs[e1] & peqs[e2]));
2083 pp = peqs[e1] | peqs[e2];
2084 pn = neqs[e1] | neqs[e2];
2086 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2087 if (e3 != e1 && e3 != e2)
2089 if (!implies (zeqs[e3], pz))
2090 goto nextE3;
2092 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2093 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2094 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2095 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2096 alpha3 = alpha;
2098 if (alpha1 * alpha2 <= 0)
2099 goto nextE3;
2101 if (alpha1 < 0)
2103 alpha1 = -alpha1;
2104 alpha2 = -alpha2;
2105 alpha3 = -alpha3;
2108 if (alpha3 > 0)
2110 /* Trying to prove e3 is redundant. */
2111 if (!implies (peqs[e3], pp)
2112 || !implies (neqs[e3], pn))
2113 goto nextE3;
2115 if (pb->geqs[e3].color == omega_black
2116 && (pb->geqs[e1].color == omega_red
2117 || pb->geqs[e2].color == omega_red))
2118 goto nextE3;
2120 for (k = pb->num_vars; k >= 1; k--)
2121 if (alpha3 * pb->geqs[e3].coef[k]
2122 != (alpha1 * pb->geqs[e1].coef[k]
2123 + alpha2 * pb->geqs[e2].coef[k]))
2124 goto nextE3;
2126 c = (alpha1 * pb->geqs[e1].coef[0]
2127 + alpha2 * pb->geqs[e2].coef[0]);
2129 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2131 if (dump_file && (dump_flags & TDF_DETAILS))
2133 fprintf (dump_file,
2134 "found redundant inequality\n");
2135 fprintf (dump_file,
2136 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2137 alpha1, alpha2, alpha3);
2139 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2140 fprintf (dump_file, "\n");
2141 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2142 fprintf (dump_file, "\n=> ");
2143 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2144 fprintf (dump_file, "\n\n");
2147 is_dead[e3] = true;
2150 else
2152 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2153 or trying to prove e3 < 0, and therefore the
2154 problem has no solutions. */
2155 if (!implies (peqs[e3], pn)
2156 || !implies (neqs[e3], pp))
2157 goto nextE3;
2159 if (pb->geqs[e1].color == omega_red
2160 || pb->geqs[e2].color == omega_red
2161 || pb->geqs[e3].color == omega_red)
2162 goto nextE3;
2164 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2165 for (k = pb->num_vars; k >= 1; k--)
2166 if (alpha3 * pb->geqs[e3].coef[k]
2167 != (alpha1 * pb->geqs[e1].coef[k]
2168 + alpha2 * pb->geqs[e2].coef[k]))
2169 goto nextE3;
2171 c = (alpha1 * pb->geqs[e1].coef[0]
2172 + alpha2 * pb->geqs[e2].coef[0]);
2174 if (c < alpha3 * (pb->geqs[e3].coef[0]))
2176 /* We just proved e3 < 0, so no solutions exist. */
2177 if (dump_file && (dump_flags & TDF_DETAILS))
2179 fprintf (dump_file,
2180 "found implied over tight inequality\n");
2181 fprintf (dump_file,
2182 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2183 alpha1, alpha2, -alpha3);
2184 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2185 fprintf (dump_file, "\n");
2186 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2187 fprintf (dump_file, "\n=> not ");
2188 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2189 fprintf (dump_file, "\n\n");
2191 free (is_dead);
2192 free (peqs);
2193 free (zeqs);
2194 free (neqs);
2195 return omega_false;
2197 else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2199 /* We just proved that e3 <=0, so e3 = 0. */
2200 if (dump_file && (dump_flags & TDF_DETAILS))
2202 fprintf (dump_file,
2203 "found implied tight inequality\n");
2204 fprintf (dump_file,
2205 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2206 alpha1, alpha2, -alpha3);
2207 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2208 fprintf (dump_file, "\n");
2209 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2210 fprintf (dump_file, "\n=> inverse ");
2211 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2212 fprintf (dump_file, "\n\n");
2215 omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2216 &pb->geqs[e3], pb->num_vars);
2217 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2218 adding_equality_constraint (pb, pb->num_eqs - 1);
2219 is_dead[e3] = true;
2222 nextE3:;
2226 /* Delete the inequalities that were marked as dead. */
2227 for (e = pb->num_geqs - 1; e >= 0; e--)
2228 if (is_dead[e])
2229 omega_delete_geq (pb, e, pb->num_vars);
2231 if (!expensive)
2232 goto eliminate_redundant_done;
2234 tmp_problem = XNEW (struct omega_pb_d);
2235 conservative++;
2237 for (e = pb->num_geqs - 1; e >= 0; e--)
2239 if (dump_file && (dump_flags & TDF_DETAILS))
2241 fprintf (dump_file,
2242 "checking equation %d to see if it is redundant: ", e);
2243 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2244 fprintf (dump_file, "\n");
2247 omega_copy_problem (tmp_problem, pb);
2248 omega_negate_geq (tmp_problem, e);
2249 tmp_problem->safe_vars = 0;
2250 tmp_problem->variables_freed = false;
2252 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2253 omega_delete_geq (pb, e, pb->num_vars);
2256 free (tmp_problem);
2257 conservative--;
2259 if (!omega_reduce_with_subs)
2261 resurrect_subs (pb);
2262 gcc_assert (please_no_equalities_in_simplified_problems
2263 || pb->num_subs == 0);
2266 eliminate_redundant_done:
2267 free (is_dead);
2268 free (peqs);
2269 free (zeqs);
2270 free (neqs);
2271 return omega_true;
2274 /* For each inequality that has coefficients bigger than 20, try to
2275 create a new constraint that cannot be derived from the original
2276 constraint and that has smaller coefficients. Add the new
2277 constraint at the end of geqs. Return the number of inequalities
2278 that have been added to PB. */
2280 static int
2281 smooth_weird_equations (omega_pb pb)
2283 int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2284 int c;
2285 int v;
2286 int result = 0;
2288 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2289 if (pb->geqs[e1].color == omega_black)
2291 int g = 999999;
2293 for (v = pb->num_vars; v >= 1; v--)
2294 if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2295 g = abs (pb->geqs[e1].coef[v]);
2297 /* Magic number. */
2298 if (g > 20)
2300 e3 = pb->num_geqs;
2302 for (v = pb->num_vars; v >= 1; v--)
2303 pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2306 pb->geqs[e3].color = omega_black;
2307 pb->geqs[e3].touched = 1;
2308 /* Magic number. */
2309 pb->geqs[e3].coef[0] = 9997;
2311 if (dump_file && (dump_flags & TDF_DETAILS))
2313 fprintf (dump_file, "Checking to see if we can derive: ");
2314 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2315 fprintf (dump_file, "\n from: ");
2316 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2317 fprintf (dump_file, "\n");
2320 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2321 if (e1 != e2 && pb->geqs[e2].color == omega_black)
2323 for (p = pb->num_vars; p > 1; p--)
2325 for (q = p - 1; q > 0; q--)
2327 alpha =
2328 (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2329 pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2330 if (alpha != 0)
2331 goto foundPQ;
2334 continue;
2336 foundPQ:
2338 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2339 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2340 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2341 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2342 alpha3 = alpha;
2344 if (alpha1 * alpha2 <= 0)
2345 continue;
2347 if (alpha1 < 0)
2349 alpha1 = -alpha1;
2350 alpha2 = -alpha2;
2351 alpha3 = -alpha3;
2354 if (alpha3 > 0)
2356 /* Try to prove e3 is redundant: verify
2357 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2358 for (k = pb->num_vars; k >= 1; k--)
2359 if (alpha3 * pb->geqs[e3].coef[k]
2360 != (alpha1 * pb->geqs[e1].coef[k]
2361 + alpha2 * pb->geqs[e2].coef[k]))
2362 goto nextE2;
2364 c = alpha1 * pb->geqs[e1].coef[0]
2365 + alpha2 * pb->geqs[e2].coef[0];
2367 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2368 pb->geqs[e3].coef[0] = int_div (c, alpha3);
2370 nextE2:;
2373 if (pb->geqs[e3].coef[0] < 9997)
2375 result++;
2376 pb->num_geqs++;
2378 if (dump_file && (dump_flags & TDF_DETAILS))
2380 fprintf (dump_file,
2381 "Smoothing weird equations; adding:\n");
2382 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2383 fprintf (dump_file, "\nto:\n");
2384 omega_print_problem (dump_file, pb);
2385 fprintf (dump_file, "\n\n");
2390 return result;
2393 /* Replace tuples of inequalities, that define upper and lower half
2394 spaces, with an equation. */
2396 static void
2397 coalesce (omega_pb pb)
2399 int e, e2;
2400 int colors = 0;
2401 bool *is_dead;
2402 int found_something = 0;
2404 for (e = 0; e < pb->num_geqs; e++)
2405 if (pb->geqs[e].color == omega_red)
2406 colors++;
2408 if (colors < 2)
2409 return;
2411 is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2413 for (e = 0; e < pb->num_geqs; e++)
2414 is_dead[e] = false;
2416 for (e = 0; e < pb->num_geqs; e++)
2417 if (pb->geqs[e].color == omega_red
2418 && !pb->geqs[e].touched)
2419 for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2420 if (!pb->geqs[e2].touched
2421 && pb->geqs[e].key == -pb->geqs[e2].key
2422 && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2423 && pb->geqs[e2].color == omega_red)
2425 omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2426 pb->num_vars);
2427 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2428 found_something++;
2429 is_dead[e] = true;
2430 is_dead[e2] = true;
2433 for (e = pb->num_geqs - 1; e >= 0; e--)
2434 if (is_dead[e])
2435 omega_delete_geq (pb, e, pb->num_vars);
2437 if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2439 fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2440 found_something);
2441 omega_print_problem (dump_file, pb);
2444 free (is_dead);
2447 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2448 true, continue to eliminate all the red inequalities. */
2450 void
2451 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2453 int e, e2, e3, i, j, k, a, alpha1, alpha2;
2454 int c = 0;
2455 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2456 int dead_count = 0;
2457 int red_found;
2458 omega_pb tmp_problem;
2460 if (dump_file && (dump_flags & TDF_DETAILS))
2462 fprintf (dump_file, "in eliminate RED:\n");
2463 omega_print_problem (dump_file, pb);
2466 if (pb->num_eqs > 0)
2467 omega_simplify_problem (pb);
2469 for (e = pb->num_geqs - 1; e >= 0; e--)
2470 is_dead[e] = false;
2472 for (e = pb->num_geqs - 1; e >= 0; e--)
2473 if (pb->geqs[e].color == omega_black && !is_dead[e])
2474 for (e2 = e - 1; e2 >= 0; e2--)
2475 if (pb->geqs[e2].color == omega_black
2476 && !is_dead[e2])
2478 a = 0;
2480 for (i = pb->num_vars; i > 1; i--)
2481 for (j = i - 1; j > 0; j--)
2482 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2483 - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2484 goto found_pair;
2486 continue;
2488 found_pair:
2489 if (dump_file && (dump_flags & TDF_DETAILS))
2491 fprintf (dump_file,
2492 "found two equations to combine, i = %s, ",
2493 omega_variable_to_str (pb, i));
2494 fprintf (dump_file, "j = %s, alpha = %d\n",
2495 omega_variable_to_str (pb, j), a);
2496 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2497 fprintf (dump_file, "\n");
2498 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2499 fprintf (dump_file, "\n");
2502 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2503 if (pb->geqs[e3].color == omega_red)
2505 alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2506 - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2507 alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2508 - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2510 if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2511 || (a < 0 && alpha1 < 0 && alpha2 < 0))
2513 if (dump_file && (dump_flags & TDF_DETAILS))
2515 fprintf (dump_file,
2516 "alpha1 = %d, alpha2 = %d;"
2517 "comparing against: ",
2518 alpha1, alpha2);
2519 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2520 fprintf (dump_file, "\n");
2523 for (k = pb->num_vars; k >= 0; k--)
2525 c = (alpha1 * pb->geqs[e].coef[k]
2526 + alpha2 * pb->geqs[e2].coef[k]);
2528 if (c != a * pb->geqs[e3].coef[k])
2529 break;
2531 if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2532 fprintf (dump_file, " %s: %d, %d\n",
2533 omega_variable_to_str (pb, k), c,
2534 a * pb->geqs[e3].coef[k]);
2537 if (k < 0
2538 || (k == 0 &&
2539 ((a > 0 && c < a * pb->geqs[e3].coef[k])
2540 || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2542 if (dump_file && (dump_flags & TDF_DETAILS))
2544 dead_count++;
2545 fprintf (dump_file,
2546 "red equation#%d is dead "
2547 "(%d dead so far, %d remain)\n",
2548 e3, dead_count,
2549 pb->num_geqs - dead_count);
2550 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2551 fprintf (dump_file, "\n");
2552 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2553 fprintf (dump_file, "\n");
2554 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2555 fprintf (dump_file, "\n");
2557 is_dead[e3] = true;
2563 for (e = pb->num_geqs - 1; e >= 0; e--)
2564 if (is_dead[e])
2565 omega_delete_geq (pb, e, pb->num_vars);
2567 free (is_dead);
2569 if (dump_file && (dump_flags & TDF_DETAILS))
2571 fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2572 omega_print_problem (dump_file, pb);
2575 for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2576 if (pb->geqs[e].color == omega_red)
2577 red_found = 1;
2579 if (!red_found)
2581 if (dump_file && (dump_flags & TDF_DETAILS))
2582 fprintf (dump_file, "fast checks worked\n");
2584 if (!omega_reduce_with_subs)
2585 gcc_assert (please_no_equalities_in_simplified_problems
2586 || pb->num_subs == 0);
2588 return;
2591 if (!omega_verify_simplification
2592 && verify_omega_pb (pb) == omega_false)
2593 return;
2595 conservative++;
2596 tmp_problem = XNEW (struct omega_pb_d);
2598 for (e = pb->num_geqs - 1; e >= 0; e--)
2599 if (pb->geqs[e].color == omega_red)
2601 if (dump_file && (dump_flags & TDF_DETAILS))
2603 fprintf (dump_file,
2604 "checking equation %d to see if it is redundant: ", e);
2605 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2606 fprintf (dump_file, "\n");
2609 omega_copy_problem (tmp_problem, pb);
2610 omega_negate_geq (tmp_problem, e);
2611 tmp_problem->safe_vars = 0;
2612 tmp_problem->variables_freed = false;
2613 tmp_problem->num_subs = 0;
2615 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2617 if (dump_file && (dump_flags & TDF_DETAILS))
2618 fprintf (dump_file, "it is redundant\n");
2619 omega_delete_geq (pb, e, pb->num_vars);
2621 else
2623 if (dump_file && (dump_flags & TDF_DETAILS))
2624 fprintf (dump_file, "it is not redundant\n");
2626 if (!eliminate_all)
2628 if (dump_file && (dump_flags & TDF_DETAILS))
2629 fprintf (dump_file, "no need to check other red equations\n");
2630 break;
2635 conservative--;
2636 free (tmp_problem);
2637 /* omega_simplify_problem (pb); */
2639 if (!omega_reduce_with_subs)
2640 gcc_assert (please_no_equalities_in_simplified_problems
2641 || pb->num_subs == 0);
2644 /* Transform some wildcard variables to non-safe variables. */
2646 static void
2647 chain_unprotect (omega_pb pb)
2649 int i, e;
2650 bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2652 for (i = 1; omega_safe_var_p (pb, i); i++)
2654 unprotect[i] = omega_wildcard_p (pb, i);
2656 for (e = pb->num_subs - 1; e >= 0; e--)
2657 if (pb->subs[e].coef[i])
2658 unprotect[i] = false;
2661 if (dump_file && (dump_flags & TDF_DETAILS))
2663 fprintf (dump_file, "Doing chain reaction unprotection\n");
2664 omega_print_problem (dump_file, pb);
2666 for (i = 1; omega_safe_var_p (pb, i); i++)
2667 if (unprotect[i])
2668 fprintf (dump_file, "unprotecting %s\n",
2669 omega_variable_to_str (pb, i));
2672 for (i = 1; omega_safe_var_p (pb, i); i++)
2673 if (unprotect[i])
2674 omega_unprotect_1 (pb, &i, unprotect);
2676 if (dump_file && (dump_flags & TDF_DETAILS))
2678 fprintf (dump_file, "After chain reactions\n");
2679 omega_print_problem (dump_file, pb);
2682 free (unprotect);
2685 /* Reduce problem PB. */
2687 static void
2688 omega_problem_reduced (omega_pb pb)
2690 if (omega_verify_simplification
2691 && !in_approximate_mode
2692 && verify_omega_pb (pb) == omega_false)
2693 return;
2695 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2696 && !omega_eliminate_redundant (pb, true))
2697 return;
2699 omega_found_reduction = omega_true;
2701 if (!please_no_equalities_in_simplified_problems)
2702 coalesce (pb);
2704 if (omega_reduce_with_subs
2705 || please_no_equalities_in_simplified_problems)
2706 chain_unprotect (pb);
2707 else
2708 resurrect_subs (pb);
2710 if (!return_single_result)
2712 int i;
2714 for (i = 1; omega_safe_var_p (pb, i); i++)
2715 pb->forwarding_address[pb->var[i]] = i;
2717 for (i = 0; i < pb->num_subs; i++)
2718 pb->forwarding_address[pb->subs[i].key] = -i - 1;
2720 (*omega_when_reduced) (pb);
2723 if (dump_file && (dump_flags & TDF_DETAILS))
2725 fprintf (dump_file, "-------------------------------------------\n");
2726 fprintf (dump_file, "problem reduced:\n");
2727 omega_print_problem (dump_file, pb);
2728 fprintf (dump_file, "-------------------------------------------\n");
2732 /* Eliminates all the free variables for problem PB, that is all the
2733 variables from FV to PB->NUM_VARS. */
2735 static void
2736 omega_free_eliminations (omega_pb pb, int fv)
2738 bool try_again = true;
2739 int i, e, e2;
2740 int n_vars = pb->num_vars;
2742 while (try_again)
2744 try_again = false;
2746 for (i = n_vars; i > fv; i--)
2748 for (e = pb->num_geqs - 1; e >= 0; e--)
2749 if (pb->geqs[e].coef[i])
2750 break;
2752 if (e < 0)
2753 e2 = e;
2754 else if (pb->geqs[e].coef[i] > 0)
2756 for (e2 = e - 1; e2 >= 0; e2--)
2757 if (pb->geqs[e2].coef[i] < 0)
2758 break;
2760 else
2762 for (e2 = e - 1; e2 >= 0; e2--)
2763 if (pb->geqs[e2].coef[i] > 0)
2764 break;
2767 if (e2 < 0)
2769 int e3;
2770 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2771 if (pb->subs[e3].coef[i])
2772 break;
2774 if (e3 >= 0)
2775 continue;
2777 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2778 if (pb->eqs[e3].coef[i])
2779 break;
2781 if (e3 >= 0)
2782 continue;
2784 if (dump_file && (dump_flags & TDF_DETAILS))
2785 fprintf (dump_file, "a free elimination of %s\n",
2786 omega_variable_to_str (pb, i));
2788 if (e >= 0)
2790 omega_delete_geq (pb, e, n_vars);
2792 for (e--; e >= 0; e--)
2793 if (pb->geqs[e].coef[i])
2794 omega_delete_geq (pb, e, n_vars);
2796 try_again = (i < n_vars);
2799 omega_delete_variable (pb, i);
2800 n_vars = pb->num_vars;
2805 if (dump_file && (dump_flags & TDF_DETAILS))
2807 fprintf (dump_file, "\nafter free eliminations:\n");
2808 omega_print_problem (dump_file, pb);
2809 fprintf (dump_file, "\n");
2813 /* Do free red eliminations. */
2815 static void
2816 free_red_eliminations (omega_pb pb)
2818 bool try_again = true;
2819 int i, e, e2;
2820 int n_vars = pb->num_vars;
2821 bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2822 bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2823 bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2825 for (i = n_vars; i > 0; i--)
2827 is_red_var[i] = false;
2828 is_dead_var[i] = false;
2831 for (e = pb->num_geqs - 1; e >= 0; e--)
2833 is_dead_geq[e] = false;
2835 if (pb->geqs[e].color == omega_red)
2836 for (i = n_vars; i > 0; i--)
2837 if (pb->geqs[e].coef[i] != 0)
2838 is_red_var[i] = true;
2841 while (try_again)
2843 try_again = false;
2844 for (i = n_vars; i > 0; i--)
2845 if (!is_red_var[i] && !is_dead_var[i])
2847 for (e = pb->num_geqs - 1; e >= 0; e--)
2848 if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2849 break;
2851 if (e < 0)
2852 e2 = e;
2853 else if (pb->geqs[e].coef[i] > 0)
2855 for (e2 = e - 1; e2 >= 0; e2--)
2856 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2857 break;
2859 else
2861 for (e2 = e - 1; e2 >= 0; e2--)
2862 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2863 break;
2866 if (e2 < 0)
2868 int e3;
2869 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2870 if (pb->subs[e3].coef[i])
2871 break;
2873 if (e3 >= 0)
2874 continue;
2876 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2877 if (pb->eqs[e3].coef[i])
2878 break;
2880 if (e3 >= 0)
2881 continue;
2883 if (dump_file && (dump_flags & TDF_DETAILS))
2884 fprintf (dump_file, "a free red elimination of %s\n",
2885 omega_variable_to_str (pb, i));
2887 for (; e >= 0; e--)
2888 if (pb->geqs[e].coef[i])
2889 is_dead_geq[e] = true;
2891 try_again = true;
2892 is_dead_var[i] = true;
2897 for (e = pb->num_geqs - 1; e >= 0; e--)
2898 if (is_dead_geq[e])
2899 omega_delete_geq (pb, e, n_vars);
2901 for (i = n_vars; i > 0; i--)
2902 if (is_dead_var[i])
2903 omega_delete_variable (pb, i);
2905 if (dump_file && (dump_flags & TDF_DETAILS))
2907 fprintf (dump_file, "\nafter free red eliminations:\n");
2908 omega_print_problem (dump_file, pb);
2909 fprintf (dump_file, "\n");
2912 free (is_red_var);
2913 free (is_dead_var);
2914 free (is_dead_geq);
2917 /* For equation EQ of the form "0 = EQN", insert in PB two
2918 inequalities "0 <= EQN" and "0 <= -EQN". */
2920 void
2921 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2923 int i;
2925 if (dump_file && (dump_flags & TDF_DETAILS))
2926 fprintf (dump_file, "Converting Eq to Geqs\n");
2928 /* Insert "0 <= EQN". */
2929 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2930 pb->geqs[pb->num_geqs].touched = 1;
2931 pb->num_geqs++;
2933 /* Insert "0 <= -EQN". */
2934 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2935 pb->geqs[pb->num_geqs].touched = 1;
2937 for (i = 0; i <= pb->num_vars; i++)
2938 pb->geqs[pb->num_geqs].coef[i] *= -1;
2940 pb->num_geqs++;
2942 if (dump_file && (dump_flags & TDF_DETAILS))
2943 omega_print_problem (dump_file, pb);
2946 /* Eliminates variable I from PB. */
2948 static void
2949 omega_do_elimination (omega_pb pb, int e, int i)
2951 eqn sub = omega_alloc_eqns (0, 1);
2952 int c;
2953 int n_vars = pb->num_vars;
2955 if (dump_file && (dump_flags & TDF_DETAILS))
2956 fprintf (dump_file, "eliminating variable %s\n",
2957 omega_variable_to_str (pb, i));
2959 omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
2960 c = sub->coef[i];
2961 sub->coef[i] = 0;
2962 if (c == 1 || c == -1)
2964 if (pb->eqs[e].color == omega_red)
2966 bool fB;
2967 omega_substitute_red (pb, sub, i, c, &fB);
2968 if (fB)
2969 omega_convert_eq_to_geqs (pb, e);
2970 else
2971 omega_delete_variable (pb, i);
2973 else
2975 omega_substitute (pb, sub, i, c);
2976 omega_delete_variable (pb, i);
2979 else
2981 int a = abs (c);
2982 int e2 = e;
2984 if (dump_file && (dump_flags & TDF_DETAILS))
2985 fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
2987 for (e = pb->num_eqs - 1; e >= 0; e--)
2988 if (pb->eqs[e].coef[i])
2990 eqn eqn = &(pb->eqs[e]);
2991 int j, k;
2992 for (j = n_vars; j >= 0; j--)
2993 eqn->coef[j] *= a;
2994 k = eqn->coef[i];
2995 eqn->coef[i] = 0;
2996 if (sub->color == omega_red)
2997 eqn->color = omega_red;
2998 for (j = n_vars; j >= 0; j--)
2999 eqn->coef[j] -= sub->coef[j] * k / c;
3002 for (e = pb->num_geqs - 1; e >= 0; e--)
3003 if (pb->geqs[e].coef[i])
3005 eqn eqn = &(pb->geqs[e]);
3006 int j, k;
3008 if (sub->color == omega_red)
3009 eqn->color = omega_red;
3011 for (j = n_vars; j >= 0; j--)
3012 eqn->coef[j] *= a;
3014 eqn->touched = 1;
3015 k = eqn->coef[i];
3016 eqn->coef[i] = 0;
3018 for (j = n_vars; j >= 0; j--)
3019 eqn->coef[j] -= sub->coef[j] * k / c;
3023 for (e = pb->num_subs - 1; e >= 0; e--)
3024 if (pb->subs[e].coef[i])
3026 eqn eqn = &(pb->subs[e]);
3027 int j, k;
3028 gcc_assert (0);
3029 gcc_assert (sub->color == omega_black);
3030 for (j = n_vars; j >= 0; j--)
3031 eqn->coef[j] *= a;
3032 k = eqn->coef[i];
3033 eqn->coef[i] = 0;
3034 for (j = n_vars; j >= 0; j--)
3035 eqn->coef[j] -= sub->coef[j] * k / c;
3038 if (in_approximate_mode)
3039 omega_delete_variable (pb, i);
3040 else
3041 omega_convert_eq_to_geqs (pb, e2);
3044 omega_free_eqns (sub, 1);
3047 /* Helper function for printing "sorry, no solution". */
3049 static inline enum omega_result
3050 omega_problem_has_no_solution (void)
3052 if (dump_file && (dump_flags & TDF_DETAILS))
3053 fprintf (dump_file, "\nequations have no solution \n");
3055 return omega_false;
3058 /* Helper function: solve equations in PB one at a time, following the
3059 DESIRED_RES result. */
3061 static enum omega_result
3062 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3064 int i, j, e;
3065 int g, g2;
3066 g = 0;
3069 if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3071 fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3072 desired_res, may_be_red);
3073 omega_print_problem (dump_file, pb);
3074 fprintf (dump_file, "\n");
3077 if (may_be_red)
3079 i = 0;
3080 j = pb->num_eqs - 1;
3082 while (1)
3084 eqn eq;
3086 while (i <= j && pb->eqs[i].color == omega_red)
3087 i++;
3089 while (i <= j && pb->eqs[j].color == omega_black)
3090 j--;
3092 if (i >= j)
3093 break;
3095 eq = omega_alloc_eqns (0, 1);
3096 omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3097 omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3098 omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3099 omega_free_eqns (eq, 1);
3100 i++;
3101 j--;
3105 /* Eliminate all EQ equations */
3106 for (e = pb->num_eqs - 1; e >= 0; e--)
3108 eqn eqn = &(pb->eqs[e]);
3109 int sv;
3111 if (dump_file && (dump_flags & TDF_DETAILS))
3112 fprintf (dump_file, "----\n");
3114 for (i = pb->num_vars; i > 0; i--)
3115 if (eqn->coef[i])
3116 break;
3118 g = eqn->coef[i];
3120 for (j = i - 1; j > 0; j--)
3121 if (eqn->coef[j])
3122 break;
3124 /* i is the position of last nonzero coefficient,
3125 g is the coefficient of i,
3126 j is the position of next nonzero coefficient. */
3128 if (j == 0)
3130 if (eqn->coef[0] % g != 0)
3131 return omega_problem_has_no_solution ();
3133 eqn->coef[0] = eqn->coef[0] / g;
3134 eqn->coef[i] = 1;
3135 pb->num_eqs--;
3136 omega_do_elimination (pb, e, i);
3137 continue;
3140 else if (j == -1)
3142 if (eqn->coef[0] != 0)
3143 return omega_problem_has_no_solution ();
3145 pb->num_eqs--;
3146 continue;
3149 if (g < 0)
3150 g = -g;
3152 if (g == 1)
3154 pb->num_eqs--;
3155 omega_do_elimination (pb, e, i);
3158 else
3160 int k = j;
3161 bool promotion_possible =
3162 (omega_safe_var_p (pb, j)
3163 && pb->safe_vars + 1 == i
3164 && !omega_eqn_is_red (eqn, desired_res)
3165 && !in_approximate_mode);
3167 if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3168 fprintf (dump_file, " Promotion possible\n");
3170 normalizeEQ:
3171 if (!omega_safe_var_p (pb, j))
3173 for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3174 g = gcd (abs (eqn->coef[j]), g);
3175 g2 = g;
3177 else if (!omega_safe_var_p (pb, i))
3178 g2 = g;
3179 else
3180 g2 = 0;
3182 for (; g != 1 && j > 0; j--)
3183 g = gcd (abs (eqn->coef[j]), g);
3185 if (g > 1)
3187 if (eqn->coef[0] % g != 0)
3188 return omega_problem_has_no_solution ();
3190 for (j = 0; j <= pb->num_vars; j++)
3191 eqn->coef[j] /= g;
3193 g2 = g2 / g;
3196 if (g2 > 1)
3198 int e2;
3200 for (e2 = e - 1; e2 >= 0; e2--)
3201 if (pb->eqs[e2].coef[i])
3202 break;
3204 if (e2 == -1)
3205 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3206 if (pb->geqs[e2].coef[i])
3207 break;
3209 if (e2 == -1)
3210 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3211 if (pb->subs[e2].coef[i])
3212 break;
3214 if (e2 == -1)
3216 bool change = false;
3218 if (dump_file && (dump_flags & TDF_DETAILS))
3220 fprintf (dump_file, "Ha! We own it! \n");
3221 omega_print_eq (dump_file, pb, eqn);
3222 fprintf (dump_file, " \n");
3225 g = eqn->coef[i];
3226 g = abs (g);
3228 for (j = i - 1; j >= 0; j--)
3230 int t = int_mod (eqn->coef[j], g);
3232 if (2 * t >= g)
3233 t -= g;
3235 if (t != eqn->coef[j])
3237 eqn->coef[j] = t;
3238 change = true;
3242 if (!change)
3244 if (dump_file && (dump_flags & TDF_DETAILS))
3245 fprintf (dump_file, "So what?\n");
3248 else
3250 omega_name_wild_card (pb, i);
3252 if (dump_file && (dump_flags & TDF_DETAILS))
3254 omega_print_eq (dump_file, pb, eqn);
3255 fprintf (dump_file, " \n");
3258 e++;
3259 continue;
3264 if (promotion_possible)
3266 if (dump_file && (dump_flags & TDF_DETAILS))
3268 fprintf (dump_file, "promoting %s to safety\n",
3269 omega_variable_to_str (pb, i));
3270 omega_print_vars (dump_file, pb);
3273 pb->safe_vars++;
3275 if (!omega_wildcard_p (pb, i))
3276 omega_name_wild_card (pb, i);
3278 promotion_possible = false;
3279 j = k;
3280 goto normalizeEQ;
3283 if (g2 > 1 && !in_approximate_mode)
3285 if (pb->eqs[e].color == omega_red)
3287 if (dump_file && (dump_flags & TDF_DETAILS))
3288 fprintf (dump_file, "handling red equality\n");
3290 pb->num_eqs--;
3291 omega_do_elimination (pb, e, i);
3292 continue;
3295 if (dump_file && (dump_flags & TDF_DETAILS))
3297 fprintf (dump_file,
3298 "adding equation to handle safe variable \n");
3299 omega_print_eq (dump_file, pb, eqn);
3300 fprintf (dump_file, "\n----\n");
3301 omega_print_problem (dump_file, pb);
3302 fprintf (dump_file, "\n----\n");
3303 fprintf (dump_file, "\n----\n");
3306 i = omega_add_new_wild_card (pb);
3307 pb->num_eqs++;
3308 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3309 omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3310 omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3312 for (j = pb->num_vars; j >= 0; j--)
3314 pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3316 if (2 * pb->eqs[e + 1].coef[j] >= g2)
3317 pb->eqs[e + 1].coef[j] -= g2;
3320 pb->eqs[e + 1].coef[i] = g2;
3321 e += 2;
3323 if (dump_file && (dump_flags & TDF_DETAILS))
3324 omega_print_problem (dump_file, pb);
3326 continue;
3329 sv = pb->safe_vars;
3330 if (g2 == 0)
3331 sv = 0;
3333 /* Find variable to eliminate. */
3334 if (g2 > 1)
3336 gcc_assert (in_approximate_mode);
3338 if (dump_file && (dump_flags & TDF_DETAILS))
3340 fprintf (dump_file, "non-exact elimination: ");
3341 omega_print_eq (dump_file, pb, eqn);
3342 fprintf (dump_file, "\n");
3343 omega_print_problem (dump_file, pb);
3346 for (i = pb->num_vars; i > sv; i--)
3347 if (pb->eqs[e].coef[i] != 0)
3348 break;
3350 else
3351 for (i = pb->num_vars; i > sv; i--)
3352 if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3353 break;
3355 if (i > sv)
3357 pb->num_eqs--;
3358 omega_do_elimination (pb, e, i);
3360 if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3362 fprintf (dump_file, "result of non-exact elimination:\n");
3363 omega_print_problem (dump_file, pb);
3366 else
3368 int factor = (INT_MAX);
3369 j = 0;
3371 if (dump_file && (dump_flags & TDF_DETAILS))
3372 fprintf (dump_file, "doing moding\n");
3374 for (i = pb->num_vars; i != sv; i--)
3375 if ((pb->eqs[e].coef[i] & 1) != 0)
3377 j = i;
3378 i--;
3380 for (; i != sv; i--)
3381 if ((pb->eqs[e].coef[i] & 1) != 0)
3382 break;
3384 break;
3387 if (j != 0 && i == sv)
3389 omega_do_mod (pb, 2, e, j);
3390 e++;
3391 continue;
3394 j = 0;
3395 for (i = pb->num_vars; i != sv; i--)
3396 if (pb->eqs[e].coef[i] != 0
3397 && factor > abs (pb->eqs[e].coef[i]) + 1)
3399 factor = abs (pb->eqs[e].coef[i]) + 1;
3400 j = i;
3403 if (j == sv)
3405 if (dump_file && (dump_flags & TDF_DETAILS))
3406 fprintf (dump_file, "should not have happened\n");
3407 gcc_assert (0);
3410 omega_do_mod (pb, factor, e, j);
3411 /* Go back and try this equation again. */
3412 e++;
3417 pb->num_eqs = 0;
3418 return omega_unknown;
3421 /* Transform an inequation E to an equality, then solve DIFF problems
3422 based on PB, and only differing by the constant part that is
3423 diminished by one, trying to figure out which of the constants
3424 satisfies PB. */
3426 static enum omega_result
3427 parallel_splinter (omega_pb pb, int e, int diff,
3428 enum omega_result desired_res)
3430 omega_pb tmp_problem;
3431 int i;
3433 if (dump_file && (dump_flags & TDF_DETAILS))
3435 fprintf (dump_file, "Using parallel splintering\n");
3436 omega_print_problem (dump_file, pb);
3439 tmp_problem = XNEW (struct omega_pb_d);
3440 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3441 pb->num_eqs = 1;
3443 for (i = 0; i <= diff; i++)
3445 omega_copy_problem (tmp_problem, pb);
3447 if (dump_file && (dump_flags & TDF_DETAILS))
3449 fprintf (dump_file, "Splinter # %i\n", i);
3450 omega_print_problem (dump_file, pb);
3453 if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3455 free (tmp_problem);
3456 return omega_true;
3459 pb->eqs[0].coef[0]--;
3462 free (tmp_problem);
3463 return omega_false;
3466 /* Helper function: solve equations one at a time. */
3468 static enum omega_result
3469 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3471 int i, e;
3472 int n_vars, fv;
3473 enum omega_result result;
3474 bool coupled_subscripts = false;
3475 bool smoothed = false;
3476 bool eliminate_again;
3477 bool tried_eliminating_redundant = false;
3479 if (desired_res != omega_simplify)
3481 pb->num_subs = 0;
3482 pb->safe_vars = 0;
3485 solve_geq_start:
3486 do {
3487 gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3489 /* Verify that there are not too many inequalities. */
3490 gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3492 if (dump_file && (dump_flags & TDF_DETAILS))
3494 fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3495 desired_res, please_no_equalities_in_simplified_problems);
3496 omega_print_problem (dump_file, pb);
3497 fprintf (dump_file, "\n");
3500 n_vars = pb->num_vars;
3502 if (n_vars == 1)
3504 enum omega_eqn_color u_color = omega_black;
3505 enum omega_eqn_color l_color = omega_black;
3506 int upper_bound = pos_infinity;
3507 int lower_bound = neg_infinity;
3509 for (e = pb->num_geqs - 1; e >= 0; e--)
3511 int a = pb->geqs[e].coef[1];
3512 int c = pb->geqs[e].coef[0];
3514 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3515 if (a == 0)
3517 if (c < 0)
3518 return omega_problem_has_no_solution ();
3520 else if (a > 0)
3522 if (a != 1)
3523 c = int_div (c, a);
3525 if (lower_bound < -c
3526 || (lower_bound == -c
3527 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3529 lower_bound = -c;
3530 l_color = pb->geqs[e].color;
3533 else
3535 if (a != -1)
3536 c = int_div (c, -a);
3538 if (upper_bound > c
3539 || (upper_bound == c
3540 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3542 upper_bound = c;
3543 u_color = pb->geqs[e].color;
3548 if (dump_file && (dump_flags & TDF_DETAILS))
3550 fprintf (dump_file, "upper bound = %d\n", upper_bound);
3551 fprintf (dump_file, "lower bound = %d\n", lower_bound);
3554 if (lower_bound > upper_bound)
3555 return omega_problem_has_no_solution ();
3557 if (desired_res == omega_simplify)
3559 pb->num_geqs = 0;
3560 if (pb->safe_vars == 1)
3563 if (lower_bound == upper_bound
3564 && u_color == omega_black
3565 && l_color == omega_black)
3567 pb->eqs[0].coef[0] = -lower_bound;
3568 pb->eqs[0].coef[1] = 1;
3569 pb->eqs[0].color = omega_black;
3570 pb->num_eqs = 1;
3571 return omega_solve_problem (pb, desired_res);
3573 else
3575 if (lower_bound > neg_infinity)
3577 pb->geqs[0].coef[0] = -lower_bound;
3578 pb->geqs[0].coef[1] = 1;
3579 pb->geqs[0].key = 1;
3580 pb->geqs[0].color = l_color;
3581 pb->geqs[0].touched = 0;
3582 pb->num_geqs = 1;
3585 if (upper_bound < pos_infinity)
3587 pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3588 pb->geqs[pb->num_geqs].coef[1] = -1;
3589 pb->geqs[pb->num_geqs].key = -1;
3590 pb->geqs[pb->num_geqs].color = u_color;
3591 pb->geqs[pb->num_geqs].touched = 0;
3592 pb->num_geqs++;
3596 else
3597 pb->num_vars = 0;
3599 omega_problem_reduced (pb);
3600 return omega_false;
3603 if (original_problem != no_problem
3604 && l_color == omega_black
3605 && u_color == omega_black
3606 && !conservative
3607 && lower_bound == upper_bound)
3609 pb->eqs[0].coef[0] = -lower_bound;
3610 pb->eqs[0].coef[1] = 1;
3611 pb->num_eqs = 1;
3612 adding_equality_constraint (pb, 0);
3615 return omega_true;
3618 if (!pb->variables_freed)
3620 pb->variables_freed = true;
3622 if (desired_res != omega_simplify)
3623 omega_free_eliminations (pb, 0);
3624 else
3625 omega_free_eliminations (pb, pb->safe_vars);
3627 n_vars = pb->num_vars;
3629 if (n_vars == 1)
3630 continue;
3633 switch (normalize_omega_problem (pb))
3635 case normalize_false:
3636 return omega_false;
3637 break;
3639 case normalize_coupled:
3640 coupled_subscripts = true;
3641 break;
3643 case normalize_uncoupled:
3644 coupled_subscripts = false;
3645 break;
3647 default:
3648 gcc_unreachable ();
3651 n_vars = pb->num_vars;
3653 if (dump_file && (dump_flags & TDF_DETAILS))
3655 fprintf (dump_file, "\nafter normalization:\n");
3656 omega_print_problem (dump_file, pb);
3657 fprintf (dump_file, "\n");
3658 fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3661 do {
3662 int parallel_difference = INT_MAX;
3663 int best_parallel_eqn = -1;
3664 int minC, maxC, minCj = 0;
3665 int lower_bound_count = 0;
3666 int e2, Le = 0, Ue;
3667 bool possible_easy_int_solution;
3668 int max_splinters = 1;
3669 bool exact = false;
3670 bool lucky_exact = false;
3671 int best = (INT_MAX);
3672 int j = 0, jLe = 0, jLowerBoundCount = 0;
3675 eliminate_again = false;
3677 if (pb->num_eqs > 0)
3678 return omega_solve_problem (pb, desired_res);
3680 if (!coupled_subscripts)
3682 if (pb->safe_vars == 0)
3683 pb->num_geqs = 0;
3684 else
3685 for (e = pb->num_geqs - 1; e >= 0; e--)
3686 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3687 omega_delete_geq (pb, e, n_vars);
3689 pb->num_vars = pb->safe_vars;
3691 if (desired_res == omega_simplify)
3693 omega_problem_reduced (pb);
3694 return omega_false;
3697 return omega_true;
3700 if (desired_res != omega_simplify)
3701 fv = 0;
3702 else
3703 fv = pb->safe_vars;
3705 if (pb->num_geqs == 0)
3707 if (desired_res == omega_simplify)
3709 pb->num_vars = pb->safe_vars;
3710 omega_problem_reduced (pb);
3711 return omega_false;
3713 return omega_true;
3716 if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3718 omega_problem_reduced (pb);
3719 return omega_false;
3722 if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3723 || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3725 if (dump_file && (dump_flags & TDF_DETAILS))
3726 fprintf (dump_file,
3727 "TOO MANY EQUATIONS; "
3728 "%d equations, %d variables, "
3729 "ELIMINATING REDUNDANT ONES\n",
3730 pb->num_geqs, n_vars);
3732 if (!omega_eliminate_redundant (pb, false))
3733 return omega_false;
3735 n_vars = pb->num_vars;
3737 if (pb->num_eqs > 0)
3738 return omega_solve_problem (pb, desired_res);
3740 if (dump_file && (dump_flags & TDF_DETAILS))
3741 fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3744 if (desired_res != omega_simplify)
3745 fv = 0;
3746 else
3747 fv = pb->safe_vars;
3749 for (i = n_vars; i != fv; i--)
3751 int score;
3752 int ub = -2;
3753 int lb = -2;
3754 bool lucky = false;
3755 int upper_bound_count = 0;
3757 lower_bound_count = 0;
3758 minC = maxC = 0;
3760 for (e = pb->num_geqs - 1; e >= 0; e--)
3761 if (pb->geqs[e].coef[i] < 0)
3763 minC = MIN (minC, pb->geqs[e].coef[i]);
3764 upper_bound_count++;
3765 if (pb->geqs[e].coef[i] < -1)
3767 if (ub == -2)
3768 ub = e;
3769 else
3770 ub = -1;
3773 else if (pb->geqs[e].coef[i] > 0)
3775 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3776 lower_bound_count++;
3777 Le = e;
3778 if (pb->geqs[e].coef[i] > 1)
3780 if (lb == -2)
3781 lb = e;
3782 else
3783 lb = -1;
3787 if (lower_bound_count == 0
3788 || upper_bound_count == 0)
3790 lower_bound_count = 0;
3791 break;
3794 if (ub >= 0 && lb >= 0
3795 && pb->geqs[lb].key == -pb->geqs[ub].key)
3797 int Lc = pb->geqs[lb].coef[i];
3798 int Uc = -pb->geqs[ub].coef[i];
3799 int diff =
3800 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3801 lucky = (diff >= (Uc - 1) * (Lc - 1));
3804 if (maxC == 1
3805 || minC == -1
3806 || lucky
3807 || in_approximate_mode)
3809 score = upper_bound_count * lower_bound_count;
3811 if (dump_file && (dump_flags & TDF_DETAILS))
3812 fprintf (dump_file,
3813 "For %s, exact, score = %d*%d, range = %d ... %d,"
3814 "\nlucky = %d, in_approximate_mode=%d \n",
3815 omega_variable_to_str (pb, i),
3816 upper_bound_count,
3817 lower_bound_count, minC, maxC, lucky,
3818 in_approximate_mode);
3820 if (!exact
3821 || score < best)
3824 best = score;
3825 j = i;
3826 minCj = minC;
3827 jLe = Le;
3828 jLowerBoundCount = lower_bound_count;
3829 exact = true;
3830 lucky_exact = lucky;
3831 if (score == 1)
3832 break;
3835 else if (!exact)
3837 if (dump_file && (dump_flags & TDF_DETAILS))
3838 fprintf (dump_file,
3839 "For %s, non-exact, score = %d*%d,"
3840 "range = %d ... %d \n",
3841 omega_variable_to_str (pb, i),
3842 upper_bound_count,
3843 lower_bound_count, minC, maxC);
3845 score = maxC - minC;
3847 if (best > score)
3849 best = score;
3850 j = i;
3851 minCj = minC;
3852 jLe = Le;
3853 jLowerBoundCount = lower_bound_count;
3858 if (lower_bound_count == 0)
3860 omega_free_eliminations (pb, pb->safe_vars);
3861 n_vars = pb->num_vars;
3862 eliminate_again = true;
3863 continue;
3866 i = j;
3867 minC = minCj;
3868 Le = jLe;
3869 lower_bound_count = jLowerBoundCount;
3871 for (e = pb->num_geqs - 1; e >= 0; e--)
3872 if (pb->geqs[e].coef[i] > 0)
3874 if (pb->geqs[e].coef[i] == -minC)
3875 max_splinters += -minC - 1;
3876 else
3877 max_splinters +=
3878 pos_mul_hwi ((pb->geqs[e].coef[i] - 1),
3879 (-minC - 1)) / (-minC) + 1;
3882 /* #ifdef Omega3 */
3883 /* Trying to produce exact elimination by finding redundant
3884 constraints. */
3885 if (!exact && !tried_eliminating_redundant)
3887 omega_eliminate_redundant (pb, false);
3888 tried_eliminating_redundant = true;
3889 eliminate_again = true;
3890 continue;
3892 tried_eliminating_redundant = false;
3893 /* #endif */
3895 if (return_single_result && desired_res == omega_simplify && !exact)
3897 omega_problem_reduced (pb);
3898 return omega_true;
3901 /* #ifndef Omega3 */
3902 /* Trying to produce exact elimination by finding redundant
3903 constraints. */
3904 if (!exact && !tried_eliminating_redundant)
3906 omega_eliminate_redundant (pb, false);
3907 tried_eliminating_redundant = true;
3908 continue;
3910 tried_eliminating_redundant = false;
3911 /* #endif */
3913 if (!exact)
3915 int e1, e2;
3917 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3918 if (pb->geqs[e1].color == omega_black)
3919 for (e2 = e1 - 1; e2 >= 0; e2--)
3920 if (pb->geqs[e2].color == omega_black
3921 && pb->geqs[e1].key == -pb->geqs[e2].key
3922 && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3923 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3924 / 2 < parallel_difference))
3926 parallel_difference =
3927 (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3928 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3929 / 2;
3930 best_parallel_eqn = e1;
3933 if (dump_file && (dump_flags & TDF_DETAILS)
3934 && best_parallel_eqn >= 0)
3936 fprintf (dump_file,
3937 "Possible parallel projection, diff = %d, in ",
3938 parallel_difference);
3939 omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3940 fprintf (dump_file, "\n");
3941 omega_print_problem (dump_file, pb);
3945 if (dump_file && (dump_flags & TDF_DETAILS))
3947 fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
3948 omega_variable_to_str (pb, i), i, minC,
3949 lower_bound_count);
3950 omega_print_problem (dump_file, pb);
3952 if (lucky_exact)
3953 fprintf (dump_file, "(a lucky exact elimination)\n");
3955 else if (exact)
3956 fprintf (dump_file, "(an exact elimination)\n");
3958 fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
3961 gcc_assert (max_splinters >= 1);
3963 if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
3964 && parallel_difference <= max_splinters)
3965 return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
3966 desired_res);
3968 smoothed = false;
3970 if (i != n_vars)
3972 int t;
3973 int j = pb->num_vars;
3975 if (dump_file && (dump_flags & TDF_DETAILS))
3977 fprintf (dump_file, "Swapping %d and %d\n", i, j);
3978 omega_print_problem (dump_file, pb);
3981 swap (&pb->var[i], &pb->var[j]);
3983 for (e = pb->num_geqs - 1; e >= 0; e--)
3984 if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
3986 pb->geqs[e].touched = 1;
3987 t = pb->geqs[e].coef[i];
3988 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
3989 pb->geqs[e].coef[j] = t;
3992 for (e = pb->num_subs - 1; e >= 0; e--)
3993 if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
3995 t = pb->subs[e].coef[i];
3996 pb->subs[e].coef[i] = pb->subs[e].coef[j];
3997 pb->subs[e].coef[j] = t;
4000 if (dump_file && (dump_flags & TDF_DETAILS))
4002 fprintf (dump_file, "Swapping complete \n");
4003 omega_print_problem (dump_file, pb);
4004 fprintf (dump_file, "\n");
4007 i = j;
4010 else if (dump_file && (dump_flags & TDF_DETAILS))
4012 fprintf (dump_file, "No swap needed\n");
4013 omega_print_problem (dump_file, pb);
4016 pb->num_vars--;
4017 n_vars = pb->num_vars;
4019 if (exact)
4021 if (n_vars == 1)
4023 int upper_bound = pos_infinity;
4024 int lower_bound = neg_infinity;
4025 enum omega_eqn_color ub_color = omega_black;
4026 enum omega_eqn_color lb_color = omega_black;
4027 int topeqn = pb->num_geqs - 1;
4028 int Lc = pb->geqs[Le].coef[i];
4030 for (Le = topeqn; Le >= 0; Le--)
4031 if ((Lc = pb->geqs[Le].coef[i]) == 0)
4033 if (pb->geqs[Le].coef[1] == 1)
4035 int constantTerm = -pb->geqs[Le].coef[0];
4037 if (constantTerm > lower_bound ||
4038 (constantTerm == lower_bound &&
4039 !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
4041 lower_bound = constantTerm;
4042 lb_color = pb->geqs[Le].color;
4045 if (dump_file && (dump_flags & TDF_DETAILS))
4047 if (pb->geqs[Le].color == omega_black)
4048 fprintf (dump_file, " :::=> %s >= %d\n",
4049 omega_variable_to_str (pb, 1),
4050 constantTerm);
4051 else
4052 fprintf (dump_file,
4053 " :::=> [%s >= %d]\n",
4054 omega_variable_to_str (pb, 1),
4055 constantTerm);
4058 else
4060 int constantTerm = pb->geqs[Le].coef[0];
4061 if (constantTerm < upper_bound ||
4062 (constantTerm == upper_bound
4063 && !omega_eqn_is_red (&pb->geqs[Le],
4064 desired_res)))
4066 upper_bound = constantTerm;
4067 ub_color = pb->geqs[Le].color;
4070 if (dump_file && (dump_flags & TDF_DETAILS))
4072 if (pb->geqs[Le].color == omega_black)
4073 fprintf (dump_file, " :::=> %s <= %d\n",
4074 omega_variable_to_str (pb, 1),
4075 constantTerm);
4076 else
4077 fprintf (dump_file,
4078 " :::=> [%s <= %d]\n",
4079 omega_variable_to_str (pb, 1),
4080 constantTerm);
4084 else if (Lc > 0)
4085 for (Ue = topeqn; Ue >= 0; Ue--)
4086 if (pb->geqs[Ue].coef[i] < 0
4087 && pb->geqs[Le].key != -pb->geqs[Ue].key)
4089 int Uc = -pb->geqs[Ue].coef[i];
4090 int coefficient = pb->geqs[Ue].coef[1] * Lc
4091 + pb->geqs[Le].coef[1] * Uc;
4092 int constantTerm = pb->geqs[Ue].coef[0] * Lc
4093 + pb->geqs[Le].coef[0] * Uc;
4095 if (dump_file && (dump_flags & TDF_DETAILS))
4097 omega_print_geq_extra (dump_file, pb,
4098 &(pb->geqs[Ue]));
4099 fprintf (dump_file, "\n");
4100 omega_print_geq_extra (dump_file, pb,
4101 &(pb->geqs[Le]));
4102 fprintf (dump_file, "\n");
4105 if (coefficient > 0)
4107 constantTerm = -int_div (constantTerm, coefficient);
4109 if (constantTerm > lower_bound
4110 || (constantTerm == lower_bound
4111 && (desired_res != omega_simplify
4112 || (pb->geqs[Ue].color == omega_black
4113 && pb->geqs[Le].color == omega_black))))
4115 lower_bound = constantTerm;
4116 lb_color = (pb->geqs[Ue].color == omega_red
4117 || pb->geqs[Le].color == omega_red)
4118 ? omega_red : omega_black;
4121 if (dump_file && (dump_flags & TDF_DETAILS))
4123 if (pb->geqs[Ue].color == omega_red
4124 || pb->geqs[Le].color == omega_red)
4125 fprintf (dump_file,
4126 " ::=> [%s >= %d]\n",
4127 omega_variable_to_str (pb, 1),
4128 constantTerm);
4129 else
4130 fprintf (dump_file,
4131 " ::=> %s >= %d\n",
4132 omega_variable_to_str (pb, 1),
4133 constantTerm);
4136 else
4138 constantTerm = int_div (constantTerm, -coefficient);
4139 if (constantTerm < upper_bound
4140 || (constantTerm == upper_bound
4141 && pb->geqs[Ue].color == omega_black
4142 && pb->geqs[Le].color == omega_black))
4144 upper_bound = constantTerm;
4145 ub_color = (pb->geqs[Ue].color == omega_red
4146 || pb->geqs[Le].color == omega_red)
4147 ? omega_red : omega_black;
4150 if (dump_file
4151 && (dump_flags & TDF_DETAILS))
4153 if (pb->geqs[Ue].color == omega_red
4154 || pb->geqs[Le].color == omega_red)
4155 fprintf (dump_file,
4156 " ::=> [%s <= %d]\n",
4157 omega_variable_to_str (pb, 1),
4158 constantTerm);
4159 else
4160 fprintf (dump_file,
4161 " ::=> %s <= %d\n",
4162 omega_variable_to_str (pb, 1),
4163 constantTerm);
4168 pb->num_geqs = 0;
4170 if (dump_file && (dump_flags & TDF_DETAILS))
4171 fprintf (dump_file,
4172 " therefore, %c%d <= %c%s%c <= %d%c\n",
4173 lb_color == omega_red ? '[' : ' ', lower_bound,
4174 (lb_color == omega_red && ub_color == omega_black)
4175 ? ']' : ' ',
4176 omega_variable_to_str (pb, 1),
4177 (lb_color == omega_black && ub_color == omega_red)
4178 ? '[' : ' ',
4179 upper_bound, ub_color == omega_red ? ']' : ' ');
4181 if (lower_bound > upper_bound)
4182 return omega_false;
4184 if (pb->safe_vars == 1)
4186 if (upper_bound == lower_bound
4187 && !(ub_color == omega_red || lb_color == omega_red)
4188 && !please_no_equalities_in_simplified_problems)
4190 pb->num_eqs++;
4191 pb->eqs[0].coef[1] = -1;
4192 pb->eqs[0].coef[0] = upper_bound;
4194 if (ub_color == omega_red
4195 || lb_color == omega_red)
4196 pb->eqs[0].color = omega_red;
4198 if (desired_res == omega_simplify
4199 && pb->eqs[0].color == omega_black)
4200 return omega_solve_problem (pb, desired_res);
4203 if (upper_bound != pos_infinity)
4205 pb->geqs[0].coef[1] = -1;
4206 pb->geqs[0].coef[0] = upper_bound;
4207 pb->geqs[0].color = ub_color;
4208 pb->geqs[0].key = -1;
4209 pb->geqs[0].touched = 0;
4210 pb->num_geqs++;
4213 if (lower_bound != neg_infinity)
4215 pb->geqs[pb->num_geqs].coef[1] = 1;
4216 pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
4217 pb->geqs[pb->num_geqs].color = lb_color;
4218 pb->geqs[pb->num_geqs].key = 1;
4219 pb->geqs[pb->num_geqs].touched = 0;
4220 pb->num_geqs++;
4224 if (desired_res == omega_simplify)
4226 omega_problem_reduced (pb);
4227 return omega_false;
4229 else
4231 if (!conservative
4232 && (desired_res != omega_simplify
4233 || (lb_color == omega_black
4234 && ub_color == omega_black))
4235 && original_problem != no_problem
4236 && lower_bound == upper_bound)
4238 for (i = original_problem->num_vars; i >= 0; i--)
4239 if (original_problem->var[i] == pb->var[1])
4240 break;
4242 if (i == 0)
4243 break;
4245 e = original_problem->num_eqs++;
4246 omega_init_eqn_zero (&original_problem->eqs[e],
4247 original_problem->num_vars);
4248 original_problem->eqs[e].coef[i] = -1;
4249 original_problem->eqs[e].coef[0] = upper_bound;
4251 if (dump_file && (dump_flags & TDF_DETAILS))
4253 fprintf (dump_file,
4254 "adding equality %d to outer problem\n", e);
4255 omega_print_problem (dump_file, original_problem);
4258 return omega_true;
4262 eliminate_again = true;
4264 if (lower_bound_count == 1)
4266 eqn lbeqn = omega_alloc_eqns (0, 1);
4267 int Lc = pb->geqs[Le].coef[i];
4269 if (dump_file && (dump_flags & TDF_DETAILS))
4270 fprintf (dump_file, "an inplace elimination\n");
4272 omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
4273 omega_delete_geq_extra (pb, Le, n_vars + 1);
4275 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4276 if (pb->geqs[Ue].coef[i] < 0)
4278 if (lbeqn->key == -pb->geqs[Ue].key)
4279 omega_delete_geq_extra (pb, Ue, n_vars + 1);
4280 else
4282 int k;
4283 int Uc = -pb->geqs[Ue].coef[i];
4284 pb->geqs[Ue].touched = 1;
4285 eliminate_again = false;
4287 if (lbeqn->color == omega_red)
4288 pb->geqs[Ue].color = omega_red;
4290 for (k = 0; k <= n_vars; k++)
4291 pb->geqs[Ue].coef[k] =
4292 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4293 mul_hwi (lbeqn->coef[k], Uc);
4295 if (dump_file && (dump_flags & TDF_DETAILS))
4297 omega_print_geq (dump_file, pb,
4298 &(pb->geqs[Ue]));
4299 fprintf (dump_file, "\n");
4304 omega_free_eqns (lbeqn, 1);
4305 continue;
4307 else
4309 int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
4310 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
4311 int num_dead = 0;
4312 int top_eqn = pb->num_geqs - 1;
4313 lower_bound_count--;
4315 if (dump_file && (dump_flags & TDF_DETAILS))
4316 fprintf (dump_file, "lower bound count = %d\n",
4317 lower_bound_count);
4319 for (Le = top_eqn; Le >= 0; Le--)
4320 if (pb->geqs[Le].coef[i] > 0)
4322 int Lc = pb->geqs[Le].coef[i];
4323 for (Ue = top_eqn; Ue >= 0; Ue--)
4324 if (pb->geqs[Ue].coef[i] < 0)
4326 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4328 int k;
4329 int Uc = -pb->geqs[Ue].coef[i];
4331 if (num_dead == 0)
4332 e2 = pb->num_geqs++;
4333 else
4334 e2 = dead_eqns[--num_dead];
4336 gcc_assert (e2 < OMEGA_MAX_GEQS);
4338 if (dump_file && (dump_flags & TDF_DETAILS))
4340 fprintf (dump_file,
4341 "Le = %d, Ue = %d, gen = %d\n",
4342 Le, Ue, e2);
4343 omega_print_geq_extra (dump_file, pb,
4344 &(pb->geqs[Le]));
4345 fprintf (dump_file, "\n");
4346 omega_print_geq_extra (dump_file, pb,
4347 &(pb->geqs[Ue]));
4348 fprintf (dump_file, "\n");
4351 eliminate_again = false;
4353 for (k = n_vars; k >= 0; k--)
4354 pb->geqs[e2].coef[k] =
4355 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4356 mul_hwi (pb->geqs[Le].coef[k], Uc);
4358 pb->geqs[e2].coef[n_vars + 1] = 0;
4359 pb->geqs[e2].touched = 1;
4361 if (pb->geqs[Ue].color == omega_red
4362 || pb->geqs[Le].color == omega_red)
4363 pb->geqs[e2].color = omega_red;
4364 else
4365 pb->geqs[e2].color = omega_black;
4367 if (dump_file && (dump_flags & TDF_DETAILS))
4369 omega_print_geq (dump_file, pb,
4370 &(pb->geqs[e2]));
4371 fprintf (dump_file, "\n");
4375 if (lower_bound_count == 0)
4377 dead_eqns[num_dead++] = Ue;
4379 if (dump_file && (dump_flags & TDF_DETAILS))
4380 fprintf (dump_file, "Killed %d\n", Ue);
4384 lower_bound_count--;
4385 dead_eqns[num_dead++] = Le;
4387 if (dump_file && (dump_flags & TDF_DETAILS))
4388 fprintf (dump_file, "Killed %d\n", Le);
4391 for (e = pb->num_geqs - 1; e >= 0; e--)
4392 is_dead[e] = false;
4394 while (num_dead > 0)
4395 is_dead[dead_eqns[--num_dead]] = true;
4397 for (e = pb->num_geqs - 1; e >= 0; e--)
4398 if (is_dead[e])
4399 omega_delete_geq_extra (pb, e, n_vars + 1);
4401 free (dead_eqns);
4402 free (is_dead);
4403 continue;
4406 else
4408 omega_pb rS, iS;
4410 rS = omega_alloc_problem (0, 0);
4411 iS = omega_alloc_problem (0, 0);
4412 e2 = 0;
4413 possible_easy_int_solution = true;
4415 for (e = 0; e < pb->num_geqs; e++)
4416 if (pb->geqs[e].coef[i] == 0)
4418 omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
4419 pb->num_vars);
4420 omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
4421 pb->num_vars);
4423 if (dump_file && (dump_flags & TDF_DETAILS))
4425 int t;
4426 fprintf (dump_file, "Copying (%d, %d): ", i,
4427 pb->geqs[e].coef[i]);
4428 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
4429 fprintf (dump_file, "\n");
4430 for (t = 0; t <= n_vars + 1; t++)
4431 fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
4432 fprintf (dump_file, "\n");
4435 e2++;
4436 gcc_assert (e2 < OMEGA_MAX_GEQS);
4439 for (Le = pb->num_geqs - 1; Le >= 0; Le--)
4440 if (pb->geqs[Le].coef[i] > 0)
4441 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4442 if (pb->geqs[Ue].coef[i] < 0)
4444 int k;
4445 int Lc = pb->geqs[Le].coef[i];
4446 int Uc = -pb->geqs[Ue].coef[i];
4448 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4451 rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
4453 if (dump_file && (dump_flags & TDF_DETAILS))
4455 fprintf (dump_file, "---\n");
4456 fprintf (dump_file,
4457 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4458 Le, Lc, Ue, Uc, e2);
4459 omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
4460 fprintf (dump_file, "\n");
4461 omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
4462 fprintf (dump_file, "\n");
4465 if (Uc == Lc)
4467 for (k = n_vars; k >= 0; k--)
4468 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4469 pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
4471 iS->geqs[e2].coef[0] -= (Uc - 1);
4473 else
4475 for (k = n_vars; k >= 0; k--)
4476 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4477 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4478 mul_hwi (pb->geqs[Le].coef[k], Uc);
4480 iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
4483 if (pb->geqs[Ue].color == omega_red
4484 || pb->geqs[Le].color == omega_red)
4485 iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
4486 else
4487 iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
4489 if (dump_file && (dump_flags & TDF_DETAILS))
4491 omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
4492 fprintf (dump_file, "\n");
4495 e2++;
4496 gcc_assert (e2 < OMEGA_MAX_GEQS);
4498 else if (pb->geqs[Ue].coef[0] * Lc +
4499 pb->geqs[Le].coef[0] * Uc -
4500 (Uc - 1) * (Lc - 1) < 0)
4501 possible_easy_int_solution = false;
4504 iS->variables_initialized = rS->variables_initialized = true;
4505 iS->num_vars = rS->num_vars = pb->num_vars;
4506 iS->num_geqs = rS->num_geqs = e2;
4507 iS->num_eqs = rS->num_eqs = 0;
4508 iS->num_subs = rS->num_subs = pb->num_subs;
4509 iS->safe_vars = rS->safe_vars = pb->safe_vars;
4511 for (e = n_vars; e >= 0; e--)
4512 rS->var[e] = pb->var[e];
4514 for (e = n_vars; e >= 0; e--)
4515 iS->var[e] = pb->var[e];
4517 for (e = pb->num_subs - 1; e >= 0; e--)
4519 omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
4520 omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
4523 pb->num_vars++;
4524 n_vars = pb->num_vars;
4526 if (desired_res != omega_true)
4528 if (original_problem == no_problem)
4530 original_problem = pb;
4531 result = omega_solve_geq (rS, omega_false);
4532 original_problem = no_problem;
4534 else
4535 result = omega_solve_geq (rS, omega_false);
4537 if (result == omega_false)
4539 free (rS);
4540 free (iS);
4541 return result;
4544 if (pb->num_eqs > 0)
4546 /* An equality constraint must have been found */
4547 free (rS);
4548 free (iS);
4549 return omega_solve_problem (pb, desired_res);
4553 if (desired_res != omega_false)
4555 int j;
4556 int lower_bounds = 0;
4557 int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
4559 if (possible_easy_int_solution)
4561 conservative++;
4562 result = omega_solve_geq (iS, desired_res);
4563 conservative--;
4565 if (result != omega_false)
4567 free (rS);
4568 free (iS);
4569 free (lower_bound);
4570 return result;
4574 if (!exact && best_parallel_eqn >= 0
4575 && parallel_difference <= max_splinters)
4577 free (rS);
4578 free (iS);
4579 free (lower_bound);
4580 return parallel_splinter (pb, best_parallel_eqn,
4581 parallel_difference,
4582 desired_res);
4585 if (dump_file && (dump_flags & TDF_DETAILS))
4586 fprintf (dump_file, "have to do exact analysis\n");
4588 conservative++;
4590 for (e = 0; e < pb->num_geqs; e++)
4591 if (pb->geqs[e].coef[i] > 1)
4592 lower_bound[lower_bounds++] = e;
4594 /* Sort array LOWER_BOUND. */
4595 for (j = 0; j < lower_bounds; j++)
4597 int k, smallest = j;
4599 for (k = j + 1; k < lower_bounds; k++)
4600 if (pb->geqs[lower_bound[smallest]].coef[i] >
4601 pb->geqs[lower_bound[k]].coef[i])
4602 smallest = k;
4604 k = lower_bound[smallest];
4605 lower_bound[smallest] = lower_bound[j];
4606 lower_bound[j] = k;
4609 if (dump_file && (dump_flags & TDF_DETAILS))
4611 fprintf (dump_file, "lower bound coefficients = ");
4613 for (j = 0; j < lower_bounds; j++)
4614 fprintf (dump_file, " %d",
4615 pb->geqs[lower_bound[j]].coef[i]);
4617 fprintf (dump_file, "\n");
4620 for (j = 0; j < lower_bounds; j++)
4622 int max_incr;
4623 int c;
4624 int worst_lower_bound_constant = -minC;
4626 e = lower_bound[j];
4627 max_incr = (((pb->geqs[e].coef[i] - 1) *
4628 (worst_lower_bound_constant - 1) - 1)
4629 / worst_lower_bound_constant);
4630 /* max_incr += 2; */
4632 if (dump_file && (dump_flags & TDF_DETAILS))
4634 fprintf (dump_file, "for equation ");
4635 omega_print_geq (dump_file, pb, &pb->geqs[e]);
4636 fprintf (dump_file,
4637 "\ntry decrements from 0 to %d\n",
4638 max_incr);
4639 omega_print_problem (dump_file, pb);
4642 if (max_incr > 50 && !smoothed
4643 && smooth_weird_equations (pb))
4645 conservative--;
4646 free (rS);
4647 free (iS);
4648 smoothed = true;
4649 goto solve_geq_start;
4652 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4653 pb->num_vars);
4654 pb->eqs[0].color = omega_black;
4655 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4656 pb->geqs[e].touched = 1;
4657 pb->num_eqs = 1;
4659 for (c = max_incr; c >= 0; c--)
4661 if (dump_file && (dump_flags & TDF_DETAILS))
4663 fprintf (dump_file,
4664 "trying next decrement of %d\n",
4665 max_incr - c);
4666 omega_print_problem (dump_file, pb);
4669 omega_copy_problem (rS, pb);
4671 if (dump_file && (dump_flags & TDF_DETAILS))
4672 omega_print_problem (dump_file, rS);
4674 result = omega_solve_problem (rS, desired_res);
4676 if (result == omega_true)
4678 free (rS);
4679 free (iS);
4680 free (lower_bound);
4681 conservative--;
4682 return omega_true;
4685 pb->eqs[0].coef[0]--;
4688 if (j + 1 < lower_bounds)
4690 pb->num_eqs = 0;
4691 omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4692 pb->num_vars);
4693 pb->geqs[e].touched = 1;
4694 pb->geqs[e].color = omega_black;
4695 omega_copy_problem (rS, pb);
4697 if (dump_file && (dump_flags & TDF_DETAILS))
4698 fprintf (dump_file,
4699 "exhausted lower bound, "
4700 "checking if still feasible ");
4702 result = omega_solve_problem (rS, omega_false);
4704 if (result == omega_false)
4705 break;
4709 if (dump_file && (dump_flags & TDF_DETAILS))
4710 fprintf (dump_file, "fall-off the end\n");
4712 free (rS);
4713 free (iS);
4714 free (lower_bound);
4715 conservative--;
4716 return omega_false;
4719 free (rS);
4720 free (iS);
4722 return omega_unknown;
4723 } while (eliminate_again);
4724 } while (1);
4727 /* Because the omega solver is recursive, this counter limits the
4728 recursion depth. */
4729 static int omega_solve_depth = 0;
4731 /* Return omega_true when the problem PB has a solution following the
4732 DESIRED_RES. */
4734 enum omega_result
4735 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4737 enum omega_result result;
4739 gcc_assert (pb->num_vars >= pb->safe_vars);
4740 omega_solve_depth++;
4742 if (desired_res != omega_simplify)
4743 pb->safe_vars = 0;
4745 if (omega_solve_depth > 50)
4747 if (dump_file && (dump_flags & TDF_DETAILS))
4749 fprintf (dump_file,
4750 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4751 omega_solve_depth, in_approximate_mode);
4752 omega_print_problem (dump_file, pb);
4754 gcc_assert (0);
4757 if (omega_solve_eq (pb, desired_res) == omega_false)
4759 omega_solve_depth--;
4760 return omega_false;
4763 if (in_approximate_mode && !pb->num_geqs)
4765 result = omega_true;
4766 pb->num_vars = pb->safe_vars;
4767 omega_problem_reduced (pb);
4769 else
4770 result = omega_solve_geq (pb, desired_res);
4772 omega_solve_depth--;
4774 if (!omega_reduce_with_subs)
4776 resurrect_subs (pb);
4777 gcc_assert (please_no_equalities_in_simplified_problems
4778 || !result || pb->num_subs == 0);
4781 return result;
4784 /* Return true if red equations constrain the set of possible solutions.
4785 We assume that there are solutions to the black equations by
4786 themselves, so if there is no solution to the combined problem, we
4787 return true. */
4789 bool
4790 omega_problem_has_red_equations (omega_pb pb)
4792 bool result;
4793 int e;
4794 int i;
4796 if (dump_file && (dump_flags & TDF_DETAILS))
4798 fprintf (dump_file, "Checking for red equations:\n");
4799 omega_print_problem (dump_file, pb);
4802 please_no_equalities_in_simplified_problems++;
4803 may_be_red++;
4805 if (omega_single_result)
4806 return_single_result++;
4808 create_color = true;
4809 result = (omega_simplify_problem (pb) == omega_false);
4811 if (omega_single_result)
4812 return_single_result--;
4814 may_be_red--;
4815 please_no_equalities_in_simplified_problems--;
4817 if (result)
4819 if (dump_file && (dump_flags & TDF_DETAILS))
4820 fprintf (dump_file, "Gist is FALSE\n");
4822 pb->num_subs = 0;
4823 pb->num_geqs = 0;
4824 pb->num_eqs = 1;
4825 pb->eqs[0].color = omega_red;
4827 for (i = pb->num_vars; i > 0; i--)
4828 pb->eqs[0].coef[i] = 0;
4830 pb->eqs[0].coef[0] = 1;
4831 return true;
4834 free_red_eliminations (pb);
4835 gcc_assert (pb->num_eqs == 0);
4837 for (e = pb->num_geqs - 1; e >= 0; e--)
4838 if (pb->geqs[e].color == omega_red)
4839 result = true;
4841 if (!result)
4842 return false;
4844 for (i = pb->safe_vars; i >= 1; i--)
4846 int ub = 0;
4847 int lb = 0;
4849 for (e = pb->num_geqs - 1; e >= 0; e--)
4851 if (pb->geqs[e].coef[i])
4853 if (pb->geqs[e].coef[i] > 0)
4854 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4856 else
4857 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4861 if (ub == 2 || lb == 2)
4864 if (dump_file && (dump_flags & TDF_DETAILS))
4865 fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4867 if (!omega_reduce_with_subs)
4869 resurrect_subs (pb);
4870 gcc_assert (pb->num_subs == 0);
4873 return true;
4878 if (dump_file && (dump_flags & TDF_DETAILS))
4879 fprintf (dump_file,
4880 "*** Doing potentially expensive elimination tests "
4881 "for red equations\n");
4883 please_no_equalities_in_simplified_problems++;
4884 omega_eliminate_red (pb, true);
4885 please_no_equalities_in_simplified_problems--;
4887 result = false;
4888 gcc_assert (pb->num_eqs == 0);
4890 for (e = pb->num_geqs - 1; e >= 0; e--)
4891 if (pb->geqs[e].color == omega_red)
4892 result = true;
4894 if (dump_file && (dump_flags & TDF_DETAILS))
4896 if (!result)
4897 fprintf (dump_file,
4898 "******************** Redundant Red Equations eliminated!!\n");
4899 else
4900 fprintf (dump_file,
4901 "******************** Red Equations remain\n");
4903 omega_print_problem (dump_file, pb);
4906 if (!omega_reduce_with_subs)
4908 normalize_return_type r;
4910 resurrect_subs (pb);
4911 r = normalize_omega_problem (pb);
4912 gcc_assert (r != normalize_false);
4914 coalesce (pb);
4915 cleanout_wildcards (pb);
4916 gcc_assert (pb->num_subs == 0);
4919 return result;
4922 /* Calls omega_simplify_problem in approximate mode. */
4924 enum omega_result
4925 omega_simplify_approximate (omega_pb pb)
4927 enum omega_result result;
4929 if (dump_file && (dump_flags & TDF_DETAILS))
4930 fprintf (dump_file, "(Entering approximate mode\n");
4932 in_approximate_mode = true;
4933 result = omega_simplify_problem (pb);
4934 in_approximate_mode = false;
4936 gcc_assert (pb->num_vars == pb->safe_vars);
4937 if (!omega_reduce_with_subs)
4938 gcc_assert (pb->num_subs == 0);
4940 if (dump_file && (dump_flags & TDF_DETAILS))
4941 fprintf (dump_file, "Leaving approximate mode)\n");
4943 return result;
4947 /* Simplifies problem PB by eliminating redundant constraints and
4948 reducing the constraints system to a minimal form. Returns
4949 omega_true when the problem was successfully reduced, omega_unknown
4950 when the solver is unable to determine an answer. */
4952 enum omega_result
4953 omega_simplify_problem (omega_pb pb)
4955 int i;
4957 omega_found_reduction = omega_false;
4959 if (!pb->variables_initialized)
4960 omega_initialize_variables (pb);
4962 if (next_key * 3 > MAX_KEYS)
4964 int e;
4966 hash_version++;
4967 next_key = OMEGA_MAX_VARS + 1;
4969 for (e = pb->num_geqs - 1; e >= 0; e--)
4970 pb->geqs[e].touched = 1;
4972 for (i = 0; i < HASH_TABLE_SIZE; i++)
4973 hash_master[i].touched = -1;
4975 pb->hash_version = hash_version;
4978 else if (pb->hash_version != hash_version)
4980 int e;
4982 for (e = pb->num_geqs - 1; e >= 0; e--)
4983 pb->geqs[e].touched = 1;
4985 pb->hash_version = hash_version;
4988 if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
4989 omega_free_eliminations (pb, pb->safe_vars);
4991 if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
4993 omega_found_reduction = omega_solve_problem (pb, omega_unknown);
4995 if (omega_found_reduction != omega_false
4996 && !return_single_result)
4998 pb->num_geqs = 0;
4999 pb->num_eqs = 0;
5000 (*omega_when_reduced) (pb);
5003 return omega_found_reduction;
5006 omega_solve_problem (pb, omega_simplify);
5008 if (omega_found_reduction != omega_false)
5010 for (i = 1; omega_safe_var_p (pb, i); i++)
5011 pb->forwarding_address[pb->var[i]] = i;
5013 for (i = 0; i < pb->num_subs; i++)
5014 pb->forwarding_address[pb->subs[i].key] = -i - 1;
5017 if (!omega_reduce_with_subs)
5018 gcc_assert (please_no_equalities_in_simplified_problems
5019 || omega_found_reduction == omega_false
5020 || pb->num_subs == 0);
5022 return omega_found_reduction;
5025 /* Make variable VAR unprotected: it then can be eliminated. */
5027 void
5028 omega_unprotect_variable (omega_pb pb, int var)
5030 int e, idx;
5031 idx = pb->forwarding_address[var];
5033 if (idx < 0)
5035 idx = -1 - idx;
5036 pb->num_subs--;
5038 if (idx < pb->num_subs)
5040 omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5041 pb->num_vars);
5042 pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5045 else
5047 int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5048 int e2;
5050 for (e = pb->num_subs - 1; e >= 0; e--)
5051 bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5053 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5054 if (bring_to_life[e2])
5056 pb->num_vars++;
5057 pb->safe_vars++;
5059 if (pb->safe_vars < pb->num_vars)
5061 for (e = pb->num_geqs - 1; e >= 0; e--)
5063 pb->geqs[e].coef[pb->num_vars] =
5064 pb->geqs[e].coef[pb->safe_vars];
5066 pb->geqs[e].coef[pb->safe_vars] = 0;
5069 for (e = pb->num_eqs - 1; e >= 0; e--)
5071 pb->eqs[e].coef[pb->num_vars] =
5072 pb->eqs[e].coef[pb->safe_vars];
5074 pb->eqs[e].coef[pb->safe_vars] = 0;
5077 for (e = pb->num_subs - 1; e >= 0; e--)
5079 pb->subs[e].coef[pb->num_vars] =
5080 pb->subs[e].coef[pb->safe_vars];
5082 pb->subs[e].coef[pb->safe_vars] = 0;
5085 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5086 pb->forwarding_address[pb->var[pb->num_vars]] =
5087 pb->num_vars;
5089 else
5091 for (e = pb->num_geqs - 1; e >= 0; e--)
5092 pb->geqs[e].coef[pb->safe_vars] = 0;
5094 for (e = pb->num_eqs - 1; e >= 0; e--)
5095 pb->eqs[e].coef[pb->safe_vars] = 0;
5097 for (e = pb->num_subs - 1; e >= 0; e--)
5098 pb->subs[e].coef[pb->safe_vars] = 0;
5101 pb->var[pb->safe_vars] = pb->subs[e2].key;
5102 pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5104 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5105 pb->num_vars);
5106 pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5107 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5109 if (e2 < pb->num_subs - 1)
5110 omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5111 pb->num_vars);
5113 pb->num_subs--;
5116 omega_unprotect_1 (pb, &idx, NULL);
5117 free (bring_to_life);
5120 chain_unprotect (pb);
5123 /* Unprotects VAR and simplifies PB. */
5125 enum omega_result
5126 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5127 int var, int sign)
5129 int n_vars = pb->num_vars;
5130 int e, j;
5131 int k = pb->forwarding_address[var];
5133 if (k < 0)
5135 k = -1 - k;
5137 if (sign != 0)
5139 e = pb->num_geqs++;
5140 omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5142 for (j = 0; j <= n_vars; j++)
5143 pb->geqs[e].coef[j] *= sign;
5145 pb->geqs[e].coef[0]--;
5146 pb->geqs[e].touched = 1;
5147 pb->geqs[e].color = color;
5149 else
5151 e = pb->num_eqs++;
5152 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5153 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5154 pb->eqs[e].color = color;
5157 else if (sign != 0)
5159 e = pb->num_geqs++;
5160 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5161 pb->geqs[e].coef[k] = sign;
5162 pb->geqs[e].coef[0] = -1;
5163 pb->geqs[e].touched = 1;
5164 pb->geqs[e].color = color;
5166 else
5168 e = pb->num_eqs++;
5169 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5170 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5171 pb->eqs[e].coef[k] = 1;
5172 pb->eqs[e].color = color;
5175 omega_unprotect_variable (pb, var);
5176 return omega_simplify_problem (pb);
5179 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5181 void
5182 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5183 int var, int value)
5185 int e;
5186 int k = pb->forwarding_address[var];
5188 if (k < 0)
5190 k = -1 - k;
5191 e = pb->num_eqs++;
5192 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5193 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5194 pb->eqs[e].coef[0] -= value;
5196 else
5198 e = pb->num_eqs++;
5199 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5200 pb->eqs[e].coef[k] = 1;
5201 pb->eqs[e].coef[0] = -value;
5204 pb->eqs[e].color = color;
5207 /* Return false when the upper and lower bounds are not coupled.
5208 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5209 variable I. */
5211 bool
5212 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5214 int n_vars = pb->num_vars;
5215 int e, j;
5216 bool is_simple;
5217 bool coupled = false;
5219 *lower_bound = neg_infinity;
5220 *upper_bound = pos_infinity;
5221 i = pb->forwarding_address[i];
5223 if (i < 0)
5225 i = -i - 1;
5227 for (j = 1; j <= n_vars; j++)
5228 if (pb->subs[i].coef[j] != 0)
5229 return true;
5231 *upper_bound = *lower_bound = pb->subs[i].coef[0];
5232 return false;
5235 for (e = pb->num_subs - 1; e >= 0; e--)
5236 if (pb->subs[e].coef[i] != 0)
5237 coupled = true;
5239 for (e = pb->num_eqs - 1; e >= 0; e--)
5240 if (pb->eqs[e].coef[i] != 0)
5242 is_simple = true;
5244 for (j = 1; j <= n_vars; j++)
5245 if (i != j && pb->eqs[e].coef[j] != 0)
5247 is_simple = false;
5248 coupled = true;
5249 break;
5252 if (!is_simple)
5253 continue;
5254 else
5256 *lower_bound = *upper_bound =
5257 -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5258 return false;
5262 for (e = pb->num_geqs - 1; e >= 0; e--)
5263 if (pb->geqs[e].coef[i] != 0)
5265 if (pb->geqs[e].key == i)
5266 *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5268 else if (pb->geqs[e].key == -i)
5269 *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5271 else
5272 coupled = true;
5275 return coupled;
5278 /* Sets the lower bound L and upper bound U for the values of variable
5279 I, and sets COULD_BE_ZERO to true if variable I might take value
5280 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5281 variable I. */
5283 static void
5284 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5285 bool *could_be_zero, int lower_bound, int upper_bound)
5287 int e, b1, b2;
5288 eqn eqn;
5289 int sign;
5290 int v;
5292 /* Preconditions. */
5293 gcc_assert (abs (pb->forwarding_address[i]) == 1
5294 && pb->num_vars + pb->num_subs == 2
5295 && pb->num_eqs + pb->num_subs == 1);
5297 /* Define variable I in terms of variable V. */
5298 if (pb->forwarding_address[i] == -1)
5300 eqn = &pb->subs[0];
5301 sign = 1;
5302 v = 1;
5304 else
5306 eqn = &pb->eqs[0];
5307 sign = -eqn->coef[1];
5308 v = 2;
5311 for (e = pb->num_geqs - 1; e >= 0; e--)
5312 if (pb->geqs[e].coef[v] != 0)
5314 if (pb->geqs[e].coef[v] == 1)
5315 lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5317 else
5318 upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5321 if (lower_bound > upper_bound)
5323 *l = pos_infinity;
5324 *u = neg_infinity;
5325 *could_be_zero = 0;
5326 return;
5329 if (lower_bound == neg_infinity)
5331 if (eqn->coef[v] > 0)
5332 b1 = sign * neg_infinity;
5334 else
5335 b1 = -sign * neg_infinity;
5337 else
5338 b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5340 if (upper_bound == pos_infinity)
5342 if (eqn->coef[v] > 0)
5343 b2 = sign * pos_infinity;
5345 else
5346 b2 = -sign * pos_infinity;
5348 else
5349 b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5351 *l = MAX (*l, b1 <= b2 ? b1 : b2);
5352 *u = MIN (*u, b1 <= b2 ? b2 : b1);
5354 *could_be_zero = (*l <= 0 && 0 <= *u
5355 && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5358 /* Return false when a lower bound L and an upper bound U for variable
5359 I in problem PB have been initialized. */
5361 bool
5362 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5364 *l = neg_infinity;
5365 *u = pos_infinity;
5367 if (!omega_query_variable (pb, i, l, u)
5368 || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5369 return false;
5371 if (abs (pb->forwarding_address[i]) == 1
5372 && pb->num_vars + pb->num_subs == 2
5373 && pb->num_eqs + pb->num_subs == 1)
5375 bool could_be_zero;
5376 query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5377 pos_infinity);
5378 return false;
5381 return true;
5384 /* For problem PB, return an integer that represents the classic data
5385 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5386 masks that are added to the result. When DIST_KNOWN is true, DIST
5387 is set to the classic data dependence distance. LOWER_BOUND and
5388 UPPER_BOUND are bounds on the value of variable I, for example, it
5389 is possible to narrow the iteration domain with safe approximations
5390 of loop counts, and thus discard some data dependences that cannot
5391 occur. */
5394 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5395 int dd_eq, int dd_gt, int lower_bound,
5396 int upper_bound, bool *dist_known, int *dist)
5398 int result;
5399 int l, u;
5400 bool could_be_zero;
5402 l = neg_infinity;
5403 u = pos_infinity;
5405 omega_query_variable (pb, i, &l, &u);
5406 query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5407 upper_bound);
5408 result = 0;
5410 if (l < 0)
5411 result |= dd_gt;
5413 if (u > 0)
5414 result |= dd_lt;
5416 if (could_be_zero)
5417 result |= dd_eq;
5419 if (l == u)
5421 *dist_known = true;
5422 *dist = l;
5424 else
5425 *dist_known = false;
5427 return result;
5430 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5431 safe variables. Safe variables are not eliminated during the
5432 Fourier-Motzkin elimination. Safe variables are all those
5433 variables that are placed at the beginning of the array of
5434 variables: P->var[0, ..., NPROT - 1]. */
5436 omega_pb
5437 omega_alloc_problem (int nvars, int nprot)
5439 omega_pb pb;
5441 gcc_assert (nvars <= OMEGA_MAX_VARS);
5442 omega_initialize ();
5444 /* Allocate and initialize PB. */
5445 pb = XCNEW (struct omega_pb_d);
5446 pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5447 pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5448 pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5449 pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5450 pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5452 pb->hash_version = hash_version;
5453 pb->num_vars = nvars;
5454 pb->safe_vars = nprot;
5455 pb->variables_initialized = false;
5456 pb->variables_freed = false;
5457 pb->num_eqs = 0;
5458 pb->num_geqs = 0;
5459 pb->num_subs = 0;
5460 return pb;
5463 /* Keeps the state of the initialization. */
5464 static bool omega_initialized = false;
5466 /* Initialization of the Omega solver. */
5468 void
5469 omega_initialize (void)
5471 int i;
5473 if (omega_initialized)
5474 return;
5476 next_wild_card = 0;
5477 next_key = OMEGA_MAX_VARS + 1;
5478 packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5479 fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5480 fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5481 hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5483 for (i = 0; i < HASH_TABLE_SIZE; i++)
5484 hash_master[i].touched = -1;
5486 sprintf (wild_name[0], "1");
5487 sprintf (wild_name[1], "a");
5488 sprintf (wild_name[2], "b");
5489 sprintf (wild_name[3], "c");
5490 sprintf (wild_name[4], "d");
5491 sprintf (wild_name[5], "e");
5492 sprintf (wild_name[6], "f");
5493 sprintf (wild_name[7], "g");
5494 sprintf (wild_name[8], "h");
5495 sprintf (wild_name[9], "i");
5496 sprintf (wild_name[10], "j");
5497 sprintf (wild_name[11], "k");
5498 sprintf (wild_name[12], "l");
5499 sprintf (wild_name[13], "m");
5500 sprintf (wild_name[14], "n");
5501 sprintf (wild_name[15], "o");
5502 sprintf (wild_name[16], "p");
5503 sprintf (wild_name[17], "q");
5504 sprintf (wild_name[18], "r");
5505 sprintf (wild_name[19], "s");
5506 sprintf (wild_name[20], "t");
5507 sprintf (wild_name[40 - 1], "alpha");
5508 sprintf (wild_name[40 - 2], "beta");
5509 sprintf (wild_name[40 - 3], "gamma");
5510 sprintf (wild_name[40 - 4], "delta");
5511 sprintf (wild_name[40 - 5], "tau");
5512 sprintf (wild_name[40 - 6], "sigma");
5513 sprintf (wild_name[40 - 7], "chi");
5514 sprintf (wild_name[40 - 8], "omega");
5515 sprintf (wild_name[40 - 9], "pi");
5516 sprintf (wild_name[40 - 10], "ni");
5517 sprintf (wild_name[40 - 11], "Alpha");
5518 sprintf (wild_name[40 - 12], "Beta");
5519 sprintf (wild_name[40 - 13], "Gamma");
5520 sprintf (wild_name[40 - 14], "Delta");
5521 sprintf (wild_name[40 - 15], "Tau");
5522 sprintf (wild_name[40 - 16], "Sigma");
5523 sprintf (wild_name[40 - 17], "Chi");
5524 sprintf (wild_name[40 - 18], "Omega");
5525 sprintf (wild_name[40 - 19], "xxx");
5527 omega_initialized = true;