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
8 Changes copyright (C) 2005, 2006, 2007, 2008, 2009,
9 2010 Free Software Foundation, Inc.
10 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
12 This file is part of GCC.
14 GCC is free software; you can redistribute it and/or modify it under
15 the terms of the GNU General Public License as published by the Free
16 Software Foundation; either version 3, or (at your option) any later
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING3. If not see
26 <http://www.gnu.org/licenses/>. */
28 /* For a detailed description, see "Constraint-Based Array Dependence
29 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
31 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
36 #include "coretypes.h"
38 #include "diagnostic-core.h"
39 #include "tree-pass.h"
42 /* When set to true, keep substitution variables. When set to false,
43 resurrect substitution variables (convert substitutions back to EQs). */
44 static bool omega_reduce_with_subs = true;
46 /* When set to true, omega_simplify_problem checks for problem with no
47 solutions, calling verify_omega_pb. */
48 static bool omega_verify_simplification = false;
50 /* When set to true, only produce a single simplified result. */
51 static bool omega_single_result = false;
53 /* Set return_single_result to 1 when omega_single_result is true. */
54 static int return_single_result = 0;
56 /* Hash table for equations generated by the solver. */
57 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
58 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
59 static eqn hash_master;
61 static int hash_version = 0;
63 /* Set to true for making the solver enter in approximation mode. */
64 static bool in_approximate_mode = false;
66 /* When set to zero, the solver is allowed to add new equalities to
67 the problem to be solved. */
68 static int conservative = 0;
70 /* Set to omega_true when the problem was successfully reduced, set to
71 omega_unknown when the solver is unable to determine an answer. */
72 static enum omega_result omega_found_reduction;
74 /* Set to true when the solver is allowed to add omega_red equations. */
75 static bool create_color = false;
77 /* Set to nonzero when the problem to be solved can be reduced. */
78 static int may_be_red = 0;
80 /* When false, there should be no substitution equations in the
81 simplified problem. */
82 static int please_no_equalities_in_simplified_problems = 0;
84 /* Variables names for pretty printing. */
85 static char wild_name[200][40];
87 /* Pointer to the void problem. */
88 static omega_pb no_problem = (omega_pb) 0;
90 /* Pointer to the problem to be solved. */
91 static omega_pb original_problem = (omega_pb) 0;
94 /* Return the integer A divided by B. */
97 int_div (int a, int b)
102 return -((-a + b - 1)/b);
105 /* Return the integer A modulo B. */
108 int_mod (int a, int b)
110 return a - b * int_div (a, b);
113 /* For X and Y positive integers, return X multiplied by Y and check
114 that the result does not overflow. */
117 check_pos_mul (int x, int y)
120 gcc_assert ((INT_MAX) / x > y);
125 /* Return X multiplied by Y and check that the result does not
129 check_mul (int x, int y)
134 return check_pos_mul (x, y);
136 return -check_pos_mul (x, -y);
139 return -check_pos_mul (-x, y);
141 return check_pos_mul (-x, -y);
144 /* Test whether equation E is red. */
147 omega_eqn_is_red (eqn e, int desired_res)
149 return (desired_res == omega_simplify && e->color == omega_red);
152 /* Return a string for VARIABLE. */
155 omega_var_to_str (int variable)
157 if (0 <= variable && variable <= 20)
158 return wild_name[variable];
160 if (-20 < variable && variable < 0)
161 return wild_name[40 + variable];
163 /* Collapse all the entries that would have overflowed. */
164 return wild_name[21];
167 /* Return a string for variable I in problem PB. */
170 omega_variable_to_str (omega_pb pb, int i)
172 return omega_var_to_str (pb->var[i]);
175 /* Do nothing function: used for default initializations. */
178 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
182 void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
184 /* Compute the greatest common divisor of A and B. */
202 /* Print to FILE from PB equation E with all its coefficients
206 omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
210 int n = pb->num_vars;
213 for (i = 1; i <= n; i++)
214 if (c * e->coef[i] > 0)
219 if (c * e->coef[i] == 1)
220 fprintf (file, "%s", omega_variable_to_str (pb, i));
222 fprintf (file, "%d * %s", c * e->coef[i],
223 omega_variable_to_str (pb, i));
227 for (i = 1; i <= n; i++)
228 if (i != went_first && c * e->coef[i] != 0)
230 if (!first && c * e->coef[i] > 0)
231 fprintf (file, " + ");
235 if (c * e->coef[i] == 1)
236 fprintf (file, "%s", omega_variable_to_str (pb, i));
237 else if (c * e->coef[i] == -1)
238 fprintf (file, " - %s", omega_variable_to_str (pb, i));
240 fprintf (file, "%d * %s", c * e->coef[i],
241 omega_variable_to_str (pb, i));
244 if (!first && c * e->coef[0] > 0)
245 fprintf (file, " + ");
247 if (first || c * e->coef[0] != 0)
248 fprintf (file, "%d", c * e->coef[0]);
251 /* Print to FILE the equation E of problem PB. */
254 omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
257 int n = pb->num_vars + extra;
258 bool is_lt = test && e->coef[0] == -1;
266 else if (e->key != 0)
267 fprintf (file, "%d: ", e->key);
270 if (e->color == omega_red)
275 for (i = is_lt ? 1 : 0; i <= n; i++)
279 fprintf (file, " + ");
284 fprintf (file, "%d", -e->coef[i]);
285 else if (e->coef[i] == -1)
286 fprintf (file, "%s", omega_variable_to_str (pb, i));
288 fprintf (file, "%d * %s", -e->coef[i],
289 omega_variable_to_str (pb, i));
304 fprintf (file, " = ");
306 fprintf (file, " < ");
308 fprintf (file, " <= ");
312 for (i = 0; i <= n; i++)
316 fprintf (file, " + ");
321 fprintf (file, "%d", e->coef[i]);
322 else if (e->coef[i] == 1)
323 fprintf (file, "%s", omega_variable_to_str (pb, i));
325 fprintf (file, "%d * %s", e->coef[i],
326 omega_variable_to_str (pb, i));
332 if (e->color == omega_red)
336 /* Print to FILE all the variables of problem PB. */
339 omega_print_vars (FILE *file, omega_pb pb)
343 fprintf (file, "variables = ");
345 if (pb->safe_vars > 0)
346 fprintf (file, "protected (");
348 for (i = 1; i <= pb->num_vars; i++)
350 fprintf (file, "%s", omega_variable_to_str (pb, i));
352 if (i == pb->safe_vars)
355 if (i < pb->num_vars)
356 fprintf (file, ", ");
359 fprintf (file, "\n");
362 /* Debug problem PB. */
365 debug_omega_problem (omega_pb pb)
367 omega_print_problem (stderr, pb);
370 /* Print to FILE problem PB. */
373 omega_print_problem (FILE *file, omega_pb pb)
377 if (!pb->variables_initialized)
378 omega_initialize_variables (pb);
380 omega_print_vars (file, pb);
382 for (e = 0; e < pb->num_eqs; e++)
384 omega_print_eq (file, pb, &pb->eqs[e]);
385 fprintf (file, "\n");
388 fprintf (file, "Done with EQ\n");
390 for (e = 0; e < pb->num_geqs; e++)
392 omega_print_geq (file, pb, &pb->geqs[e]);
393 fprintf (file, "\n");
396 fprintf (file, "Done with GEQ\n");
398 for (e = 0; e < pb->num_subs; e++)
400 eqn eq = &pb->subs[e];
402 if (eq->color == omega_red)
406 fprintf (file, "%s := ", omega_var_to_str (eq->key));
408 fprintf (file, "#%d := ", eq->key);
410 omega_print_term (file, pb, eq, 1);
412 if (eq->color == omega_red)
415 fprintf (file, "\n");
419 /* Return the number of equations in PB tagged omega_red. */
422 omega_count_red_equations (omega_pb pb)
427 for (e = 0; e < pb->num_eqs; e++)
428 if (pb->eqs[e].color == omega_red)
430 for (i = pb->num_vars; i > 0; i--)
431 if (pb->geqs[e].coef[i])
434 if (i == 0 && pb->geqs[e].coef[0] == 1)
440 for (e = 0; e < pb->num_geqs; e++)
441 if (pb->geqs[e].color == omega_red)
444 for (e = 0; e < pb->num_subs; e++)
445 if (pb->subs[e].color == omega_red)
451 /* Print to FILE all the equations in PB that are tagged omega_red. */
454 omega_print_red_equations (FILE *file, omega_pb pb)
458 if (!pb->variables_initialized)
459 omega_initialize_variables (pb);
461 omega_print_vars (file, pb);
463 for (e = 0; e < pb->num_eqs; e++)
464 if (pb->eqs[e].color == omega_red)
466 omega_print_eq (file, pb, &pb->eqs[e]);
467 fprintf (file, "\n");
470 for (e = 0; e < pb->num_geqs; e++)
471 if (pb->geqs[e].color == omega_red)
473 omega_print_geq (file, pb, &pb->geqs[e]);
474 fprintf (file, "\n");
477 for (e = 0; e < pb->num_subs; e++)
478 if (pb->subs[e].color == omega_red)
480 eqn eq = &pb->subs[e];
484 fprintf (file, "%s := ", omega_var_to_str (eq->key));
486 fprintf (file, "#%d := ", eq->key);
488 omega_print_term (file, pb, eq, 1);
489 fprintf (file, "]\n");
493 /* Pretty print PB to FILE. */
496 omega_pretty_print_problem (FILE *file, omega_pb pb)
498 int e, v, v1, v2, v3, t;
499 bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
500 int stuffPrinted = 0;
505 } partial_order_type;
507 partial_order_type **po = XNEWVEC (partial_order_type *,
508 OMEGA_MAX_VARS * OMEGA_MAX_VARS);
509 int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
510 int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
511 int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
512 int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
513 int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
517 if (!pb->variables_initialized)
518 omega_initialize_variables (pb);
520 if (pb->num_vars > 0)
522 omega_eliminate_redundant (pb, false);
524 for (e = 0; e < pb->num_eqs; e++)
527 fprintf (file, "; ");
530 omega_print_eq (file, pb, &pb->eqs[e]);
533 for (e = 0; e < pb->num_geqs; e++)
538 for (v = 1; v <= pb->num_vars; v++)
540 last_links[v] = first_links[v] = 0;
543 for (v2 = 1; v2 <= pb->num_vars; v2++)
547 for (e = 0; e < pb->num_geqs; e++)
550 for (v = 1; v <= pb->num_vars; v++)
551 if (pb->geqs[e].coef[v] == 1)
553 else if (pb->geqs[e].coef[v] == -1)
558 while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
563 while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
568 while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
571 if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
573 || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
575 /* Not a partial order relation. */
579 if (pb->geqs[e].coef[v1] == 1)
586 /* Relation is v1 <= v2 or v1 < v2. */
587 po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
591 for (v = 1; v <= pb->num_vars; v++)
592 chain_length[v] = last_links[v];
594 /* Just in case pb->num_vars <= 0. */
596 for (t = 0; t < pb->num_vars; t++)
600 for (v1 = 1; v1 <= pb->num_vars; v1++)
601 for (v2 = 1; v2 <= pb->num_vars; v2++)
602 if (po[v1][v2] != none &&
603 chain_length[v1] <= chain_length[v2])
605 chain_length[v1] = chain_length[v2] + 1;
610 /* Caught in cycle. */
611 gcc_assert (!change);
613 for (v1 = 1; v1 <= pb->num_vars; v1++)
614 if (chain_length[v1] == 0)
619 for (v1 = 2; v1 <= pb->num_vars; v1++)
620 if (chain_length[v1] + first_links[v1] >
621 chain_length[v] + first_links[v])
624 if (chain_length[v] + first_links[v] == 0)
628 fprintf (file, "; ");
632 /* Chain starts at v. */
637 for (e = 0; e < pb->num_geqs; e++)
638 if (live[e] && pb->geqs[e].coef[v] == 1)
641 fprintf (file, ", ");
643 tmp = pb->geqs[e].coef[v];
644 pb->geqs[e].coef[v] = 0;
645 omega_print_term (file, pb, &pb->geqs[e], -1);
646 pb->geqs[e].coef[v] = tmp;
652 fprintf (file, " <= ");
661 for (v2 = 1; v2 <= pb->num_vars; v2++)
662 if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
665 if (v2 > pb->num_vars)
672 fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
674 for (multiprint = false, i = 1; i < m; i++)
680 fprintf (file, " <= ");
682 fprintf (file, " < ");
684 fprintf (file, "%s", omega_variable_to_str (pb, v2));
685 live[po_eq[v][v2]] = false;
687 if (!multiprint && i < m - 1)
688 for (v3 = 1; v3 <= pb->num_vars; v3++)
690 if (v == v3 || v2 == v3
691 || po[v][v2] != po[v][v3]
692 || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
695 fprintf (file, ",%s", omega_variable_to_str (pb, v3));
696 live[po_eq[v][v3]] = false;
697 live[po_eq[v3][chain[i + 1]]] = false;
705 /* Print last_links. */
710 for (e = 0; e < pb->num_geqs; e++)
711 if (live[e] && pb->geqs[e].coef[v] == -1)
714 fprintf (file, ", ");
716 fprintf (file, " <= ");
718 tmp = pb->geqs[e].coef[v];
719 pb->geqs[e].coef[v] = 0;
720 omega_print_term (file, pb, &pb->geqs[e], 1);
721 pb->geqs[e].coef[v] = tmp;
728 for (e = 0; e < pb->num_geqs; e++)
732 fprintf (file, "; ");
734 omega_print_geq (file, pb, &pb->geqs[e]);
737 for (e = 0; e < pb->num_subs; e++)
739 eqn eq = &pb->subs[e];
742 fprintf (file, "; ");
747 fprintf (file, "%s := ", omega_var_to_str (eq->key));
749 fprintf (file, "#%d := ", eq->key);
751 omega_print_term (file, pb, eq, 1);
764 /* Assign to variable I in PB the next wildcard name. The name of a
765 wildcard is a negative number. */
766 static int next_wild_card = 0;
769 omega_name_wild_card (omega_pb pb, int i)
772 if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
774 pb->var[i] = next_wild_card;
777 /* Return the index of the last protected (or safe) variable in PB,
778 after having added a new wildcard variable. */
781 omega_add_new_wild_card (omega_pb pb)
784 int i = ++pb->safe_vars;
787 /* Make a free place in the protected (safe) variables, by moving
788 the non protected variable pointed by "I" at the end, ie. at
789 offset pb->num_vars. */
790 if (pb->num_vars != i)
792 /* Move "I" for all the inequalities. */
793 for (e = pb->num_geqs - 1; e >= 0; e--)
795 if (pb->geqs[e].coef[i])
796 pb->geqs[e].touched = 1;
798 pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
801 /* Move "I" for all the equalities. */
802 for (e = pb->num_eqs - 1; e >= 0; e--)
803 pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
805 /* Move "I" for all the substitutions. */
806 for (e = pb->num_subs - 1; e >= 0; e--)
807 pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
809 /* Move the identifier. */
810 pb->var[pb->num_vars] = pb->var[i];
813 /* Initialize at zero all the coefficients */
814 for (e = pb->num_geqs - 1; e >= 0; e--)
815 pb->geqs[e].coef[i] = 0;
817 for (e = pb->num_eqs - 1; e >= 0; e--)
818 pb->eqs[e].coef[i] = 0;
820 for (e = pb->num_subs - 1; e >= 0; e--)
821 pb->subs[e].coef[i] = 0;
823 /* And give it a name. */
824 omega_name_wild_card (pb, i);
828 /* Delete inequality E from problem PB that has N_VARS variables. */
831 omega_delete_geq (omega_pb pb, int e, int n_vars)
833 if (dump_file && (dump_flags & TDF_DETAILS))
835 fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
836 omega_print_geq (dump_file, pb, &pb->geqs[e]);
837 fprintf (dump_file, "\n");
840 if (e < pb->num_geqs - 1)
841 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
846 /* Delete extra inequality E from problem PB that has N_VARS
850 omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
852 if (dump_file && (dump_flags & TDF_DETAILS))
854 fprintf (dump_file, "Deleting %d: ",e);
855 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
856 fprintf (dump_file, "\n");
859 if (e < pb->num_geqs - 1)
860 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
866 /* Remove variable I from problem PB. */
869 omega_delete_variable (omega_pb pb, int i)
871 int n_vars = pb->num_vars;
874 if (omega_safe_var_p (pb, i))
876 int j = pb->safe_vars;
878 for (e = pb->num_geqs - 1; e >= 0; e--)
880 pb->geqs[e].touched = 1;
881 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
882 pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
885 for (e = pb->num_eqs - 1; e >= 0; e--)
887 pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
888 pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
891 for (e = pb->num_subs - 1; e >= 0; e--)
893 pb->subs[e].coef[i] = pb->subs[e].coef[j];
894 pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
897 pb->var[i] = pb->var[j];
898 pb->var[j] = pb->var[n_vars];
902 for (e = pb->num_geqs - 1; e >= 0; e--)
903 if (pb->geqs[e].coef[n_vars])
905 pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
906 pb->geqs[e].touched = 1;
909 for (e = pb->num_eqs - 1; e >= 0; e--)
910 pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
912 for (e = pb->num_subs - 1; e >= 0; e--)
913 pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
915 pb->var[i] = pb->var[n_vars];
918 if (omega_safe_var_p (pb, i))
924 /* Because the coefficients of an equation are sparse, PACKING records
925 indices for non null coefficients. */
928 /* Set up the coefficients of PACKING, following the coefficients of
929 equation EQN that has NUM_VARS variables. */
932 setup_packing (eqn eqn, int num_vars)
937 for (k = num_vars; k >= 0; k--)
944 /* Computes a linear combination of EQ and SUB at VAR with coefficient
945 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
946 non null indices of SUB stored in PACKING. */
949 omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
952 if (eq->coef[var] != 0)
954 if (eq->color == omega_black)
958 int j, k = eq->coef[var];
962 for (j = top_var; j >= 0; j--)
963 eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
968 /* Substitute in PB variable VAR with "C * SUB". */
971 omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
973 int e, top_var = setup_packing (sub, pb->num_vars);
975 *found_black = false;
977 if (dump_file && (dump_flags & TDF_DETAILS))
979 if (sub->color == omega_red)
980 fprintf (dump_file, "[");
982 fprintf (dump_file, "substituting using %s := ",
983 omega_variable_to_str (pb, var));
984 omega_print_term (dump_file, pb, sub, -c);
986 if (sub->color == omega_red)
987 fprintf (dump_file, "]");
989 fprintf (dump_file, "\n");
990 omega_print_vars (dump_file, pb);
993 for (e = pb->num_eqs - 1; e >= 0; e--)
995 eqn eqn = &(pb->eqs[e]);
997 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
999 if (dump_file && (dump_flags & TDF_DETAILS))
1001 omega_print_eq (dump_file, pb, eqn);
1002 fprintf (dump_file, "\n");
1006 for (e = pb->num_geqs - 1; e >= 0; e--)
1008 eqn eqn = &(pb->geqs[e]);
1010 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
1012 if (eqn->coef[var] && eqn->color == omega_red)
1015 if (dump_file && (dump_flags & TDF_DETAILS))
1017 omega_print_geq (dump_file, pb, eqn);
1018 fprintf (dump_file, "\n");
1022 for (e = pb->num_subs - 1; e >= 0; e--)
1024 eqn eqn = &(pb->subs[e]);
1026 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
1028 if (dump_file && (dump_flags & TDF_DETAILS))
1030 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1031 omega_print_term (dump_file, pb, eqn, 1);
1032 fprintf (dump_file, "\n");
1036 if (dump_file && (dump_flags & TDF_DETAILS))
1037 fprintf (dump_file, "---\n\n");
1039 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1040 *found_black = true;
1043 /* Substitute in PB variable VAR with "C * SUB". */
1046 omega_substitute (omega_pb pb, eqn sub, int var, int c)
1049 int top_var = setup_packing (sub, pb->num_vars);
1051 if (dump_file && (dump_flags & TDF_DETAILS))
1053 fprintf (dump_file, "substituting using %s := ",
1054 omega_variable_to_str (pb, var));
1055 omega_print_term (dump_file, pb, sub, -c);
1056 fprintf (dump_file, "\n");
1057 omega_print_vars (dump_file, pb);
1062 for (e = pb->num_eqs - 1; e >= 0; e--)
1063 pb->eqs[e].coef[var] = 0;
1065 for (e = pb->num_geqs - 1; e >= 0; e--)
1066 if (pb->geqs[e].coef[var] != 0)
1068 pb->geqs[e].touched = 1;
1069 pb->geqs[e].coef[var] = 0;
1072 for (e = pb->num_subs - 1; e >= 0; e--)
1073 pb->subs[e].coef[var] = 0;
1075 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1078 eqn eqn = &(pb->subs[pb->num_subs++]);
1080 for (k = pb->num_vars; k >= 0; k--)
1083 eqn->key = pb->var[var];
1084 eqn->color = omega_black;
1087 else if (top_var == 0 && packing[0] == 0)
1089 c = -sub->coef[0] * c;
1091 for (e = pb->num_eqs - 1; e >= 0; e--)
1093 pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
1094 pb->eqs[e].coef[var] = 0;
1097 for (e = pb->num_geqs - 1; e >= 0; e--)
1098 if (pb->geqs[e].coef[var] != 0)
1100 pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
1101 pb->geqs[e].coef[var] = 0;
1102 pb->geqs[e].touched = 1;
1105 for (e = pb->num_subs - 1; e >= 0; e--)
1107 pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
1108 pb->subs[e].coef[var] = 0;
1111 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1114 eqn eqn = &(pb->subs[pb->num_subs++]);
1116 for (k = pb->num_vars; k >= 1; k--)
1120 eqn->key = pb->var[var];
1121 eqn->color = omega_black;
1124 if (dump_file && (dump_flags & TDF_DETAILS))
1126 fprintf (dump_file, "---\n\n");
1127 omega_print_problem (dump_file, pb);
1128 fprintf (dump_file, "===\n\n");
1133 for (e = pb->num_eqs - 1; e >= 0; e--)
1135 eqn eqn = &(pb->eqs[e]);
1136 int k = eqn->coef[var];
1143 for (j = top_var; j >= 0; j--)
1146 eqn->coef[j0] -= sub->coef[j0] * k;
1150 if (dump_file && (dump_flags & TDF_DETAILS))
1152 omega_print_eq (dump_file, pb, eqn);
1153 fprintf (dump_file, "\n");
1157 for (e = pb->num_geqs - 1; e >= 0; e--)
1159 eqn eqn = &(pb->geqs[e]);
1160 int k = eqn->coef[var];
1168 for (j = top_var; j >= 0; j--)
1171 eqn->coef[j0] -= sub->coef[j0] * k;
1175 if (dump_file && (dump_flags & TDF_DETAILS))
1177 omega_print_geq (dump_file, pb, eqn);
1178 fprintf (dump_file, "\n");
1182 for (e = pb->num_subs - 1; e >= 0; e--)
1184 eqn eqn = &(pb->subs[e]);
1185 int k = eqn->coef[var];
1192 for (j = top_var; j >= 0; j--)
1195 eqn->coef[j0] -= sub->coef[j0] * k;
1199 if (dump_file && (dump_flags & TDF_DETAILS))
1201 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1202 omega_print_term (dump_file, pb, eqn, 1);
1203 fprintf (dump_file, "\n");
1207 if (dump_file && (dump_flags & TDF_DETAILS))
1209 fprintf (dump_file, "---\n\n");
1210 omega_print_problem (dump_file, pb);
1211 fprintf (dump_file, "===\n\n");
1214 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1217 eqn eqn = &(pb->subs[pb->num_subs++]);
1220 for (k = pb->num_vars; k >= 0; k--)
1221 eqn->coef[k] = c * (sub->coef[k]);
1223 eqn->key = pb->var[var];
1224 eqn->color = sub->color;
1229 /* Solve e = factor alpha for x_j and substitute. */
1232 omega_do_mod (omega_pb pb, int factor, int e, int j)
1235 eqn eq = omega_alloc_eqns (0, 1);
1237 bool kill_j = false;
1239 omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
1241 for (k = pb->num_vars; k >= 0; k--)
1243 eq->coef[k] = int_mod (eq->coef[k], factor);
1245 if (2 * eq->coef[k] >= factor)
1246 eq->coef[k] -= factor;
1249 nfactor = eq->coef[j];
1251 if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
1253 i = omega_add_new_wild_card (pb);
1254 eq->coef[pb->num_vars] = eq->coef[i];
1256 eq->coef[i] = -factor;
1261 eq->coef[j] = -factor;
1262 if (!omega_wildcard_p (pb, j))
1263 omega_name_wild_card (pb, j);
1266 omega_substitute (pb, eq, j, nfactor);
1268 for (k = pb->num_vars; k >= 0; k--)
1269 pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
1272 omega_delete_variable (pb, j);
1274 if (dump_file && (dump_flags & TDF_DETAILS))
1276 fprintf (dump_file, "Mod-ing and normalizing produces:\n");
1277 omega_print_problem (dump_file, pb);
1280 omega_free_eqns (eq, 1);
1283 /* Multiplies by -1 inequality E. */
1286 omega_negate_geq (omega_pb pb, int e)
1290 for (i = pb->num_vars; i >= 0; i--)
1291 pb->geqs[e].coef[i] *= -1;
1293 pb->geqs[e].coef[0]--;
1294 pb->geqs[e].touched = 1;
1297 /* Returns OMEGA_TRUE when problem PB has a solution. */
1299 static enum omega_result
1300 verify_omega_pb (omega_pb pb)
1302 enum omega_result result;
1304 bool any_color = false;
1305 omega_pb tmp_problem = XNEW (struct omega_pb_d);
1307 omega_copy_problem (tmp_problem, pb);
1308 tmp_problem->safe_vars = 0;
1309 tmp_problem->num_subs = 0;
1311 for (e = pb->num_geqs - 1; e >= 0; e--)
1312 if (pb->geqs[e].color == omega_red)
1318 if (please_no_equalities_in_simplified_problems)
1322 original_problem = no_problem;
1324 original_problem = pb;
1326 if (dump_file && (dump_flags & TDF_DETAILS))
1328 fprintf (dump_file, "verifying problem");
1331 fprintf (dump_file, " (color mode)");
1333 fprintf (dump_file, " :\n");
1334 omega_print_problem (dump_file, pb);
1337 result = omega_solve_problem (tmp_problem, omega_unknown);
1338 original_problem = no_problem;
1341 if (dump_file && (dump_flags & TDF_DETAILS))
1343 if (result != omega_false)
1344 fprintf (dump_file, "verified problem\n");
1346 fprintf (dump_file, "disproved problem\n");
1347 omega_print_problem (dump_file, pb);
1353 /* Add a new equality to problem PB at last position E. */
1356 adding_equality_constraint (omega_pb pb, int e)
1358 if (original_problem != no_problem
1359 && original_problem != pb
1363 int e2 = original_problem->num_eqs++;
1365 if (dump_file && (dump_flags & TDF_DETAILS))
1367 "adding equality constraint %d to outer problem\n", e2);
1368 omega_init_eqn_zero (&original_problem->eqs[e2],
1369 original_problem->num_vars);
1371 for (i = pb->num_vars; i >= 1; i--)
1373 for (j = original_problem->num_vars; j >= 1; j--)
1374 if (original_problem->var[j] == pb->var[i])
1379 if (dump_file && (dump_flags & TDF_DETAILS))
1380 fprintf (dump_file, "retracting\n");
1381 original_problem->num_eqs--;
1384 original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
1387 original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
1389 if (dump_file && (dump_flags & TDF_DETAILS))
1390 omega_print_problem (dump_file, original_problem);
1394 static int *fast_lookup;
1395 static int *fast_lookup_red;
1399 normalize_uncoupled,
1401 } normalize_return_type;
1403 /* Normalizes PB by removing redundant constraints. Returns
1404 normalize_false when the constraints system has no solution,
1405 otherwise returns normalize_coupled or normalize_uncoupled. */
1407 static normalize_return_type
1408 normalize_omega_problem (omega_pb pb)
1410 int e, i, j, k, n_vars;
1411 int coupled_subscripts = 0;
1413 n_vars = pb->num_vars;
1415 for (e = 0; e < pb->num_geqs; e++)
1417 if (!pb->geqs[e].touched)
1419 if (!single_var_geq (&pb->geqs[e], n_vars))
1420 coupled_subscripts = 1;
1424 int g, top_var, i0, hashCode;
1425 int *p = &packing[0];
1427 for (k = 1; k <= n_vars; k++)
1428 if (pb->geqs[e].coef[k])
1431 top_var = (p - &packing[0]) - 1;
1435 if (pb->geqs[e].coef[0] < 0)
1437 if (dump_file && (dump_flags & TDF_DETAILS))
1439 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1440 fprintf (dump_file, "\nequations have no solution \n");
1442 return normalize_false;
1445 omega_delete_geq (pb, e, n_vars);
1449 else if (top_var == 0)
1451 int singlevar = packing[0];
1453 g = pb->geqs[e].coef[singlevar];
1457 pb->geqs[e].coef[singlevar] = 1;
1458 pb->geqs[e].key = singlevar;
1463 pb->geqs[e].coef[singlevar] = -1;
1464 pb->geqs[e].key = -singlevar;
1468 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1473 int hash_key_multiplier = 31;
1475 coupled_subscripts = 1;
1478 g = pb->geqs[e].coef[i];
1479 hashCode = g * (i + 3);
1484 for (; i0 >= 0; i0--)
1489 x = pb->geqs[e].coef[i];
1490 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1505 for (; i0 >= 0; i0--)
1509 x = pb->geqs[e].coef[i];
1510 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1515 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1518 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1519 hashCode = pb->geqs[e].coef[i] * (i + 3);
1521 for (; i0 >= 0; i0--)
1524 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1525 hashCode = hashCode * hash_key_multiplier * (i + 3)
1526 + pb->geqs[e].coef[i];
1530 g2 = abs (hashCode);
1532 if (dump_file && (dump_flags & TDF_DETAILS))
1534 fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
1535 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1536 fprintf (dump_file, "\n");
1539 j = g2 % HASH_TABLE_SIZE;
1542 eqn proto = &(hash_master[j]);
1544 if (proto->touched == g2)
1546 if (proto->coef[0] == top_var)
1549 for (i0 = top_var; i0 >= 0; i0--)
1553 if (pb->geqs[e].coef[i] != proto->coef[i])
1557 for (i0 = top_var; i0 >= 0; i0--)
1561 if (pb->geqs[e].coef[i] != -proto->coef[i])
1568 pb->geqs[e].key = proto->key;
1570 pb->geqs[e].key = -proto->key;
1575 else if (proto->touched < 0)
1577 omega_init_eqn_zero (proto, pb->num_vars);
1579 for (i0 = top_var; i0 >= 0; i0--)
1582 proto->coef[i] = pb->geqs[e].coef[i];
1585 for (i0 = top_var; i0 >= 0; i0--)
1588 proto->coef[i] = -pb->geqs[e].coef[i];
1591 proto->coef[0] = top_var;
1592 proto->touched = g2;
1594 if (dump_file && (dump_flags & TDF_DETAILS))
1595 fprintf (dump_file, " constraint key = %d\n",
1598 proto->key = next_key++;
1600 /* Too many hash keys generated. */
1601 gcc_assert (proto->key <= MAX_KEYS);
1604 pb->geqs[e].key = proto->key;
1606 pb->geqs[e].key = -proto->key;
1611 j = (j + 1) % HASH_TABLE_SIZE;
1615 pb->geqs[e].touched = 0;
1619 int eKey = pb->geqs[e].key;
1623 int cTerm = pb->geqs[e].coef[0];
1624 e2 = fast_lookup[MAX_KEYS - eKey];
1626 if (e2 < e && pb->geqs[e2].key == -eKey
1627 && pb->geqs[e2].color == omega_black)
1629 if (pb->geqs[e2].coef[0] < -cTerm)
1631 if (dump_file && (dump_flags & TDF_DETAILS))
1633 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1634 fprintf (dump_file, "\n");
1635 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1637 "\nequations have no solution \n");
1639 return normalize_false;
1642 if (pb->geqs[e2].coef[0] == -cTerm
1644 || pb->geqs[e].color == omega_black))
1646 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1648 if (pb->geqs[e].color == omega_black)
1649 adding_equality_constraint (pb, pb->num_eqs);
1651 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1655 e2 = fast_lookup_red[MAX_KEYS - eKey];
1657 if (e2 < e && pb->geqs[e2].key == -eKey
1658 && pb->geqs[e2].color == omega_red)
1660 if (pb->geqs[e2].coef[0] < -cTerm)
1662 if (dump_file && (dump_flags & TDF_DETAILS))
1664 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1665 fprintf (dump_file, "\n");
1666 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1668 "\nequations have no solution \n");
1670 return normalize_false;
1673 if (pb->geqs[e2].coef[0] == -cTerm && create_color)
1675 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1677 pb->eqs[pb->num_eqs].color = omega_red;
1679 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1683 e2 = fast_lookup[MAX_KEYS + eKey];
1685 if (e2 < e && pb->geqs[e2].key == eKey
1686 && pb->geqs[e2].color == omega_black)
1688 if (pb->geqs[e2].coef[0] > cTerm)
1690 if (pb->geqs[e].color == omega_black)
1692 if (dump_file && (dump_flags & TDF_DETAILS))
1695 "Removing Redundant Equation: ");
1696 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1697 fprintf (dump_file, "\n");
1699 "[a] Made Redundant by: ");
1700 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1701 fprintf (dump_file, "\n");
1703 pb->geqs[e2].coef[0] = cTerm;
1704 omega_delete_geq (pb, e, n_vars);
1711 if (dump_file && (dump_flags & TDF_DETAILS))
1713 fprintf (dump_file, "Removing Redundant Equation: ");
1714 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1715 fprintf (dump_file, "\n");
1716 fprintf (dump_file, "[b] Made Redundant by: ");
1717 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1718 fprintf (dump_file, "\n");
1720 omega_delete_geq (pb, e, n_vars);
1726 e2 = fast_lookup_red[MAX_KEYS + eKey];
1728 if (e2 < e && pb->geqs[e2].key == eKey
1729 && pb->geqs[e2].color == omega_red)
1731 if (pb->geqs[e2].coef[0] >= cTerm)
1733 if (dump_file && (dump_flags & TDF_DETAILS))
1735 fprintf (dump_file, "Removing Redundant Equation: ");
1736 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1737 fprintf (dump_file, "\n");
1738 fprintf (dump_file, "[c] Made Redundant by: ");
1739 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1740 fprintf (dump_file, "\n");
1742 pb->geqs[e2].coef[0] = cTerm;
1743 pb->geqs[e2].color = pb->geqs[e].color;
1745 else if (pb->geqs[e].color == omega_red)
1747 if (dump_file && (dump_flags & TDF_DETAILS))
1749 fprintf (dump_file, "Removing Redundant Equation: ");
1750 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1751 fprintf (dump_file, "\n");
1752 fprintf (dump_file, "[d] Made Redundant by: ");
1753 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1754 fprintf (dump_file, "\n");
1757 omega_delete_geq (pb, e, n_vars);
1764 if (pb->geqs[e].color == omega_red)
1765 fast_lookup_red[MAX_KEYS + eKey] = e;
1767 fast_lookup[MAX_KEYS + eKey] = e;
1771 create_color = false;
1772 return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
1775 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1776 of variables in EQN. */
1779 divide_eqn_by_gcd (eqn eqn, int n_vars)
1783 for (var = n_vars; var >= 0; var--)
1784 g = gcd (abs (eqn->coef[var]), g);
1787 for (var = n_vars; var >= 0; var--)
1788 eqn->coef[var] = eqn->coef[var] / g;
1791 /* Rewrite some non-safe variables in function of protected
1792 wildcard variables. */
1795 cleanout_wildcards (omega_pb pb)
1798 int n_vars = pb->num_vars;
1799 bool renormalize = false;
1801 for (e = pb->num_eqs - 1; e >= 0; e--)
1802 for (i = n_vars; !omega_safe_var_p (pb, i); i--)
1803 if (pb->eqs[e].coef[i] != 0)
1805 /* i is the last nonzero non-safe variable. */
1807 for (j = i - 1; !omega_safe_var_p (pb, j); j--)
1808 if (pb->eqs[e].coef[j] != 0)
1811 /* j is the next nonzero non-safe variable, or points
1812 to a safe variable: it is then a wildcard variable. */
1815 if (omega_safe_var_p (pb, j))
1817 eqn sub = &(pb->eqs[e]);
1818 int c = pb->eqs[e].coef[i];
1822 if (dump_file && (dump_flags & TDF_DETAILS))
1825 "Found a single wild card equality: ");
1826 omega_print_eq (dump_file, pb, &pb->eqs[e]);
1827 fprintf (dump_file, "\n");
1828 omega_print_problem (dump_file, pb);
1831 for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
1832 if (e != e2 && pb->eqs[e2].coef[i]
1833 && (pb->eqs[e2].color == omega_red
1834 || (pb->eqs[e2].color == omega_black
1835 && pb->eqs[e].color == omega_black)))
1837 eqn eqn = &(pb->eqs[e2]);
1840 for (var = n_vars; var >= 0; var--)
1841 eqn->coef[var] *= a;
1845 for (var = n_vars; var >= 0; var--)
1846 eqn->coef[var] -= sub->coef[var] * k / c;
1849 divide_eqn_by_gcd (eqn, n_vars);
1852 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
1853 if (pb->geqs[e2].coef[i]
1854 && (pb->geqs[e2].color == omega_red
1855 || (pb->eqs[e].color == omega_black
1856 && pb->geqs[e2].color == omega_black)))
1858 eqn eqn = &(pb->geqs[e2]);
1861 for (var = n_vars; var >= 0; var--)
1862 eqn->coef[var] *= a;
1866 for (var = n_vars; var >= 0; var--)
1867 eqn->coef[var] -= sub->coef[var] * k / c;
1874 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
1875 if (pb->subs[e2].coef[i]
1876 && (pb->subs[e2].color == omega_red
1877 || (pb->subs[e2].color == omega_black
1878 && pb->eqs[e].color == omega_black)))
1880 eqn eqn = &(pb->subs[e2]);
1883 for (var = n_vars; var >= 0; var--)
1884 eqn->coef[var] *= a;
1888 for (var = n_vars; var >= 0; var--)
1889 eqn->coef[var] -= sub->coef[var] * k / c;
1892 divide_eqn_by_gcd (eqn, n_vars);
1895 if (dump_file && (dump_flags & TDF_DETAILS))
1897 fprintf (dump_file, "cleaned-out wildcard: ");
1898 omega_print_problem (dump_file, pb);
1905 normalize_omega_problem (pb);
1908 /* Swap values contained in I and J. */
1911 swap (int *i, int *j)
1919 /* Swap values contained in I and J. */
1922 bswap (bool *i, bool *j)
1930 /* Make variable IDX unprotected in PB, by swapping its index at the
1931 PB->safe_vars rank. */
1934 omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
1936 /* If IDX is protected... */
1937 if (*idx < pb->safe_vars)
1939 /* ... swap its index with the last non protected index. */
1940 int j = pb->safe_vars;
1943 for (e = pb->num_geqs - 1; e >= 0; e--)
1945 pb->geqs[e].touched = 1;
1946 swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
1949 for (e = pb->num_eqs - 1; e >= 0; e--)
1950 swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
1952 for (e = pb->num_subs - 1; e >= 0; e--)
1953 swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
1956 bswap (&unprotect[*idx], &unprotect[j]);
1958 swap (&pb->var[*idx], &pb->var[j]);
1959 pb->forwarding_address[pb->var[*idx]] = *idx;
1960 pb->forwarding_address[pb->var[j]] = j;
1964 /* The variable at pb->safe_vars is also unprotected now. */
1968 /* During the Fourier-Motzkin elimination some variables are
1969 substituted with other variables. This function resurrects the
1970 substituted variables in PB. */
1973 resurrect_subs (omega_pb pb)
1975 if (pb->num_subs > 0
1976 && please_no_equalities_in_simplified_problems == 0)
1980 if (dump_file && (dump_flags & TDF_DETAILS))
1983 "problem reduced, bringing variables back to life\n");
1984 omega_print_problem (dump_file, pb);
1987 for (i = 1; omega_safe_var_p (pb, i); i++)
1988 if (omega_wildcard_p (pb, i))
1989 omega_unprotect_1 (pb, &i, NULL);
1993 for (e = pb->num_geqs - 1; e >= 0; e--)
1994 if (single_var_geq (&pb->geqs[e], pb->num_vars))
1996 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
1997 pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
2001 pb->geqs[e].touched = 1;
2002 pb->geqs[e].key = 0;
2005 for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
2007 pb->var[i + m] = pb->var[i];
2009 for (e = pb->num_geqs - 1; e >= 0; e--)
2010 pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
2012 for (e = pb->num_eqs - 1; e >= 0; e--)
2013 pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
2015 for (e = pb->num_subs - 1; e >= 0; e--)
2016 pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
2019 for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
2021 for (e = pb->num_geqs - 1; e >= 0; e--)
2022 pb->geqs[e].coef[i] = 0;
2024 for (e = pb->num_eqs - 1; e >= 0; e--)
2025 pb->eqs[e].coef[i] = 0;
2027 for (e = pb->num_subs - 1; e >= 0; e--)
2028 pb->subs[e].coef[i] = 0;
2033 for (e = pb->num_subs - 1; e >= 0; e--)
2035 pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
2036 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
2038 pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
2039 pb->eqs[pb->num_eqs].color = omega_black;
2041 if (dump_file && (dump_flags & TDF_DETAILS))
2043 fprintf (dump_file, "brought back: ");
2044 omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
2045 fprintf (dump_file, "\n");
2049 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2055 if (dump_file && (dump_flags & TDF_DETAILS))
2057 fprintf (dump_file, "variables brought back to life\n");
2058 omega_print_problem (dump_file, pb);
2061 cleanout_wildcards (pb);
2066 implies (unsigned int a, unsigned int b)
2068 return (a == (a & b));
2071 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2072 extra step is performed. Returns omega_false when there exist no
2073 solution, omega_true otherwise. */
2076 omega_eliminate_redundant (omega_pb pb, bool expensive)
2078 int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
2079 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2080 omega_pb tmp_problem;
2082 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2083 unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2084 unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2085 unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2087 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2088 unsigned int pp, pz, pn;
2090 if (dump_file && (dump_flags & TDF_DETAILS))
2092 fprintf (dump_file, "in eliminate Redundant:\n");
2093 omega_print_problem (dump_file, pb);
2096 for (e = pb->num_geqs - 1; e >= 0; e--)
2101 peqs[e] = zeqs[e] = neqs[e] = 0;
2103 for (i = pb->num_vars; i >= 1; i--)
2105 if (pb->geqs[e].coef[i] > 0)
2107 else if (pb->geqs[e].coef[i] < 0)
2117 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2119 for (e2 = e1 - 1; e2 >= 0; e2--)
2122 for (p = pb->num_vars; p > 1; p--)
2123 for (q = p - 1; q > 0; q--)
2124 if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
2125 - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
2131 pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
2132 | (neqs[e1] & peqs[e2]));
2133 pp = peqs[e1] | peqs[e2];
2134 pn = neqs[e1] | neqs[e2];
2136 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2137 if (e3 != e1 && e3 != e2)
2139 if (!implies (zeqs[e3], pz))
2142 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2143 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2144 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2145 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2148 if (alpha1 * alpha2 <= 0)
2160 /* Trying to prove e3 is redundant. */
2161 if (!implies (peqs[e3], pp)
2162 || !implies (neqs[e3], pn))
2165 if (pb->geqs[e3].color == omega_black
2166 && (pb->geqs[e1].color == omega_red
2167 || pb->geqs[e2].color == omega_red))
2170 for (k = pb->num_vars; k >= 1; k--)
2171 if (alpha3 * pb->geqs[e3].coef[k]
2172 != (alpha1 * pb->geqs[e1].coef[k]
2173 + alpha2 * pb->geqs[e2].coef[k]))
2176 c = (alpha1 * pb->geqs[e1].coef[0]
2177 + alpha2 * pb->geqs[e2].coef[0]);
2179 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2181 if (dump_file && (dump_flags & TDF_DETAILS))
2184 "found redundant inequality\n");
2186 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2187 alpha1, alpha2, alpha3);
2189 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2190 fprintf (dump_file, "\n");
2191 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2192 fprintf (dump_file, "\n=> ");
2193 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2194 fprintf (dump_file, "\n\n");
2202 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2203 or trying to prove e3 < 0, and therefore the
2204 problem has no solutions. */
2205 if (!implies (peqs[e3], pn)
2206 || !implies (neqs[e3], pp))
2209 if (pb->geqs[e1].color == omega_red
2210 || pb->geqs[e2].color == omega_red
2211 || pb->geqs[e3].color == omega_red)
2214 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2215 for (k = pb->num_vars; k >= 1; k--)
2216 if (alpha3 * pb->geqs[e3].coef[k]
2217 != (alpha1 * pb->geqs[e1].coef[k]
2218 + alpha2 * pb->geqs[e2].coef[k]))
2221 c = (alpha1 * pb->geqs[e1].coef[0]
2222 + alpha2 * pb->geqs[e2].coef[0]);
2224 if (c < alpha3 * (pb->geqs[e3].coef[0]))
2226 /* We just proved e3 < 0, so no solutions exist. */
2227 if (dump_file && (dump_flags & TDF_DETAILS))
2230 "found implied over tight inequality\n");
2232 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2233 alpha1, alpha2, -alpha3);
2234 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2235 fprintf (dump_file, "\n");
2236 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2237 fprintf (dump_file, "\n=> not ");
2238 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2239 fprintf (dump_file, "\n\n");
2247 else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2249 /* We just proved that e3 <=0, so e3 = 0. */
2250 if (dump_file && (dump_flags & TDF_DETAILS))
2253 "found implied tight inequality\n");
2255 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2256 alpha1, alpha2, -alpha3);
2257 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2258 fprintf (dump_file, "\n");
2259 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2260 fprintf (dump_file, "\n=> inverse ");
2261 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2262 fprintf (dump_file, "\n\n");
2265 omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2266 &pb->geqs[e3], pb->num_vars);
2267 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2268 adding_equality_constraint (pb, pb->num_eqs - 1);
2276 /* Delete the inequalities that were marked as dead. */
2277 for (e = pb->num_geqs - 1; e >= 0; e--)
2279 omega_delete_geq (pb, e, pb->num_vars);
2282 goto eliminate_redundant_done;
2284 tmp_problem = XNEW (struct omega_pb_d);
2287 for (e = pb->num_geqs - 1; e >= 0; e--)
2289 if (dump_file && (dump_flags & TDF_DETAILS))
2292 "checking equation %d to see if it is redundant: ", e);
2293 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2294 fprintf (dump_file, "\n");
2297 omega_copy_problem (tmp_problem, pb);
2298 omega_negate_geq (tmp_problem, e);
2299 tmp_problem->safe_vars = 0;
2300 tmp_problem->variables_freed = false;
2302 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2303 omega_delete_geq (pb, e, pb->num_vars);
2309 if (!omega_reduce_with_subs)
2311 resurrect_subs (pb);
2312 gcc_assert (please_no_equalities_in_simplified_problems
2313 || pb->num_subs == 0);
2316 eliminate_redundant_done:
2324 /* For each inequality that has coefficients bigger than 20, try to
2325 create a new constraint that cannot be derived from the original
2326 constraint and that has smaller coefficients. Add the new
2327 constraint at the end of geqs. Return the number of inequalities
2328 that have been added to PB. */
2331 smooth_weird_equations (omega_pb pb)
2333 int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2338 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2339 if (pb->geqs[e1].color == omega_black)
2343 for (v = pb->num_vars; v >= 1; v--)
2344 if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2345 g = abs (pb->geqs[e1].coef[v]);
2352 for (v = pb->num_vars; v >= 1; v--)
2353 pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2356 pb->geqs[e3].color = omega_black;
2357 pb->geqs[e3].touched = 1;
2359 pb->geqs[e3].coef[0] = 9997;
2361 if (dump_file && (dump_flags & TDF_DETAILS))
2363 fprintf (dump_file, "Checking to see if we can derive: ");
2364 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2365 fprintf (dump_file, "\n from: ");
2366 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2367 fprintf (dump_file, "\n");
2370 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2371 if (e1 != e2 && pb->geqs[e2].color == omega_black)
2373 for (p = pb->num_vars; p > 1; p--)
2375 for (q = p - 1; q > 0; q--)
2378 (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2379 pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2388 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2389 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2390 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2391 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2394 if (alpha1 * alpha2 <= 0)
2406 /* Try to prove e3 is redundant: verify
2407 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2408 for (k = pb->num_vars; k >= 1; k--)
2409 if (alpha3 * pb->geqs[e3].coef[k]
2410 != (alpha1 * pb->geqs[e1].coef[k]
2411 + alpha2 * pb->geqs[e2].coef[k]))
2414 c = alpha1 * pb->geqs[e1].coef[0]
2415 + alpha2 * pb->geqs[e2].coef[0];
2417 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2418 pb->geqs[e3].coef[0] = int_div (c, alpha3);
2423 if (pb->geqs[e3].coef[0] < 9997)
2428 if (dump_file && (dump_flags & TDF_DETAILS))
2431 "Smoothing weird equations; adding:\n");
2432 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2433 fprintf (dump_file, "\nto:\n");
2434 omega_print_problem (dump_file, pb);
2435 fprintf (dump_file, "\n\n");
2443 /* Replace tuples of inequalities, that define upper and lower half
2444 spaces, with an equation. */
2447 coalesce (omega_pb pb)
2452 int found_something = 0;
2454 for (e = 0; e < pb->num_geqs; e++)
2455 if (pb->geqs[e].color == omega_red)
2461 is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2463 for (e = 0; e < pb->num_geqs; e++)
2466 for (e = 0; e < pb->num_geqs; e++)
2467 if (pb->geqs[e].color == omega_red
2468 && !pb->geqs[e].touched)
2469 for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2470 if (!pb->geqs[e2].touched
2471 && pb->geqs[e].key == -pb->geqs[e2].key
2472 && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2473 && pb->geqs[e2].color == omega_red)
2475 omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2477 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2483 for (e = pb->num_geqs - 1; e >= 0; e--)
2485 omega_delete_geq (pb, e, pb->num_vars);
2487 if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2489 fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2491 omega_print_problem (dump_file, pb);
2497 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2498 true, continue to eliminate all the red inequalities. */
2501 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2503 int e, e2, e3, i, j, k, a, alpha1, alpha2;
2505 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2508 omega_pb tmp_problem;
2510 if (dump_file && (dump_flags & TDF_DETAILS))
2512 fprintf (dump_file, "in eliminate RED:\n");
2513 omega_print_problem (dump_file, pb);
2516 if (pb->num_eqs > 0)
2517 omega_simplify_problem (pb);
2519 for (e = pb->num_geqs - 1; e >= 0; e--)
2522 for (e = pb->num_geqs - 1; e >= 0; e--)
2523 if (pb->geqs[e].color == omega_black && !is_dead[e])
2524 for (e2 = e - 1; e2 >= 0; e2--)
2525 if (pb->geqs[e2].color == omega_black
2530 for (i = pb->num_vars; i > 1; i--)
2531 for (j = i - 1; j > 0; j--)
2532 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2533 - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2539 if (dump_file && (dump_flags & TDF_DETAILS))
2542 "found two equations to combine, i = %s, ",
2543 omega_variable_to_str (pb, i));
2544 fprintf (dump_file, "j = %s, alpha = %d\n",
2545 omega_variable_to_str (pb, j), a);
2546 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2547 fprintf (dump_file, "\n");
2548 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2549 fprintf (dump_file, "\n");
2552 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2553 if (pb->geqs[e3].color == omega_red)
2555 alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2556 - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2557 alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2558 - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2560 if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2561 || (a < 0 && alpha1 < 0 && alpha2 < 0))
2563 if (dump_file && (dump_flags & TDF_DETAILS))
2566 "alpha1 = %d, alpha2 = %d;"
2567 "comparing against: ",
2569 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2570 fprintf (dump_file, "\n");
2573 for (k = pb->num_vars; k >= 0; k--)
2575 c = (alpha1 * pb->geqs[e].coef[k]
2576 + alpha2 * pb->geqs[e2].coef[k]);
2578 if (c != a * pb->geqs[e3].coef[k])
2581 if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2582 fprintf (dump_file, " %s: %d, %d\n",
2583 omega_variable_to_str (pb, k), c,
2584 a * pb->geqs[e3].coef[k]);
2589 ((a > 0 && c < a * pb->geqs[e3].coef[k])
2590 || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2592 if (dump_file && (dump_flags & TDF_DETAILS))
2596 "red equation#%d is dead "
2597 "(%d dead so far, %d remain)\n",
2599 pb->num_geqs - dead_count);
2600 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2601 fprintf (dump_file, "\n");
2602 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2603 fprintf (dump_file, "\n");
2604 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2605 fprintf (dump_file, "\n");
2613 for (e = pb->num_geqs - 1; e >= 0; e--)
2615 omega_delete_geq (pb, e, pb->num_vars);
2619 if (dump_file && (dump_flags & TDF_DETAILS))
2621 fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2622 omega_print_problem (dump_file, pb);
2625 for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2626 if (pb->geqs[e].color == omega_red)
2631 if (dump_file && (dump_flags & TDF_DETAILS))
2632 fprintf (dump_file, "fast checks worked\n");
2634 if (!omega_reduce_with_subs)
2635 gcc_assert (please_no_equalities_in_simplified_problems
2636 || pb->num_subs == 0);
2641 if (!omega_verify_simplification
2642 && verify_omega_pb (pb) == omega_false)
2646 tmp_problem = XNEW (struct omega_pb_d);
2648 for (e = pb->num_geqs - 1; e >= 0; e--)
2649 if (pb->geqs[e].color == omega_red)
2651 if (dump_file && (dump_flags & TDF_DETAILS))
2654 "checking equation %d to see if it is redundant: ", e);
2655 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2656 fprintf (dump_file, "\n");
2659 omega_copy_problem (tmp_problem, pb);
2660 omega_negate_geq (tmp_problem, e);
2661 tmp_problem->safe_vars = 0;
2662 tmp_problem->variables_freed = false;
2663 tmp_problem->num_subs = 0;
2665 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2667 if (dump_file && (dump_flags & TDF_DETAILS))
2668 fprintf (dump_file, "it is redundant\n");
2669 omega_delete_geq (pb, e, pb->num_vars);
2673 if (dump_file && (dump_flags & TDF_DETAILS))
2674 fprintf (dump_file, "it is not redundant\n");
2678 if (dump_file && (dump_flags & TDF_DETAILS))
2679 fprintf (dump_file, "no need to check other red equations\n");
2687 /* omega_simplify_problem (pb); */
2689 if (!omega_reduce_with_subs)
2690 gcc_assert (please_no_equalities_in_simplified_problems
2691 || pb->num_subs == 0);
2694 /* Transform some wildcard variables to non-safe variables. */
2697 chain_unprotect (omega_pb pb)
2700 bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2702 for (i = 1; omega_safe_var_p (pb, i); i++)
2704 unprotect[i] = omega_wildcard_p (pb, i);
2706 for (e = pb->num_subs - 1; e >= 0; e--)
2707 if (pb->subs[e].coef[i])
2708 unprotect[i] = false;
2711 if (dump_file && (dump_flags & TDF_DETAILS))
2713 fprintf (dump_file, "Doing chain reaction unprotection\n");
2714 omega_print_problem (dump_file, pb);
2716 for (i = 1; omega_safe_var_p (pb, i); i++)
2718 fprintf (dump_file, "unprotecting %s\n",
2719 omega_variable_to_str (pb, i));
2722 for (i = 1; omega_safe_var_p (pb, i); i++)
2724 omega_unprotect_1 (pb, &i, unprotect);
2726 if (dump_file && (dump_flags & TDF_DETAILS))
2728 fprintf (dump_file, "After chain reactions\n");
2729 omega_print_problem (dump_file, pb);
2735 /* Reduce problem PB. */
2738 omega_problem_reduced (omega_pb pb)
2740 if (omega_verify_simplification
2741 && !in_approximate_mode
2742 && verify_omega_pb (pb) == omega_false)
2745 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2746 && !omega_eliminate_redundant (pb, true))
2749 omega_found_reduction = omega_true;
2751 if (!please_no_equalities_in_simplified_problems)
2754 if (omega_reduce_with_subs
2755 || please_no_equalities_in_simplified_problems)
2756 chain_unprotect (pb);
2758 resurrect_subs (pb);
2760 if (!return_single_result)
2764 for (i = 1; omega_safe_var_p (pb, i); i++)
2765 pb->forwarding_address[pb->var[i]] = i;
2767 for (i = 0; i < pb->num_subs; i++)
2768 pb->forwarding_address[pb->subs[i].key] = -i - 1;
2770 (*omega_when_reduced) (pb);
2773 if (dump_file && (dump_flags & TDF_DETAILS))
2775 fprintf (dump_file, "-------------------------------------------\n");
2776 fprintf (dump_file, "problem reduced:\n");
2777 omega_print_problem (dump_file, pb);
2778 fprintf (dump_file, "-------------------------------------------\n");
2782 /* Eliminates all the free variables for problem PB, that is all the
2783 variables from FV to PB->NUM_VARS. */
2786 omega_free_eliminations (omega_pb pb, int fv)
2788 bool try_again = true;
2790 int n_vars = pb->num_vars;
2796 for (i = n_vars; i > fv; i--)
2798 for (e = pb->num_geqs - 1; e >= 0; e--)
2799 if (pb->geqs[e].coef[i])
2804 else if (pb->geqs[e].coef[i] > 0)
2806 for (e2 = e - 1; e2 >= 0; e2--)
2807 if (pb->geqs[e2].coef[i] < 0)
2812 for (e2 = e - 1; e2 >= 0; e2--)
2813 if (pb->geqs[e2].coef[i] > 0)
2820 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2821 if (pb->subs[e3].coef[i])
2827 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2828 if (pb->eqs[e3].coef[i])
2834 if (dump_file && (dump_flags & TDF_DETAILS))
2835 fprintf (dump_file, "a free elimination of %s\n",
2836 omega_variable_to_str (pb, i));
2840 omega_delete_geq (pb, e, n_vars);
2842 for (e--; e >= 0; e--)
2843 if (pb->geqs[e].coef[i])
2844 omega_delete_geq (pb, e, n_vars);
2846 try_again = (i < n_vars);
2849 omega_delete_variable (pb, i);
2850 n_vars = pb->num_vars;
2855 if (dump_file && (dump_flags & TDF_DETAILS))
2857 fprintf (dump_file, "\nafter free eliminations:\n");
2858 omega_print_problem (dump_file, pb);
2859 fprintf (dump_file, "\n");
2863 /* Do free red eliminations. */
2866 free_red_eliminations (omega_pb pb)
2868 bool try_again = true;
2870 int n_vars = pb->num_vars;
2871 bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2872 bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2873 bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2875 for (i = n_vars; i > 0; i--)
2877 is_red_var[i] = false;
2878 is_dead_var[i] = false;
2881 for (e = pb->num_geqs - 1; e >= 0; e--)
2883 is_dead_geq[e] = false;
2885 if (pb->geqs[e].color == omega_red)
2886 for (i = n_vars; i > 0; i--)
2887 if (pb->geqs[e].coef[i] != 0)
2888 is_red_var[i] = true;
2894 for (i = n_vars; i > 0; i--)
2895 if (!is_red_var[i] && !is_dead_var[i])
2897 for (e = pb->num_geqs - 1; e >= 0; e--)
2898 if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2903 else if (pb->geqs[e].coef[i] > 0)
2905 for (e2 = e - 1; e2 >= 0; e2--)
2906 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2911 for (e2 = e - 1; e2 >= 0; e2--)
2912 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2919 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2920 if (pb->subs[e3].coef[i])
2926 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2927 if (pb->eqs[e3].coef[i])
2933 if (dump_file && (dump_flags & TDF_DETAILS))
2934 fprintf (dump_file, "a free red elimination of %s\n",
2935 omega_variable_to_str (pb, i));
2938 if (pb->geqs[e].coef[i])
2939 is_dead_geq[e] = true;
2942 is_dead_var[i] = true;
2947 for (e = pb->num_geqs - 1; e >= 0; e--)
2949 omega_delete_geq (pb, e, n_vars);
2951 for (i = n_vars; i > 0; i--)
2953 omega_delete_variable (pb, i);
2955 if (dump_file && (dump_flags & TDF_DETAILS))
2957 fprintf (dump_file, "\nafter free red eliminations:\n");
2958 omega_print_problem (dump_file, pb);
2959 fprintf (dump_file, "\n");
2967 /* For equation EQ of the form "0 = EQN", insert in PB two
2968 inequalities "0 <= EQN" and "0 <= -EQN". */
2971 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2975 if (dump_file && (dump_flags & TDF_DETAILS))
2976 fprintf (dump_file, "Converting Eq to Geqs\n");
2978 /* Insert "0 <= EQN". */
2979 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2980 pb->geqs[pb->num_geqs].touched = 1;
2983 /* Insert "0 <= -EQN". */
2984 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2985 pb->geqs[pb->num_geqs].touched = 1;
2987 for (i = 0; i <= pb->num_vars; i++)
2988 pb->geqs[pb->num_geqs].coef[i] *= -1;
2992 if (dump_file && (dump_flags & TDF_DETAILS))
2993 omega_print_problem (dump_file, pb);
2996 /* Eliminates variable I from PB. */
2999 omega_do_elimination (omega_pb pb, int e, int i)
3001 eqn sub = omega_alloc_eqns (0, 1);
3003 int n_vars = pb->num_vars;
3005 if (dump_file && (dump_flags & TDF_DETAILS))
3006 fprintf (dump_file, "eliminating variable %s\n",
3007 omega_variable_to_str (pb, i));
3009 omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
3012 if (c == 1 || c == -1)
3014 if (pb->eqs[e].color == omega_red)
3017 omega_substitute_red (pb, sub, i, c, &fB);
3019 omega_convert_eq_to_geqs (pb, e);
3021 omega_delete_variable (pb, i);
3025 omega_substitute (pb, sub, i, c);
3026 omega_delete_variable (pb, i);
3034 if (dump_file && (dump_flags & TDF_DETAILS))
3035 fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
3037 for (e = pb->num_eqs - 1; e >= 0; e--)
3038 if (pb->eqs[e].coef[i])
3040 eqn eqn = &(pb->eqs[e]);
3042 for (j = n_vars; j >= 0; j--)
3046 if (sub->color == omega_red)
3047 eqn->color = omega_red;
3048 for (j = n_vars; j >= 0; j--)
3049 eqn->coef[j] -= sub->coef[j] * k / c;
3052 for (e = pb->num_geqs - 1; e >= 0; e--)
3053 if (pb->geqs[e].coef[i])
3055 eqn eqn = &(pb->geqs[e]);
3058 if (sub->color == omega_red)
3059 eqn->color = omega_red;
3061 for (j = n_vars; j >= 0; j--)
3068 for (j = n_vars; j >= 0; j--)
3069 eqn->coef[j] -= sub->coef[j] * k / c;
3073 for (e = pb->num_subs - 1; e >= 0; e--)
3074 if (pb->subs[e].coef[i])
3076 eqn eqn = &(pb->subs[e]);
3079 gcc_assert (sub->color == omega_black);
3080 for (j = n_vars; j >= 0; j--)
3084 for (j = n_vars; j >= 0; j--)
3085 eqn->coef[j] -= sub->coef[j] * k / c;
3088 if (in_approximate_mode)
3089 omega_delete_variable (pb, i);
3091 omega_convert_eq_to_geqs (pb, e2);
3094 omega_free_eqns (sub, 1);
3097 /* Helper function for printing "sorry, no solution". */
3099 static inline enum omega_result
3100 omega_problem_has_no_solution (void)
3102 if (dump_file && (dump_flags & TDF_DETAILS))
3103 fprintf (dump_file, "\nequations have no solution \n");
3108 /* Helper function: solve equations in PB one at a time, following the
3109 DESIRED_RES result. */
3111 static enum omega_result
3112 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3119 if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3121 fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3122 desired_res, may_be_red);
3123 omega_print_problem (dump_file, pb);
3124 fprintf (dump_file, "\n");
3130 j = pb->num_eqs - 1;
3136 while (i <= j && pb->eqs[i].color == omega_red)
3139 while (i <= j && pb->eqs[j].color == omega_black)
3145 eq = omega_alloc_eqns (0, 1);
3146 omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3147 omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3148 omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3149 omega_free_eqns (eq, 1);
3155 /* Eliminate all EQ equations */
3156 for (e = pb->num_eqs - 1; e >= 0; e--)
3158 eqn eqn = &(pb->eqs[e]);
3161 if (dump_file && (dump_flags & TDF_DETAILS))
3162 fprintf (dump_file, "----\n");
3164 for (i = pb->num_vars; i > 0; i--)
3170 for (j = i - 1; j > 0; j--)
3174 /* i is the position of last nonzero coefficient,
3175 g is the coefficient of i,
3176 j is the position of next nonzero coefficient. */
3180 if (eqn->coef[0] % g != 0)
3181 return omega_problem_has_no_solution ();
3183 eqn->coef[0] = eqn->coef[0] / g;
3186 omega_do_elimination (pb, e, i);
3192 if (eqn->coef[0] != 0)
3193 return omega_problem_has_no_solution ();
3205 omega_do_elimination (pb, e, i);
3211 bool promotion_possible =
3212 (omega_safe_var_p (pb, j)
3213 && pb->safe_vars + 1 == i
3214 && !omega_eqn_is_red (eqn, desired_res)
3215 && !in_approximate_mode);
3217 if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3218 fprintf (dump_file, " Promotion possible\n");
3221 if (!omega_safe_var_p (pb, j))
3223 for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3224 g = gcd (abs (eqn->coef[j]), g);
3227 else if (!omega_safe_var_p (pb, i))
3232 for (; g != 1 && j > 0; j--)
3233 g = gcd (abs (eqn->coef[j]), g);
3237 if (eqn->coef[0] % g != 0)
3238 return omega_problem_has_no_solution ();
3240 for (j = 0; j <= pb->num_vars; j++)
3250 for (e2 = e - 1; e2 >= 0; e2--)
3251 if (pb->eqs[e2].coef[i])
3255 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3256 if (pb->geqs[e2].coef[i])
3260 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3261 if (pb->subs[e2].coef[i])
3266 bool change = false;
3268 if (dump_file && (dump_flags & TDF_DETAILS))
3270 fprintf (dump_file, "Ha! We own it! \n");
3271 omega_print_eq (dump_file, pb, eqn);
3272 fprintf (dump_file, " \n");
3278 for (j = i - 1; j >= 0; j--)
3280 int t = int_mod (eqn->coef[j], g);
3285 if (t != eqn->coef[j])
3294 if (dump_file && (dump_flags & TDF_DETAILS))
3295 fprintf (dump_file, "So what?\n");
3300 omega_name_wild_card (pb, i);
3302 if (dump_file && (dump_flags & TDF_DETAILS))
3304 omega_print_eq (dump_file, pb, eqn);
3305 fprintf (dump_file, " \n");
3314 if (promotion_possible)
3316 if (dump_file && (dump_flags & TDF_DETAILS))
3318 fprintf (dump_file, "promoting %s to safety\n",
3319 omega_variable_to_str (pb, i));
3320 omega_print_vars (dump_file, pb);
3325 if (!omega_wildcard_p (pb, i))
3326 omega_name_wild_card (pb, i);
3328 promotion_possible = false;
3333 if (g2 > 1 && !in_approximate_mode)
3335 if (pb->eqs[e].color == omega_red)
3337 if (dump_file && (dump_flags & TDF_DETAILS))
3338 fprintf (dump_file, "handling red equality\n");
3341 omega_do_elimination (pb, e, i);
3345 if (dump_file && (dump_flags & TDF_DETAILS))
3348 "adding equation to handle safe variable \n");
3349 omega_print_eq (dump_file, pb, eqn);
3350 fprintf (dump_file, "\n----\n");
3351 omega_print_problem (dump_file, pb);
3352 fprintf (dump_file, "\n----\n");
3353 fprintf (dump_file, "\n----\n");
3356 i = omega_add_new_wild_card (pb);
3358 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3359 omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3360 omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3362 for (j = pb->num_vars; j >= 0; j--)
3364 pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3366 if (2 * pb->eqs[e + 1].coef[j] >= g2)
3367 pb->eqs[e + 1].coef[j] -= g2;
3370 pb->eqs[e + 1].coef[i] = g2;
3373 if (dump_file && (dump_flags & TDF_DETAILS))
3374 omega_print_problem (dump_file, pb);
3383 /* Find variable to eliminate. */
3386 gcc_assert (in_approximate_mode);
3388 if (dump_file && (dump_flags & TDF_DETAILS))
3390 fprintf (dump_file, "non-exact elimination: ");
3391 omega_print_eq (dump_file, pb, eqn);
3392 fprintf (dump_file, "\n");
3393 omega_print_problem (dump_file, pb);
3396 for (i = pb->num_vars; i > sv; i--)
3397 if (pb->eqs[e].coef[i] != 0)
3401 for (i = pb->num_vars; i > sv; i--)
3402 if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3408 omega_do_elimination (pb, e, i);
3410 if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3412 fprintf (dump_file, "result of non-exact elimination:\n");
3413 omega_print_problem (dump_file, pb);
3418 int factor = (INT_MAX);
3421 if (dump_file && (dump_flags & TDF_DETAILS))
3422 fprintf (dump_file, "doing moding\n");
3424 for (i = pb->num_vars; i != sv; i--)
3425 if ((pb->eqs[e].coef[i] & 1) != 0)
3430 for (; i != sv; i--)
3431 if ((pb->eqs[e].coef[i] & 1) != 0)
3437 if (j != 0 && i == sv)
3439 omega_do_mod (pb, 2, e, j);
3445 for (i = pb->num_vars; i != sv; i--)
3446 if (pb->eqs[e].coef[i] != 0
3447 && factor > abs (pb->eqs[e].coef[i]) + 1)
3449 factor = abs (pb->eqs[e].coef[i]) + 1;
3455 if (dump_file && (dump_flags & TDF_DETAILS))
3456 fprintf (dump_file, "should not have happened\n");
3460 omega_do_mod (pb, factor, e, j);
3461 /* Go back and try this equation again. */
3468 return omega_unknown;
3471 /* Transform an inequation E to an equality, then solve DIFF problems
3472 based on PB, and only differing by the constant part that is
3473 diminished by one, trying to figure out which of the constants
3476 static enum omega_result
3477 parallel_splinter (omega_pb pb, int e, int diff,
3478 enum omega_result desired_res)
3480 omega_pb tmp_problem;
3483 if (dump_file && (dump_flags & TDF_DETAILS))
3485 fprintf (dump_file, "Using parallel splintering\n");
3486 omega_print_problem (dump_file, pb);
3489 tmp_problem = XNEW (struct omega_pb_d);
3490 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3493 for (i = 0; i <= diff; i++)
3495 omega_copy_problem (tmp_problem, pb);
3497 if (dump_file && (dump_flags & TDF_DETAILS))
3499 fprintf (dump_file, "Splinter # %i\n", i);
3500 omega_print_problem (dump_file, pb);
3503 if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3509 pb->eqs[0].coef[0]--;
3516 /* Helper function: solve equations one at a time. */
3518 static enum omega_result
3519 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3523 enum omega_result result;
3524 bool coupled_subscripts = false;
3525 bool smoothed = false;
3526 bool eliminate_again;
3527 bool tried_eliminating_redundant = false;
3529 if (desired_res != omega_simplify)
3537 gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3539 /* Verify that there are not too many inequalities. */
3540 gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3542 if (dump_file && (dump_flags & TDF_DETAILS))
3544 fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3545 desired_res, please_no_equalities_in_simplified_problems);
3546 omega_print_problem (dump_file, pb);
3547 fprintf (dump_file, "\n");
3550 n_vars = pb->num_vars;
3554 enum omega_eqn_color u_color = omega_black;
3555 enum omega_eqn_color l_color = omega_black;
3556 int upper_bound = pos_infinity;
3557 int lower_bound = neg_infinity;
3559 for (e = pb->num_geqs - 1; e >= 0; e--)
3561 int a = pb->geqs[e].coef[1];
3562 int c = pb->geqs[e].coef[0];
3564 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3568 return omega_problem_has_no_solution ();
3575 if (lower_bound < -c
3576 || (lower_bound == -c
3577 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3580 l_color = pb->geqs[e].color;
3586 c = int_div (c, -a);
3589 || (upper_bound == c
3590 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3593 u_color = pb->geqs[e].color;
3598 if (dump_file && (dump_flags & TDF_DETAILS))
3600 fprintf (dump_file, "upper bound = %d\n", upper_bound);
3601 fprintf (dump_file, "lower bound = %d\n", lower_bound);
3604 if (lower_bound > upper_bound)
3605 return omega_problem_has_no_solution ();
3607 if (desired_res == omega_simplify)
3610 if (pb->safe_vars == 1)
3613 if (lower_bound == upper_bound
3614 && u_color == omega_black
3615 && l_color == omega_black)
3617 pb->eqs[0].coef[0] = -lower_bound;
3618 pb->eqs[0].coef[1] = 1;
3619 pb->eqs[0].color = omega_black;
3621 return omega_solve_problem (pb, desired_res);
3625 if (lower_bound > neg_infinity)
3627 pb->geqs[0].coef[0] = -lower_bound;
3628 pb->geqs[0].coef[1] = 1;
3629 pb->geqs[0].key = 1;
3630 pb->geqs[0].color = l_color;
3631 pb->geqs[0].touched = 0;
3635 if (upper_bound < pos_infinity)
3637 pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3638 pb->geqs[pb->num_geqs].coef[1] = -1;
3639 pb->geqs[pb->num_geqs].key = -1;
3640 pb->geqs[pb->num_geqs].color = u_color;
3641 pb->geqs[pb->num_geqs].touched = 0;
3649 omega_problem_reduced (pb);
3653 if (original_problem != no_problem
3654 && l_color == omega_black
3655 && u_color == omega_black
3657 && lower_bound == upper_bound)
3659 pb->eqs[0].coef[0] = -lower_bound;
3660 pb->eqs[0].coef[1] = 1;
3662 adding_equality_constraint (pb, 0);
3668 if (!pb->variables_freed)
3670 pb->variables_freed = true;
3672 if (desired_res != omega_simplify)
3673 omega_free_eliminations (pb, 0);
3675 omega_free_eliminations (pb, pb->safe_vars);
3677 n_vars = pb->num_vars;
3683 switch (normalize_omega_problem (pb))
3685 case normalize_false:
3689 case normalize_coupled:
3690 coupled_subscripts = true;
3693 case normalize_uncoupled:
3694 coupled_subscripts = false;
3701 n_vars = pb->num_vars;
3703 if (dump_file && (dump_flags & TDF_DETAILS))
3705 fprintf (dump_file, "\nafter normalization:\n");
3706 omega_print_problem (dump_file, pb);
3707 fprintf (dump_file, "\n");
3708 fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3712 int parallel_difference = INT_MAX;
3713 int best_parallel_eqn = -1;
3714 int minC, maxC, minCj = 0;
3715 int lower_bound_count = 0;
3717 bool possible_easy_int_solution;
3718 int max_splinters = 1;
3720 bool lucky_exact = false;
3721 int best = (INT_MAX);
3722 int j = 0, jLe = 0, jLowerBoundCount = 0;
3725 eliminate_again = false;
3727 if (pb->num_eqs > 0)
3728 return omega_solve_problem (pb, desired_res);
3730 if (!coupled_subscripts)
3732 if (pb->safe_vars == 0)
3735 for (e = pb->num_geqs - 1; e >= 0; e--)
3736 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3737 omega_delete_geq (pb, e, n_vars);
3739 pb->num_vars = pb->safe_vars;
3741 if (desired_res == omega_simplify)
3743 omega_problem_reduced (pb);
3750 if (desired_res != omega_simplify)
3755 if (pb->num_geqs == 0)
3757 if (desired_res == omega_simplify)
3759 pb->num_vars = pb->safe_vars;
3760 omega_problem_reduced (pb);
3766 if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3768 omega_problem_reduced (pb);
3772 if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3773 || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3775 if (dump_file && (dump_flags & TDF_DETAILS))
3777 "TOO MANY EQUATIONS; "
3778 "%d equations, %d variables, "
3779 "ELIMINATING REDUNDANT ONES\n",
3780 pb->num_geqs, n_vars);
3782 if (!omega_eliminate_redundant (pb, false))
3785 n_vars = pb->num_vars;
3787 if (pb->num_eqs > 0)
3788 return omega_solve_problem (pb, desired_res);
3790 if (dump_file && (dump_flags & TDF_DETAILS))
3791 fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3794 if (desired_res != omega_simplify)
3799 for (i = n_vars; i != fv; i--)
3805 int upper_bound_count = 0;
3807 lower_bound_count = 0;
3810 for (e = pb->num_geqs - 1; e >= 0; e--)
3811 if (pb->geqs[e].coef[i] < 0)
3813 minC = MIN (minC, pb->geqs[e].coef[i]);
3814 upper_bound_count++;
3815 if (pb->geqs[e].coef[i] < -1)
3823 else if (pb->geqs[e].coef[i] > 0)
3825 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3826 lower_bound_count++;
3828 if (pb->geqs[e].coef[i] > 1)
3837 if (lower_bound_count == 0
3838 || upper_bound_count == 0)
3840 lower_bound_count = 0;
3844 if (ub >= 0 && lb >= 0
3845 && pb->geqs[lb].key == -pb->geqs[ub].key)
3847 int Lc = pb->geqs[lb].coef[i];
3848 int Uc = -pb->geqs[ub].coef[i];
3850 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3851 lucky = (diff >= (Uc - 1) * (Lc - 1));
3857 || in_approximate_mode)
3859 score = upper_bound_count * lower_bound_count;
3861 if (dump_file && (dump_flags & TDF_DETAILS))
3863 "For %s, exact, score = %d*%d, range = %d ... %d,"
3864 "\nlucky = %d, in_approximate_mode=%d \n",
3865 omega_variable_to_str (pb, i),
3867 lower_bound_count, minC, maxC, lucky,
3868 in_approximate_mode);
3878 jLowerBoundCount = lower_bound_count;
3880 lucky_exact = lucky;
3887 if (dump_file && (dump_flags & TDF_DETAILS))
3889 "For %s, non-exact, score = %d*%d,"
3890 "range = %d ... %d \n",
3891 omega_variable_to_str (pb, i),
3893 lower_bound_count, minC, maxC);
3895 score = maxC - minC;
3903 jLowerBoundCount = lower_bound_count;
3908 if (lower_bound_count == 0)
3910 omega_free_eliminations (pb, pb->safe_vars);
3911 n_vars = pb->num_vars;
3912 eliminate_again = true;
3919 lower_bound_count = jLowerBoundCount;
3921 for (e = pb->num_geqs - 1; e >= 0; e--)
3922 if (pb->geqs[e].coef[i] > 0)
3924 if (pb->geqs[e].coef[i] == -minC)
3925 max_splinters += -minC - 1;
3928 check_pos_mul ((pb->geqs[e].coef[i] - 1),
3929 (-minC - 1)) / (-minC) + 1;
3933 /* Trying to produce exact elimination by finding redundant
3935 if (!exact && !tried_eliminating_redundant)
3937 omega_eliminate_redundant (pb, false);
3938 tried_eliminating_redundant = true;
3939 eliminate_again = true;
3942 tried_eliminating_redundant = false;
3945 if (return_single_result && desired_res == omega_simplify && !exact)
3947 omega_problem_reduced (pb);
3951 /* #ifndef Omega3 */
3952 /* Trying to produce exact elimination by finding redundant
3954 if (!exact && !tried_eliminating_redundant)
3956 omega_eliminate_redundant (pb, false);
3957 tried_eliminating_redundant = true;
3960 tried_eliminating_redundant = false;
3967 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3968 if (pb->geqs[e1].color == omega_black)
3969 for (e2 = e1 - 1; e2 >= 0; e2--)
3970 if (pb->geqs[e2].color == omega_black
3971 && pb->geqs[e1].key == -pb->geqs[e2].key
3972 && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3973 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3974 / 2 < parallel_difference))
3976 parallel_difference =
3977 (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3978 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3980 best_parallel_eqn = e1;
3983 if (dump_file && (dump_flags & TDF_DETAILS)
3984 && best_parallel_eqn >= 0)
3987 "Possible parallel projection, diff = %d, in ",
3988 parallel_difference);
3989 omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3990 fprintf (dump_file, "\n");
3991 omega_print_problem (dump_file, pb);
3995 if (dump_file && (dump_flags & TDF_DETAILS))
3997 fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
3998 omega_variable_to_str (pb, i), i, minC,
4000 omega_print_problem (dump_file, pb);
4003 fprintf (dump_file, "(a lucky exact elimination)\n");
4006 fprintf (dump_file, "(an exact elimination)\n");
4008 fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
4011 gcc_assert (max_splinters >= 1);
4013 if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
4014 && parallel_difference <= max_splinters)
4015 return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
4023 int j = pb->num_vars;
4025 if (dump_file && (dump_flags & TDF_DETAILS))
4027 fprintf (dump_file, "Swapping %d and %d\n", i, j);
4028 omega_print_problem (dump_file, pb);
4031 swap (&pb->var[i], &pb->var[j]);
4033 for (e = pb->num_geqs - 1; e >= 0; e--)
4034 if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
4036 pb->geqs[e].touched = 1;
4037 t = pb->geqs[e].coef[i];
4038 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
4039 pb->geqs[e].coef[j] = t;
4042 for (e = pb->num_subs - 1; e >= 0; e--)
4043 if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
4045 t = pb->subs[e].coef[i];
4046 pb->subs[e].coef[i] = pb->subs[e].coef[j];
4047 pb->subs[e].coef[j] = t;
4050 if (dump_file && (dump_flags & TDF_DETAILS))
4052 fprintf (dump_file, "Swapping complete \n");
4053 omega_print_problem (dump_file, pb);
4054 fprintf (dump_file, "\n");
4060 else if (dump_file && (dump_flags & TDF_DETAILS))
4062 fprintf (dump_file, "No swap needed\n");
4063 omega_print_problem (dump_file, pb);
4067 n_vars = pb->num_vars;
4073 int upper_bound = pos_infinity;
4074 int lower_bound = neg_infinity;
4075 enum omega_eqn_color ub_color = omega_black;
4076 enum omega_eqn_color lb_color = omega_black;
4077 int topeqn = pb->num_geqs - 1;
4078 int Lc = pb->geqs[Le].coef[i];
4080 for (Le = topeqn; Le >= 0; Le--)
4081 if ((Lc = pb->geqs[Le].coef[i]) == 0)
4083 if (pb->geqs[Le].coef[1] == 1)
4085 int constantTerm = -pb->geqs[Le].coef[0];
4087 if (constantTerm > lower_bound ||
4088 (constantTerm == lower_bound &&
4089 !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
4091 lower_bound = constantTerm;
4092 lb_color = pb->geqs[Le].color;
4095 if (dump_file && (dump_flags & TDF_DETAILS))
4097 if (pb->geqs[Le].color == omega_black)
4098 fprintf (dump_file, " :::=> %s >= %d\n",
4099 omega_variable_to_str (pb, 1),
4103 " :::=> [%s >= %d]\n",
4104 omega_variable_to_str (pb, 1),
4110 int constantTerm = pb->geqs[Le].coef[0];
4111 if (constantTerm < upper_bound ||
4112 (constantTerm == upper_bound
4113 && !omega_eqn_is_red (&pb->geqs[Le],
4116 upper_bound = constantTerm;
4117 ub_color = pb->geqs[Le].color;
4120 if (dump_file && (dump_flags & TDF_DETAILS))
4122 if (pb->geqs[Le].color == omega_black)
4123 fprintf (dump_file, " :::=> %s <= %d\n",
4124 omega_variable_to_str (pb, 1),
4128 " :::=> [%s <= %d]\n",
4129 omega_variable_to_str (pb, 1),
4135 for (Ue = topeqn; Ue >= 0; Ue--)
4136 if (pb->geqs[Ue].coef[i] < 0
4137 && pb->geqs[Le].key != -pb->geqs[Ue].key)
4139 int Uc = -pb->geqs[Ue].coef[i];
4140 int coefficient = pb->geqs[Ue].coef[1] * Lc
4141 + pb->geqs[Le].coef[1] * Uc;
4142 int constantTerm = pb->geqs[Ue].coef[0] * Lc
4143 + pb->geqs[Le].coef[0] * Uc;
4145 if (dump_file && (dump_flags & TDF_DETAILS))
4147 omega_print_geq_extra (dump_file, pb,
4149 fprintf (dump_file, "\n");
4150 omega_print_geq_extra (dump_file, pb,
4152 fprintf (dump_file, "\n");
4155 if (coefficient > 0)
4157 constantTerm = -int_div (constantTerm, coefficient);
4159 if (constantTerm > lower_bound
4160 || (constantTerm == lower_bound
4161 && (desired_res != omega_simplify
4162 || (pb->geqs[Ue].color == omega_black
4163 && pb->geqs[Le].color == omega_black))))
4165 lower_bound = constantTerm;
4166 lb_color = (pb->geqs[Ue].color == omega_red
4167 || pb->geqs[Le].color == omega_red)
4168 ? omega_red : omega_black;
4171 if (dump_file && (dump_flags & TDF_DETAILS))
4173 if (pb->geqs[Ue].color == omega_red
4174 || pb->geqs[Le].color == omega_red)
4176 " ::=> [%s >= %d]\n",
4177 omega_variable_to_str (pb, 1),
4182 omega_variable_to_str (pb, 1),
4188 constantTerm = int_div (constantTerm, -coefficient);
4189 if (constantTerm < upper_bound
4190 || (constantTerm == upper_bound
4191 && pb->geqs[Ue].color == omega_black
4192 && pb->geqs[Le].color == omega_black))
4194 upper_bound = constantTerm;
4195 ub_color = (pb->geqs[Ue].color == omega_red
4196 || pb->geqs[Le].color == omega_red)
4197 ? omega_red : omega_black;
4201 && (dump_flags & TDF_DETAILS))
4203 if (pb->geqs[Ue].color == omega_red
4204 || pb->geqs[Le].color == omega_red)
4206 " ::=> [%s <= %d]\n",
4207 omega_variable_to_str (pb, 1),
4212 omega_variable_to_str (pb, 1),
4220 if (dump_file && (dump_flags & TDF_DETAILS))
4222 " therefore, %c%d <= %c%s%c <= %d%c\n",
4223 lb_color == omega_red ? '[' : ' ', lower_bound,
4224 (lb_color == omega_red && ub_color == omega_black)
4226 omega_variable_to_str (pb, 1),
4227 (lb_color == omega_black && ub_color == omega_red)
4229 upper_bound, ub_color == omega_red ? ']' : ' ');
4231 if (lower_bound > upper_bound)
4234 if (pb->safe_vars == 1)
4236 if (upper_bound == lower_bound
4237 && !(ub_color == omega_red || lb_color == omega_red)
4238 && !please_no_equalities_in_simplified_problems)
4241 pb->eqs[0].coef[1] = -1;
4242 pb->eqs[0].coef[0] = upper_bound;
4244 if (ub_color == omega_red
4245 || lb_color == omega_red)
4246 pb->eqs[0].color = omega_red;
4248 if (desired_res == omega_simplify
4249 && pb->eqs[0].color == omega_black)
4250 return omega_solve_problem (pb, desired_res);
4253 if (upper_bound != pos_infinity)
4255 pb->geqs[0].coef[1] = -1;
4256 pb->geqs[0].coef[0] = upper_bound;
4257 pb->geqs[0].color = ub_color;
4258 pb->geqs[0].key = -1;
4259 pb->geqs[0].touched = 0;
4263 if (lower_bound != neg_infinity)
4265 pb->geqs[pb->num_geqs].coef[1] = 1;
4266 pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
4267 pb->geqs[pb->num_geqs].color = lb_color;
4268 pb->geqs[pb->num_geqs].key = 1;
4269 pb->geqs[pb->num_geqs].touched = 0;
4274 if (desired_res == omega_simplify)
4276 omega_problem_reduced (pb);
4282 && (desired_res != omega_simplify
4283 || (lb_color == omega_black
4284 && ub_color == omega_black))
4285 && original_problem != no_problem
4286 && lower_bound == upper_bound)
4288 for (i = original_problem->num_vars; i >= 0; i--)
4289 if (original_problem->var[i] == pb->var[1])
4295 e = original_problem->num_eqs++;
4296 omega_init_eqn_zero (&original_problem->eqs[e],
4297 original_problem->num_vars);
4298 original_problem->eqs[e].coef[i] = -1;
4299 original_problem->eqs[e].coef[0] = upper_bound;
4301 if (dump_file && (dump_flags & TDF_DETAILS))
4304 "adding equality %d to outer problem\n", e);
4305 omega_print_problem (dump_file, original_problem);
4312 eliminate_again = true;
4314 if (lower_bound_count == 1)
4316 eqn lbeqn = omega_alloc_eqns (0, 1);
4317 int Lc = pb->geqs[Le].coef[i];
4319 if (dump_file && (dump_flags & TDF_DETAILS))
4320 fprintf (dump_file, "an inplace elimination\n");
4322 omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
4323 omega_delete_geq_extra (pb, Le, n_vars + 1);
4325 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4326 if (pb->geqs[Ue].coef[i] < 0)
4328 if (lbeqn->key == -pb->geqs[Ue].key)
4329 omega_delete_geq_extra (pb, Ue, n_vars + 1);
4333 int Uc = -pb->geqs[Ue].coef[i];
4334 pb->geqs[Ue].touched = 1;
4335 eliminate_again = false;
4337 if (lbeqn->color == omega_red)
4338 pb->geqs[Ue].color = omega_red;
4340 for (k = 0; k <= n_vars; k++)
4341 pb->geqs[Ue].coef[k] =
4342 check_mul (pb->geqs[Ue].coef[k], Lc) +
4343 check_mul (lbeqn->coef[k], Uc);
4345 if (dump_file && (dump_flags & TDF_DETAILS))
4347 omega_print_geq (dump_file, pb,
4349 fprintf (dump_file, "\n");
4354 omega_free_eqns (lbeqn, 1);
4359 int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
4360 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
4362 int top_eqn = pb->num_geqs - 1;
4363 lower_bound_count--;
4365 if (dump_file && (dump_flags & TDF_DETAILS))
4366 fprintf (dump_file, "lower bound count = %d\n",
4369 for (Le = top_eqn; Le >= 0; Le--)
4370 if (pb->geqs[Le].coef[i] > 0)
4372 int Lc = pb->geqs[Le].coef[i];
4373 for (Ue = top_eqn; Ue >= 0; Ue--)
4374 if (pb->geqs[Ue].coef[i] < 0)
4376 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4379 int Uc = -pb->geqs[Ue].coef[i];
4382 e2 = pb->num_geqs++;
4384 e2 = dead_eqns[--num_dead];
4386 gcc_assert (e2 < OMEGA_MAX_GEQS);
4388 if (dump_file && (dump_flags & TDF_DETAILS))
4391 "Le = %d, Ue = %d, gen = %d\n",
4393 omega_print_geq_extra (dump_file, pb,
4395 fprintf (dump_file, "\n");
4396 omega_print_geq_extra (dump_file, pb,
4398 fprintf (dump_file, "\n");
4401 eliminate_again = false;
4403 for (k = n_vars; k >= 0; k--)
4404 pb->geqs[e2].coef[k] =
4405 check_mul (pb->geqs[Ue].coef[k], Lc) +
4406 check_mul (pb->geqs[Le].coef[k], Uc);
4408 pb->geqs[e2].coef[n_vars + 1] = 0;
4409 pb->geqs[e2].touched = 1;
4411 if (pb->geqs[Ue].color == omega_red
4412 || pb->geqs[Le].color == omega_red)
4413 pb->geqs[e2].color = omega_red;
4415 pb->geqs[e2].color = omega_black;
4417 if (dump_file && (dump_flags & TDF_DETAILS))
4419 omega_print_geq (dump_file, pb,
4421 fprintf (dump_file, "\n");
4425 if (lower_bound_count == 0)
4427 dead_eqns[num_dead++] = Ue;
4429 if (dump_file && (dump_flags & TDF_DETAILS))
4430 fprintf (dump_file, "Killed %d\n", Ue);
4434 lower_bound_count--;
4435 dead_eqns[num_dead++] = Le;
4437 if (dump_file && (dump_flags & TDF_DETAILS))
4438 fprintf (dump_file, "Killed %d\n", Le);
4441 for (e = pb->num_geqs - 1; e >= 0; e--)
4444 while (num_dead > 0)
4445 is_dead[dead_eqns[--num_dead]] = true;
4447 for (e = pb->num_geqs - 1; e >= 0; e--)
4449 omega_delete_geq_extra (pb, e, n_vars + 1);
4460 rS = omega_alloc_problem (0, 0);
4461 iS = omega_alloc_problem (0, 0);
4463 possible_easy_int_solution = true;
4465 for (e = 0; e < pb->num_geqs; e++)
4466 if (pb->geqs[e].coef[i] == 0)
4468 omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
4470 omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
4473 if (dump_file && (dump_flags & TDF_DETAILS))
4476 fprintf (dump_file, "Copying (%d, %d): ", i,
4477 pb->geqs[e].coef[i]);
4478 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
4479 fprintf (dump_file, "\n");
4480 for (t = 0; t <= n_vars + 1; t++)
4481 fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
4482 fprintf (dump_file, "\n");
4486 gcc_assert (e2 < OMEGA_MAX_GEQS);
4489 for (Le = pb->num_geqs - 1; Le >= 0; Le--)
4490 if (pb->geqs[Le].coef[i] > 0)
4491 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4492 if (pb->geqs[Ue].coef[i] < 0)
4495 int Lc = pb->geqs[Le].coef[i];
4496 int Uc = -pb->geqs[Ue].coef[i];
4498 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4501 rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
4503 if (dump_file && (dump_flags & TDF_DETAILS))
4505 fprintf (dump_file, "---\n");
4507 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4508 Le, Lc, Ue, Uc, e2);
4509 omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
4510 fprintf (dump_file, "\n");
4511 omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
4512 fprintf (dump_file, "\n");
4517 for (k = n_vars; k >= 0; k--)
4518 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4519 pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
4521 iS->geqs[e2].coef[0] -= (Uc - 1);
4525 for (k = n_vars; k >= 0; k--)
4526 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4527 check_mul (pb->geqs[Ue].coef[k], Lc) +
4528 check_mul (pb->geqs[Le].coef[k], Uc);
4530 iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
4533 if (pb->geqs[Ue].color == omega_red
4534 || pb->geqs[Le].color == omega_red)
4535 iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
4537 iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
4539 if (dump_file && (dump_flags & TDF_DETAILS))
4541 omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
4542 fprintf (dump_file, "\n");
4546 gcc_assert (e2 < OMEGA_MAX_GEQS);
4548 else if (pb->geqs[Ue].coef[0] * Lc +
4549 pb->geqs[Le].coef[0] * Uc -
4550 (Uc - 1) * (Lc - 1) < 0)
4551 possible_easy_int_solution = false;
4554 iS->variables_initialized = rS->variables_initialized = true;
4555 iS->num_vars = rS->num_vars = pb->num_vars;
4556 iS->num_geqs = rS->num_geqs = e2;
4557 iS->num_eqs = rS->num_eqs = 0;
4558 iS->num_subs = rS->num_subs = pb->num_subs;
4559 iS->safe_vars = rS->safe_vars = pb->safe_vars;
4561 for (e = n_vars; e >= 0; e--)
4562 rS->var[e] = pb->var[e];
4564 for (e = n_vars; e >= 0; e--)
4565 iS->var[e] = pb->var[e];
4567 for (e = pb->num_subs - 1; e >= 0; e--)
4569 omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
4570 omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
4574 n_vars = pb->num_vars;
4576 if (desired_res != omega_true)
4578 if (original_problem == no_problem)
4580 original_problem = pb;
4581 result = omega_solve_geq (rS, omega_false);
4582 original_problem = no_problem;
4585 result = omega_solve_geq (rS, omega_false);
4587 if (result == omega_false)
4594 if (pb->num_eqs > 0)
4596 /* An equality constraint must have been found */
4599 return omega_solve_problem (pb, desired_res);
4603 if (desired_res != omega_false)
4606 int lower_bounds = 0;
4607 int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
4609 if (possible_easy_int_solution)
4612 result = omega_solve_geq (iS, desired_res);
4615 if (result != omega_false)
4624 if (!exact && best_parallel_eqn >= 0
4625 && parallel_difference <= max_splinters)
4630 return parallel_splinter (pb, best_parallel_eqn,
4631 parallel_difference,
4635 if (dump_file && (dump_flags & TDF_DETAILS))
4636 fprintf (dump_file, "have to do exact analysis\n");
4640 for (e = 0; e < pb->num_geqs; e++)
4641 if (pb->geqs[e].coef[i] > 1)
4642 lower_bound[lower_bounds++] = e;
4644 /* Sort array LOWER_BOUND. */
4645 for (j = 0; j < lower_bounds; j++)
4647 int k, smallest = j;
4649 for (k = j + 1; k < lower_bounds; k++)
4650 if (pb->geqs[lower_bound[smallest]].coef[i] >
4651 pb->geqs[lower_bound[k]].coef[i])
4654 k = lower_bound[smallest];
4655 lower_bound[smallest] = lower_bound[j];
4659 if (dump_file && (dump_flags & TDF_DETAILS))
4661 fprintf (dump_file, "lower bound coefficients = ");
4663 for (j = 0; j < lower_bounds; j++)
4664 fprintf (dump_file, " %d",
4665 pb->geqs[lower_bound[j]].coef[i]);
4667 fprintf (dump_file, "\n");
4670 for (j = 0; j < lower_bounds; j++)
4674 int worst_lower_bound_constant = -minC;
4677 max_incr = (((pb->geqs[e].coef[i] - 1) *
4678 (worst_lower_bound_constant - 1) - 1)
4679 / worst_lower_bound_constant);
4680 /* max_incr += 2; */
4682 if (dump_file && (dump_flags & TDF_DETAILS))
4684 fprintf (dump_file, "for equation ");
4685 omega_print_geq (dump_file, pb, &pb->geqs[e]);
4687 "\ntry decrements from 0 to %d\n",
4689 omega_print_problem (dump_file, pb);
4692 if (max_incr > 50 && !smoothed
4693 && smooth_weird_equations (pb))
4699 goto solve_geq_start;
4702 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4704 pb->eqs[0].color = omega_black;
4705 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4706 pb->geqs[e].touched = 1;
4709 for (c = max_incr; c >= 0; c--)
4711 if (dump_file && (dump_flags & TDF_DETAILS))
4714 "trying next decrement of %d\n",
4716 omega_print_problem (dump_file, pb);
4719 omega_copy_problem (rS, pb);
4721 if (dump_file && (dump_flags & TDF_DETAILS))
4722 omega_print_problem (dump_file, rS);
4724 result = omega_solve_problem (rS, desired_res);
4726 if (result == omega_true)
4735 pb->eqs[0].coef[0]--;
4738 if (j + 1 < lower_bounds)
4741 omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4743 pb->geqs[e].touched = 1;
4744 pb->geqs[e].color = omega_black;
4745 omega_copy_problem (rS, pb);
4747 if (dump_file && (dump_flags & TDF_DETAILS))
4749 "exhausted lower bound, "
4750 "checking if still feasible ");
4752 result = omega_solve_problem (rS, omega_false);
4754 if (result == omega_false)
4759 if (dump_file && (dump_flags & TDF_DETAILS))
4760 fprintf (dump_file, "fall-off the end\n");
4772 return omega_unknown;
4773 } while (eliminate_again);
4777 /* Because the omega solver is recursive, this counter limits the
4779 static int omega_solve_depth = 0;
4781 /* Return omega_true when the problem PB has a solution following the
4785 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4787 enum omega_result result;
4789 gcc_assert (pb->num_vars >= pb->safe_vars);
4790 omega_solve_depth++;
4792 if (desired_res != omega_simplify)
4795 if (omega_solve_depth > 50)
4797 if (dump_file && (dump_flags & TDF_DETAILS))
4800 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4801 omega_solve_depth, in_approximate_mode);
4802 omega_print_problem (dump_file, pb);
4807 if (omega_solve_eq (pb, desired_res) == omega_false)
4809 omega_solve_depth--;
4813 if (in_approximate_mode && !pb->num_geqs)
4815 result = omega_true;
4816 pb->num_vars = pb->safe_vars;
4817 omega_problem_reduced (pb);
4820 result = omega_solve_geq (pb, desired_res);
4822 omega_solve_depth--;
4824 if (!omega_reduce_with_subs)
4826 resurrect_subs (pb);
4827 gcc_assert (please_no_equalities_in_simplified_problems
4828 || !result || pb->num_subs == 0);
4834 /* Return true if red equations constrain the set of possible solutions.
4835 We assume that there are solutions to the black equations by
4836 themselves, so if there is no solution to the combined problem, we
4840 omega_problem_has_red_equations (omega_pb pb)
4846 if (dump_file && (dump_flags & TDF_DETAILS))
4848 fprintf (dump_file, "Checking for red equations:\n");
4849 omega_print_problem (dump_file, pb);
4852 please_no_equalities_in_simplified_problems++;
4855 if (omega_single_result)
4856 return_single_result++;
4858 create_color = true;
4859 result = (omega_simplify_problem (pb) == omega_false);
4861 if (omega_single_result)
4862 return_single_result--;
4865 please_no_equalities_in_simplified_problems--;
4869 if (dump_file && (dump_flags & TDF_DETAILS))
4870 fprintf (dump_file, "Gist is FALSE\n");
4875 pb->eqs[0].color = omega_red;
4877 for (i = pb->num_vars; i > 0; i--)
4878 pb->eqs[0].coef[i] = 0;
4880 pb->eqs[0].coef[0] = 1;
4884 free_red_eliminations (pb);
4885 gcc_assert (pb->num_eqs == 0);
4887 for (e = pb->num_geqs - 1; e >= 0; e--)
4888 if (pb->geqs[e].color == omega_red)
4894 for (i = pb->safe_vars; i >= 1; i--)
4899 for (e = pb->num_geqs - 1; e >= 0; e--)
4901 if (pb->geqs[e].coef[i])
4903 if (pb->geqs[e].coef[i] > 0)
4904 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4907 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4911 if (ub == 2 || lb == 2)
4914 if (dump_file && (dump_flags & TDF_DETAILS))
4915 fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4917 if (!omega_reduce_with_subs)
4919 resurrect_subs (pb);
4920 gcc_assert (pb->num_subs == 0);
4928 if (dump_file && (dump_flags & TDF_DETAILS))
4930 "*** Doing potentially expensive elimination tests "
4931 "for red equations\n");
4933 please_no_equalities_in_simplified_problems++;
4934 omega_eliminate_red (pb, true);
4935 please_no_equalities_in_simplified_problems--;
4938 gcc_assert (pb->num_eqs == 0);
4940 for (e = pb->num_geqs - 1; e >= 0; e--)
4941 if (pb->geqs[e].color == omega_red)
4944 if (dump_file && (dump_flags & TDF_DETAILS))
4948 "******************** Redundant Red Equations eliminated!!\n");
4951 "******************** Red Equations remain\n");
4953 omega_print_problem (dump_file, pb);
4956 if (!omega_reduce_with_subs)
4958 normalize_return_type r;
4960 resurrect_subs (pb);
4961 r = normalize_omega_problem (pb);
4962 gcc_assert (r != normalize_false);
4965 cleanout_wildcards (pb);
4966 gcc_assert (pb->num_subs == 0);
4972 /* Calls omega_simplify_problem in approximate mode. */
4975 omega_simplify_approximate (omega_pb pb)
4977 enum omega_result result;
4979 if (dump_file && (dump_flags & TDF_DETAILS))
4980 fprintf (dump_file, "(Entering approximate mode\n");
4982 in_approximate_mode = true;
4983 result = omega_simplify_problem (pb);
4984 in_approximate_mode = false;
4986 gcc_assert (pb->num_vars == pb->safe_vars);
4987 if (!omega_reduce_with_subs)
4988 gcc_assert (pb->num_subs == 0);
4990 if (dump_file && (dump_flags & TDF_DETAILS))
4991 fprintf (dump_file, "Leaving approximate mode)\n");
4997 /* Simplifies problem PB by eliminating redundant constraints and
4998 reducing the constraints system to a minimal form. Returns
4999 omega_true when the problem was successfully reduced, omega_unknown
5000 when the solver is unable to determine an answer. */
5003 omega_simplify_problem (omega_pb pb)
5007 omega_found_reduction = omega_false;
5009 if (!pb->variables_initialized)
5010 omega_initialize_variables (pb);
5012 if (next_key * 3 > MAX_KEYS)
5017 next_key = OMEGA_MAX_VARS + 1;
5019 for (e = pb->num_geqs - 1; e >= 0; e--)
5020 pb->geqs[e].touched = 1;
5022 for (i = 0; i < HASH_TABLE_SIZE; i++)
5023 hash_master[i].touched = -1;
5025 pb->hash_version = hash_version;
5028 else if (pb->hash_version != hash_version)
5032 for (e = pb->num_geqs - 1; e >= 0; e--)
5033 pb->geqs[e].touched = 1;
5035 pb->hash_version = hash_version;
5038 if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
5039 omega_free_eliminations (pb, pb->safe_vars);
5041 if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
5043 omega_found_reduction = omega_solve_problem (pb, omega_unknown);
5045 if (omega_found_reduction != omega_false
5046 && !return_single_result)
5050 (*omega_when_reduced) (pb);
5053 return omega_found_reduction;
5056 omega_solve_problem (pb, omega_simplify);
5058 if (omega_found_reduction != omega_false)
5060 for (i = 1; omega_safe_var_p (pb, i); i++)
5061 pb->forwarding_address[pb->var[i]] = i;
5063 for (i = 0; i < pb->num_subs; i++)
5064 pb->forwarding_address[pb->subs[i].key] = -i - 1;
5067 if (!omega_reduce_with_subs)
5068 gcc_assert (please_no_equalities_in_simplified_problems
5069 || omega_found_reduction == omega_false
5070 || pb->num_subs == 0);
5072 return omega_found_reduction;
5075 /* Make variable VAR unprotected: it then can be eliminated. */
5078 omega_unprotect_variable (omega_pb pb, int var)
5081 idx = pb->forwarding_address[var];
5088 if (idx < pb->num_subs)
5090 omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5092 pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5097 int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5100 for (e = pb->num_subs - 1; e >= 0; e--)
5101 bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5103 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5104 if (bring_to_life[e2])
5109 if (pb->safe_vars < pb->num_vars)
5111 for (e = pb->num_geqs - 1; e >= 0; e--)
5113 pb->geqs[e].coef[pb->num_vars] =
5114 pb->geqs[e].coef[pb->safe_vars];
5116 pb->geqs[e].coef[pb->safe_vars] = 0;
5119 for (e = pb->num_eqs - 1; e >= 0; e--)
5121 pb->eqs[e].coef[pb->num_vars] =
5122 pb->eqs[e].coef[pb->safe_vars];
5124 pb->eqs[e].coef[pb->safe_vars] = 0;
5127 for (e = pb->num_subs - 1; e >= 0; e--)
5129 pb->subs[e].coef[pb->num_vars] =
5130 pb->subs[e].coef[pb->safe_vars];
5132 pb->subs[e].coef[pb->safe_vars] = 0;
5135 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5136 pb->forwarding_address[pb->var[pb->num_vars]] =
5141 for (e = pb->num_geqs - 1; e >= 0; e--)
5142 pb->geqs[e].coef[pb->safe_vars] = 0;
5144 for (e = pb->num_eqs - 1; e >= 0; e--)
5145 pb->eqs[e].coef[pb->safe_vars] = 0;
5147 for (e = pb->num_subs - 1; e >= 0; e--)
5148 pb->subs[e].coef[pb->safe_vars] = 0;
5151 pb->var[pb->safe_vars] = pb->subs[e2].key;
5152 pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5154 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5156 pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5157 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5159 if (e2 < pb->num_subs - 1)
5160 omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5166 omega_unprotect_1 (pb, &idx, NULL);
5167 free (bring_to_life);
5170 chain_unprotect (pb);
5173 /* Unprotects VAR and simplifies PB. */
5176 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5179 int n_vars = pb->num_vars;
5181 int k = pb->forwarding_address[var];
5190 omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5192 for (j = 0; j <= n_vars; j++)
5193 pb->geqs[e].coef[j] *= sign;
5195 pb->geqs[e].coef[0]--;
5196 pb->geqs[e].touched = 1;
5197 pb->geqs[e].color = color;
5202 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5203 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5204 pb->eqs[e].color = color;
5210 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5211 pb->geqs[e].coef[k] = sign;
5212 pb->geqs[e].coef[0] = -1;
5213 pb->geqs[e].touched = 1;
5214 pb->geqs[e].color = color;
5219 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5220 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5221 pb->eqs[e].coef[k] = 1;
5222 pb->eqs[e].color = color;
5225 omega_unprotect_variable (pb, var);
5226 return omega_simplify_problem (pb);
5229 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5232 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5236 int k = pb->forwarding_address[var];
5242 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5243 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5244 pb->eqs[e].coef[0] -= value;
5249 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5250 pb->eqs[e].coef[k] = 1;
5251 pb->eqs[e].coef[0] = -value;
5254 pb->eqs[e].color = color;
5257 /* Return false when the upper and lower bounds are not coupled.
5258 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5262 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5264 int n_vars = pb->num_vars;
5267 bool coupled = false;
5269 *lower_bound = neg_infinity;
5270 *upper_bound = pos_infinity;
5271 i = pb->forwarding_address[i];
5277 for (j = 1; j <= n_vars; j++)
5278 if (pb->subs[i].coef[j] != 0)
5281 *upper_bound = *lower_bound = pb->subs[i].coef[0];
5285 for (e = pb->num_subs - 1; e >= 0; e--)
5286 if (pb->subs[e].coef[i] != 0)
5289 for (e = pb->num_eqs - 1; e >= 0; e--)
5290 if (pb->eqs[e].coef[i] != 0)
5294 for (j = 1; j <= n_vars; j++)
5295 if (i != j && pb->eqs[e].coef[j] != 0)
5306 *lower_bound = *upper_bound =
5307 -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5312 for (e = pb->num_geqs - 1; e >= 0; e--)
5313 if (pb->geqs[e].coef[i] != 0)
5315 if (pb->geqs[e].key == i)
5316 *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5318 else if (pb->geqs[e].key == -i)
5319 *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5328 /* Sets the lower bound L and upper bound U for the values of variable
5329 I, and sets COULD_BE_ZERO to true if variable I might take value
5330 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5334 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5335 bool *could_be_zero, int lower_bound, int upper_bound)
5342 /* Preconditions. */
5343 gcc_assert (abs (pb->forwarding_address[i]) == 1
5344 && pb->num_vars + pb->num_subs == 2
5345 && pb->num_eqs + pb->num_subs == 1);
5347 /* Define variable I in terms of variable V. */
5348 if (pb->forwarding_address[i] == -1)
5357 sign = -eqn->coef[1];
5361 for (e = pb->num_geqs - 1; e >= 0; e--)
5362 if (pb->geqs[e].coef[v] != 0)
5364 if (pb->geqs[e].coef[v] == 1)
5365 lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5368 upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5371 if (lower_bound > upper_bound)
5379 if (lower_bound == neg_infinity)
5381 if (eqn->coef[v] > 0)
5382 b1 = sign * neg_infinity;
5385 b1 = -sign * neg_infinity;
5388 b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5390 if (upper_bound == pos_infinity)
5392 if (eqn->coef[v] > 0)
5393 b2 = sign * pos_infinity;
5396 b2 = -sign * pos_infinity;
5399 b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5401 *l = MAX (*l, b1 <= b2 ? b1 : b2);
5402 *u = MIN (*u, b1 <= b2 ? b2 : b1);
5404 *could_be_zero = (*l <= 0 && 0 <= *u
5405 && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5408 /* Return false when a lower bound L and an upper bound U for variable
5409 I in problem PB have been initialized. */
5412 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5417 if (!omega_query_variable (pb, i, l, u)
5418 || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5421 if (abs (pb->forwarding_address[i]) == 1
5422 && pb->num_vars + pb->num_subs == 2
5423 && pb->num_eqs + pb->num_subs == 1)
5426 query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5434 /* For problem PB, return an integer that represents the classic data
5435 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5436 masks that are added to the result. When DIST_KNOWN is true, DIST
5437 is set to the classic data dependence distance. LOWER_BOUND and
5438 UPPER_BOUND are bounds on the value of variable I, for example, it
5439 is possible to narrow the iteration domain with safe approximations
5440 of loop counts, and thus discard some data dependences that cannot
5444 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5445 int dd_eq, int dd_gt, int lower_bound,
5446 int upper_bound, bool *dist_known, int *dist)
5455 omega_query_variable (pb, i, &l, &u);
5456 query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5475 *dist_known = false;
5480 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5481 safe variables. Safe variables are not eliminated during the
5482 Fourier-Motzkin elimination. Safe variables are all those
5483 variables that are placed at the beginning of the array of
5484 variables: P->var[0, ..., NPROT - 1]. */
5487 omega_alloc_problem (int nvars, int nprot)
5491 gcc_assert (nvars <= OMEGA_MAX_VARS);
5492 omega_initialize ();
5494 /* Allocate and initialize PB. */
5495 pb = XCNEW (struct omega_pb_d);
5496 pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5497 pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5498 pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5499 pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5500 pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5502 pb->hash_version = hash_version;
5503 pb->num_vars = nvars;
5504 pb->safe_vars = nprot;
5505 pb->variables_initialized = false;
5506 pb->variables_freed = false;
5513 /* Keeps the state of the initialization. */
5514 static bool omega_initialized = false;
5516 /* Initialization of the Omega solver. */
5519 omega_initialize (void)
5523 if (omega_initialized)
5527 next_key = OMEGA_MAX_VARS + 1;
5528 packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5529 fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5530 fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5531 hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5533 for (i = 0; i < HASH_TABLE_SIZE; i++)
5534 hash_master[i].touched = -1;
5536 sprintf (wild_name[0], "1");
5537 sprintf (wild_name[1], "a");
5538 sprintf (wild_name[2], "b");
5539 sprintf (wild_name[3], "c");
5540 sprintf (wild_name[4], "d");
5541 sprintf (wild_name[5], "e");
5542 sprintf (wild_name[6], "f");
5543 sprintf (wild_name[7], "g");
5544 sprintf (wild_name[8], "h");
5545 sprintf (wild_name[9], "i");
5546 sprintf (wild_name[10], "j");
5547 sprintf (wild_name[11], "k");
5548 sprintf (wild_name[12], "l");
5549 sprintf (wild_name[13], "m");
5550 sprintf (wild_name[14], "n");
5551 sprintf (wild_name[15], "o");
5552 sprintf (wild_name[16], "p");
5553 sprintf (wild_name[17], "q");
5554 sprintf (wild_name[18], "r");
5555 sprintf (wild_name[19], "s");
5556 sprintf (wild_name[20], "t");
5557 sprintf (wild_name[40 - 1], "alpha");
5558 sprintf (wild_name[40 - 2], "beta");
5559 sprintf (wild_name[40 - 3], "gamma");
5560 sprintf (wild_name[40 - 4], "delta");
5561 sprintf (wild_name[40 - 5], "tau");
5562 sprintf (wild_name[40 - 6], "sigma");
5563 sprintf (wild_name[40 - 7], "chi");
5564 sprintf (wild_name[40 - 8], "omega");
5565 sprintf (wild_name[40 - 9], "pi");
5566 sprintf (wild_name[40 - 10], "ni");
5567 sprintf (wild_name[40 - 11], "Alpha");
5568 sprintf (wild_name[40 - 12], "Beta");
5569 sprintf (wild_name[40 - 13], "Gamma");
5570 sprintf (wild_name[40 - 14], "Delta");
5571 sprintf (wild_name[40 - 15], "Tau");
5572 sprintf (wild_name[40 - 16], "Sigma");
5573 sprintf (wild_name[40 - 17], "Chi");
5574 sprintf (wild_name[40 - 18], "Omega");
5575 sprintf (wild_name[40 - 19], "xxx");
5577 omega_initialized = true;