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-2013 Free Software Foundation, Inc.
9 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
11 This file is part of GCC.
13 GCC is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free
15 Software Foundation; either version 3, or (at your option) any later
18 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
19 WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 You should have received a copy of the GNU General Public License
24 along with GCC; see the file COPYING3. If not see
25 <http://www.gnu.org/licenses/>. */
27 /* For a detailed description, see "Constraint-Based Array Dependence
28 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
30 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
35 #include "coretypes.h"
37 #include "diagnostic-core.h"
41 /* When set to true, keep substitution variables. When set to false,
42 resurrect substitution variables (convert substitutions back to EQs). */
43 static bool omega_reduce_with_subs = true;
45 /* When set to true, omega_simplify_problem checks for problem with no
46 solutions, calling verify_omega_pb. */
47 static bool omega_verify_simplification = false;
49 /* When set to true, only produce a single simplified result. */
50 static bool omega_single_result = false;
52 /* Set return_single_result to 1 when omega_single_result is true. */
53 static int return_single_result = 0;
55 /* Hash table for equations generated by the solver. */
56 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
57 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
58 static eqn hash_master;
60 static int hash_version = 0;
62 /* Set to true for making the solver enter in approximation mode. */
63 static bool in_approximate_mode = false;
65 /* When set to zero, the solver is allowed to add new equalities to
66 the problem to be solved. */
67 static int conservative = 0;
69 /* Set to omega_true when the problem was successfully reduced, set to
70 omega_unknown when the solver is unable to determine an answer. */
71 static enum omega_result omega_found_reduction;
73 /* Set to true when the solver is allowed to add omega_red equations. */
74 static bool create_color = false;
76 /* Set to nonzero when the problem to be solved can be reduced. */
77 static int may_be_red = 0;
79 /* When false, there should be no substitution equations in the
80 simplified problem. */
81 static int please_no_equalities_in_simplified_problems = 0;
83 /* Variables names for pretty printing. */
84 static char wild_name[200][40];
86 /* Pointer to the void problem. */
87 static omega_pb no_problem = (omega_pb) 0;
89 /* Pointer to the problem to be solved. */
90 static omega_pb original_problem = (omega_pb) 0;
93 /* Return the integer A divided by B. */
96 int_div (int a, int b)
101 return -((-a + b - 1)/b);
104 /* Return the integer A modulo B. */
107 int_mod (int a, int b)
109 return a - b * int_div (a, b);
112 /* Test whether equation E is red. */
115 omega_eqn_is_red (eqn e, int desired_res)
117 return (desired_res == omega_simplify && e->color == omega_red);
120 /* Return a string for VARIABLE. */
123 omega_var_to_str (int variable)
125 if (0 <= variable && variable <= 20)
126 return wild_name[variable];
128 if (-20 < variable && variable < 0)
129 return wild_name[40 + variable];
131 /* Collapse all the entries that would have overflowed. */
132 return wild_name[21];
135 /* Return a string for variable I in problem PB. */
138 omega_variable_to_str (omega_pb pb, int i)
140 return omega_var_to_str (pb->var[i]);
143 /* Do nothing function: used for default initializations. */
146 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
150 void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
152 /* Print to FILE from PB equation E with all its coefficients
156 omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
160 int n = pb->num_vars;
163 for (i = 1; i <= n; i++)
164 if (c * e->coef[i] > 0)
169 if (c * e->coef[i] == 1)
170 fprintf (file, "%s", omega_variable_to_str (pb, i));
172 fprintf (file, "%d * %s", c * e->coef[i],
173 omega_variable_to_str (pb, i));
177 for (i = 1; i <= n; i++)
178 if (i != went_first && c * e->coef[i] != 0)
180 if (!first && c * e->coef[i] > 0)
181 fprintf (file, " + ");
185 if (c * e->coef[i] == 1)
186 fprintf (file, "%s", omega_variable_to_str (pb, i));
187 else if (c * e->coef[i] == -1)
188 fprintf (file, " - %s", omega_variable_to_str (pb, i));
190 fprintf (file, "%d * %s", c * e->coef[i],
191 omega_variable_to_str (pb, i));
194 if (!first && c * e->coef[0] > 0)
195 fprintf (file, " + ");
197 if (first || c * e->coef[0] != 0)
198 fprintf (file, "%d", c * e->coef[0]);
201 /* Print to FILE the equation E of problem PB. */
204 omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
207 int n = pb->num_vars + extra;
208 bool is_lt = test && e->coef[0] == -1;
216 else if (e->key != 0)
217 fprintf (file, "%d: ", e->key);
220 if (e->color == omega_red)
225 for (i = is_lt ? 1 : 0; i <= n; i++)
229 fprintf (file, " + ");
234 fprintf (file, "%d", -e->coef[i]);
235 else if (e->coef[i] == -1)
236 fprintf (file, "%s", omega_variable_to_str (pb, i));
238 fprintf (file, "%d * %s", -e->coef[i],
239 omega_variable_to_str (pb, i));
254 fprintf (file, " = ");
256 fprintf (file, " < ");
258 fprintf (file, " <= ");
262 for (i = 0; i <= n; i++)
266 fprintf (file, " + ");
271 fprintf (file, "%d", e->coef[i]);
272 else if (e->coef[i] == 1)
273 fprintf (file, "%s", omega_variable_to_str (pb, i));
275 fprintf (file, "%d * %s", e->coef[i],
276 omega_variable_to_str (pb, i));
282 if (e->color == omega_red)
286 /* Print to FILE all the variables of problem PB. */
289 omega_print_vars (FILE *file, omega_pb pb)
293 fprintf (file, "variables = ");
295 if (pb->safe_vars > 0)
296 fprintf (file, "protected (");
298 for (i = 1; i <= pb->num_vars; i++)
300 fprintf (file, "%s", omega_variable_to_str (pb, i));
302 if (i == pb->safe_vars)
305 if (i < pb->num_vars)
306 fprintf (file, ", ");
309 fprintf (file, "\n");
312 /* Debug problem PB. */
315 debug_omega_problem (omega_pb pb)
317 omega_print_problem (stderr, pb);
320 /* Print to FILE problem PB. */
323 omega_print_problem (FILE *file, omega_pb pb)
327 if (!pb->variables_initialized)
328 omega_initialize_variables (pb);
330 omega_print_vars (file, pb);
332 for (e = 0; e < pb->num_eqs; e++)
334 omega_print_eq (file, pb, &pb->eqs[e]);
335 fprintf (file, "\n");
338 fprintf (file, "Done with EQ\n");
340 for (e = 0; e < pb->num_geqs; e++)
342 omega_print_geq (file, pb, &pb->geqs[e]);
343 fprintf (file, "\n");
346 fprintf (file, "Done with GEQ\n");
348 for (e = 0; e < pb->num_subs; e++)
350 eqn eq = &pb->subs[e];
352 if (eq->color == omega_red)
356 fprintf (file, "%s := ", omega_var_to_str (eq->key));
358 fprintf (file, "#%d := ", eq->key);
360 omega_print_term (file, pb, eq, 1);
362 if (eq->color == omega_red)
365 fprintf (file, "\n");
369 /* Return the number of equations in PB tagged omega_red. */
372 omega_count_red_equations (omega_pb pb)
377 for (e = 0; e < pb->num_eqs; e++)
378 if (pb->eqs[e].color == omega_red)
380 for (i = pb->num_vars; i > 0; i--)
381 if (pb->geqs[e].coef[i])
384 if (i == 0 && pb->geqs[e].coef[0] == 1)
390 for (e = 0; e < pb->num_geqs; e++)
391 if (pb->geqs[e].color == omega_red)
394 for (e = 0; e < pb->num_subs; e++)
395 if (pb->subs[e].color == omega_red)
401 /* Print to FILE all the equations in PB that are tagged omega_red. */
404 omega_print_red_equations (FILE *file, omega_pb pb)
408 if (!pb->variables_initialized)
409 omega_initialize_variables (pb);
411 omega_print_vars (file, pb);
413 for (e = 0; e < pb->num_eqs; e++)
414 if (pb->eqs[e].color == omega_red)
416 omega_print_eq (file, pb, &pb->eqs[e]);
417 fprintf (file, "\n");
420 for (e = 0; e < pb->num_geqs; e++)
421 if (pb->geqs[e].color == omega_red)
423 omega_print_geq (file, pb, &pb->geqs[e]);
424 fprintf (file, "\n");
427 for (e = 0; e < pb->num_subs; e++)
428 if (pb->subs[e].color == omega_red)
430 eqn eq = &pb->subs[e];
434 fprintf (file, "%s := ", omega_var_to_str (eq->key));
436 fprintf (file, "#%d := ", eq->key);
438 omega_print_term (file, pb, eq, 1);
439 fprintf (file, "]\n");
443 /* Pretty print PB to FILE. */
446 omega_pretty_print_problem (FILE *file, omega_pb pb)
448 int e, v, v1, v2, v3, t;
449 bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
450 int stuffPrinted = 0;
455 } partial_order_type;
457 partial_order_type **po = XNEWVEC (partial_order_type *,
458 OMEGA_MAX_VARS * OMEGA_MAX_VARS);
459 int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
460 int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
461 int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
462 int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
463 int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
467 if (!pb->variables_initialized)
468 omega_initialize_variables (pb);
470 if (pb->num_vars > 0)
472 omega_eliminate_redundant (pb, false);
474 for (e = 0; e < pb->num_eqs; e++)
477 fprintf (file, "; ");
480 omega_print_eq (file, pb, &pb->eqs[e]);
483 for (e = 0; e < pb->num_geqs; e++)
488 for (v = 1; v <= pb->num_vars; v++)
490 last_links[v] = first_links[v] = 0;
493 for (v2 = 1; v2 <= pb->num_vars; v2++)
497 for (e = 0; e < pb->num_geqs; e++)
500 for (v = 1; v <= pb->num_vars; v++)
501 if (pb->geqs[e].coef[v] == 1)
503 else if (pb->geqs[e].coef[v] == -1)
508 while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
513 while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
518 while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
521 if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
523 || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
525 /* Not a partial order relation. */
529 if (pb->geqs[e].coef[v1] == 1)
536 /* Relation is v1 <= v2 or v1 < v2. */
537 po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
541 for (v = 1; v <= pb->num_vars; v++)
542 chain_length[v] = last_links[v];
544 /* Just in case pb->num_vars <= 0. */
546 for (t = 0; t < pb->num_vars; t++)
550 for (v1 = 1; v1 <= pb->num_vars; v1++)
551 for (v2 = 1; v2 <= pb->num_vars; v2++)
552 if (po[v1][v2] != none &&
553 chain_length[v1] <= chain_length[v2])
555 chain_length[v1] = chain_length[v2] + 1;
560 /* Caught in cycle. */
561 gcc_assert (!change);
563 for (v1 = 1; v1 <= pb->num_vars; v1++)
564 if (chain_length[v1] == 0)
569 for (v1 = 2; v1 <= pb->num_vars; v1++)
570 if (chain_length[v1] + first_links[v1] >
571 chain_length[v] + first_links[v])
574 if (chain_length[v] + first_links[v] == 0)
578 fprintf (file, "; ");
582 /* Chain starts at v. */
587 for (e = 0; e < pb->num_geqs; e++)
588 if (live[e] && pb->geqs[e].coef[v] == 1)
591 fprintf (file, ", ");
593 tmp = pb->geqs[e].coef[v];
594 pb->geqs[e].coef[v] = 0;
595 omega_print_term (file, pb, &pb->geqs[e], -1);
596 pb->geqs[e].coef[v] = tmp;
602 fprintf (file, " <= ");
611 for (v2 = 1; v2 <= pb->num_vars; v2++)
612 if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
615 if (v2 > pb->num_vars)
622 fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
624 for (multiprint = false, i = 1; i < m; i++)
630 fprintf (file, " <= ");
632 fprintf (file, " < ");
634 fprintf (file, "%s", omega_variable_to_str (pb, v2));
635 live[po_eq[v][v2]] = false;
637 if (!multiprint && i < m - 1)
638 for (v3 = 1; v3 <= pb->num_vars; v3++)
640 if (v == v3 || v2 == v3
641 || po[v][v2] != po[v][v3]
642 || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
645 fprintf (file, ",%s", omega_variable_to_str (pb, v3));
646 live[po_eq[v][v3]] = false;
647 live[po_eq[v3][chain[i + 1]]] = false;
655 /* Print last_links. */
660 for (e = 0; e < pb->num_geqs; e++)
661 if (live[e] && pb->geqs[e].coef[v] == -1)
664 fprintf (file, ", ");
666 fprintf (file, " <= ");
668 tmp = pb->geqs[e].coef[v];
669 pb->geqs[e].coef[v] = 0;
670 omega_print_term (file, pb, &pb->geqs[e], 1);
671 pb->geqs[e].coef[v] = tmp;
678 for (e = 0; e < pb->num_geqs; e++)
682 fprintf (file, "; ");
684 omega_print_geq (file, pb, &pb->geqs[e]);
687 for (e = 0; e < pb->num_subs; e++)
689 eqn eq = &pb->subs[e];
692 fprintf (file, "; ");
697 fprintf (file, "%s := ", omega_var_to_str (eq->key));
699 fprintf (file, "#%d := ", eq->key);
701 omega_print_term (file, pb, eq, 1);
714 /* Assign to variable I in PB the next wildcard name. The name of a
715 wildcard is a negative number. */
716 static int next_wild_card = 0;
719 omega_name_wild_card (omega_pb pb, int i)
722 if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
724 pb->var[i] = next_wild_card;
727 /* Return the index of the last protected (or safe) variable in PB,
728 after having added a new wildcard variable. */
731 omega_add_new_wild_card (omega_pb pb)
734 int i = ++pb->safe_vars;
737 /* Make a free place in the protected (safe) variables, by moving
738 the non protected variable pointed by "I" at the end, ie. at
739 offset pb->num_vars. */
740 if (pb->num_vars != i)
742 /* Move "I" for all the inequalities. */
743 for (e = pb->num_geqs - 1; e >= 0; e--)
745 if (pb->geqs[e].coef[i])
746 pb->geqs[e].touched = 1;
748 pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
751 /* Move "I" for all the equalities. */
752 for (e = pb->num_eqs - 1; e >= 0; e--)
753 pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
755 /* Move "I" for all the substitutions. */
756 for (e = pb->num_subs - 1; e >= 0; e--)
757 pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
759 /* Move the identifier. */
760 pb->var[pb->num_vars] = pb->var[i];
763 /* Initialize at zero all the coefficients */
764 for (e = pb->num_geqs - 1; e >= 0; e--)
765 pb->geqs[e].coef[i] = 0;
767 for (e = pb->num_eqs - 1; e >= 0; e--)
768 pb->eqs[e].coef[i] = 0;
770 for (e = pb->num_subs - 1; e >= 0; e--)
771 pb->subs[e].coef[i] = 0;
773 /* And give it a name. */
774 omega_name_wild_card (pb, i);
778 /* Delete inequality E from problem PB that has N_VARS variables. */
781 omega_delete_geq (omega_pb pb, int e, int n_vars)
783 if (dump_file && (dump_flags & TDF_DETAILS))
785 fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
786 omega_print_geq (dump_file, pb, &pb->geqs[e]);
787 fprintf (dump_file, "\n");
790 if (e < pb->num_geqs - 1)
791 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
796 /* Delete extra inequality E from problem PB that has N_VARS
800 omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
802 if (dump_file && (dump_flags & TDF_DETAILS))
804 fprintf (dump_file, "Deleting %d: ",e);
805 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
806 fprintf (dump_file, "\n");
809 if (e < pb->num_geqs - 1)
810 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
816 /* Remove variable I from problem PB. */
819 omega_delete_variable (omega_pb pb, int i)
821 int n_vars = pb->num_vars;
824 if (omega_safe_var_p (pb, i))
826 int j = pb->safe_vars;
828 for (e = pb->num_geqs - 1; e >= 0; e--)
830 pb->geqs[e].touched = 1;
831 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
832 pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
835 for (e = pb->num_eqs - 1; e >= 0; e--)
837 pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
838 pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
841 for (e = pb->num_subs - 1; e >= 0; e--)
843 pb->subs[e].coef[i] = pb->subs[e].coef[j];
844 pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
847 pb->var[i] = pb->var[j];
848 pb->var[j] = pb->var[n_vars];
852 for (e = pb->num_geqs - 1; e >= 0; e--)
853 if (pb->geqs[e].coef[n_vars])
855 pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
856 pb->geqs[e].touched = 1;
859 for (e = pb->num_eqs - 1; e >= 0; e--)
860 pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
862 for (e = pb->num_subs - 1; e >= 0; e--)
863 pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
865 pb->var[i] = pb->var[n_vars];
868 if (omega_safe_var_p (pb, i))
874 /* Because the coefficients of an equation are sparse, PACKING records
875 indices for non null coefficients. */
878 /* Set up the coefficients of PACKING, following the coefficients of
879 equation EQN that has NUM_VARS variables. */
882 setup_packing (eqn eqn, int num_vars)
887 for (k = num_vars; k >= 0; k--)
894 /* Computes a linear combination of EQ and SUB at VAR with coefficient
895 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
896 non null indices of SUB stored in PACKING. */
899 omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
902 if (eq->coef[var] != 0)
904 if (eq->color == omega_black)
908 int j, k = eq->coef[var];
912 for (j = top_var; j >= 0; j--)
913 eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
918 /* Substitute in PB variable VAR with "C * SUB". */
921 omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
923 int e, top_var = setup_packing (sub, pb->num_vars);
925 *found_black = false;
927 if (dump_file && (dump_flags & TDF_DETAILS))
929 if (sub->color == omega_red)
930 fprintf (dump_file, "[");
932 fprintf (dump_file, "substituting using %s := ",
933 omega_variable_to_str (pb, var));
934 omega_print_term (dump_file, pb, sub, -c);
936 if (sub->color == omega_red)
937 fprintf (dump_file, "]");
939 fprintf (dump_file, "\n");
940 omega_print_vars (dump_file, pb);
943 for (e = pb->num_eqs - 1; e >= 0; e--)
945 eqn eqn = &(pb->eqs[e]);
947 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
949 if (dump_file && (dump_flags & TDF_DETAILS))
951 omega_print_eq (dump_file, pb, eqn);
952 fprintf (dump_file, "\n");
956 for (e = pb->num_geqs - 1; e >= 0; e--)
958 eqn eqn = &(pb->geqs[e]);
960 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
962 if (eqn->coef[var] && eqn->color == omega_red)
965 if (dump_file && (dump_flags & TDF_DETAILS))
967 omega_print_geq (dump_file, pb, eqn);
968 fprintf (dump_file, "\n");
972 for (e = pb->num_subs - 1; e >= 0; e--)
974 eqn eqn = &(pb->subs[e]);
976 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
978 if (dump_file && (dump_flags & TDF_DETAILS))
980 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
981 omega_print_term (dump_file, pb, eqn, 1);
982 fprintf (dump_file, "\n");
986 if (dump_file && (dump_flags & TDF_DETAILS))
987 fprintf (dump_file, "---\n\n");
989 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
993 /* Substitute in PB variable VAR with "C * SUB". */
996 omega_substitute (omega_pb pb, eqn sub, int var, int c)
999 int top_var = setup_packing (sub, pb->num_vars);
1001 if (dump_file && (dump_flags & TDF_DETAILS))
1003 fprintf (dump_file, "substituting using %s := ",
1004 omega_variable_to_str (pb, var));
1005 omega_print_term (dump_file, pb, sub, -c);
1006 fprintf (dump_file, "\n");
1007 omega_print_vars (dump_file, pb);
1012 for (e = pb->num_eqs - 1; e >= 0; e--)
1013 pb->eqs[e].coef[var] = 0;
1015 for (e = pb->num_geqs - 1; e >= 0; e--)
1016 if (pb->geqs[e].coef[var] != 0)
1018 pb->geqs[e].touched = 1;
1019 pb->geqs[e].coef[var] = 0;
1022 for (e = pb->num_subs - 1; e >= 0; e--)
1023 pb->subs[e].coef[var] = 0;
1025 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1028 eqn eqn = &(pb->subs[pb->num_subs++]);
1030 for (k = pb->num_vars; k >= 0; k--)
1033 eqn->key = pb->var[var];
1034 eqn->color = omega_black;
1037 else if (top_var == 0 && packing[0] == 0)
1039 c = -sub->coef[0] * c;
1041 for (e = pb->num_eqs - 1; e >= 0; e--)
1043 pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
1044 pb->eqs[e].coef[var] = 0;
1047 for (e = pb->num_geqs - 1; e >= 0; e--)
1048 if (pb->geqs[e].coef[var] != 0)
1050 pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
1051 pb->geqs[e].coef[var] = 0;
1052 pb->geqs[e].touched = 1;
1055 for (e = pb->num_subs - 1; e >= 0; e--)
1057 pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
1058 pb->subs[e].coef[var] = 0;
1061 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1064 eqn eqn = &(pb->subs[pb->num_subs++]);
1066 for (k = pb->num_vars; k >= 1; k--)
1070 eqn->key = pb->var[var];
1071 eqn->color = omega_black;
1074 if (dump_file && (dump_flags & TDF_DETAILS))
1076 fprintf (dump_file, "---\n\n");
1077 omega_print_problem (dump_file, pb);
1078 fprintf (dump_file, "===\n\n");
1083 for (e = pb->num_eqs - 1; e >= 0; e--)
1085 eqn eqn = &(pb->eqs[e]);
1086 int k = eqn->coef[var];
1093 for (j = top_var; j >= 0; j--)
1096 eqn->coef[j0] -= sub->coef[j0] * k;
1100 if (dump_file && (dump_flags & TDF_DETAILS))
1102 omega_print_eq (dump_file, pb, eqn);
1103 fprintf (dump_file, "\n");
1107 for (e = pb->num_geqs - 1; e >= 0; e--)
1109 eqn eqn = &(pb->geqs[e]);
1110 int k = eqn->coef[var];
1118 for (j = top_var; j >= 0; j--)
1121 eqn->coef[j0] -= sub->coef[j0] * k;
1125 if (dump_file && (dump_flags & TDF_DETAILS))
1127 omega_print_geq (dump_file, pb, eqn);
1128 fprintf (dump_file, "\n");
1132 for (e = pb->num_subs - 1; e >= 0; e--)
1134 eqn eqn = &(pb->subs[e]);
1135 int k = eqn->coef[var];
1142 for (j = top_var; j >= 0; j--)
1145 eqn->coef[j0] -= sub->coef[j0] * k;
1149 if (dump_file && (dump_flags & TDF_DETAILS))
1151 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1152 omega_print_term (dump_file, pb, eqn, 1);
1153 fprintf (dump_file, "\n");
1157 if (dump_file && (dump_flags & TDF_DETAILS))
1159 fprintf (dump_file, "---\n\n");
1160 omega_print_problem (dump_file, pb);
1161 fprintf (dump_file, "===\n\n");
1164 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1167 eqn eqn = &(pb->subs[pb->num_subs++]);
1170 for (k = pb->num_vars; k >= 0; k--)
1171 eqn->coef[k] = c * (sub->coef[k]);
1173 eqn->key = pb->var[var];
1174 eqn->color = sub->color;
1179 /* Solve e = factor alpha for x_j and substitute. */
1182 omega_do_mod (omega_pb pb, int factor, int e, int j)
1185 eqn eq = omega_alloc_eqns (0, 1);
1187 bool kill_j = false;
1189 omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
1191 for (k = pb->num_vars; k >= 0; k--)
1193 eq->coef[k] = int_mod (eq->coef[k], factor);
1195 if (2 * eq->coef[k] >= factor)
1196 eq->coef[k] -= factor;
1199 nfactor = eq->coef[j];
1201 if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
1203 i = omega_add_new_wild_card (pb);
1204 eq->coef[pb->num_vars] = eq->coef[i];
1206 eq->coef[i] = -factor;
1211 eq->coef[j] = -factor;
1212 if (!omega_wildcard_p (pb, j))
1213 omega_name_wild_card (pb, j);
1216 omega_substitute (pb, eq, j, nfactor);
1218 for (k = pb->num_vars; k >= 0; k--)
1219 pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
1222 omega_delete_variable (pb, j);
1224 if (dump_file && (dump_flags & TDF_DETAILS))
1226 fprintf (dump_file, "Mod-ing and normalizing produces:\n");
1227 omega_print_problem (dump_file, pb);
1230 omega_free_eqns (eq, 1);
1233 /* Multiplies by -1 inequality E. */
1236 omega_negate_geq (omega_pb pb, int e)
1240 for (i = pb->num_vars; i >= 0; i--)
1241 pb->geqs[e].coef[i] *= -1;
1243 pb->geqs[e].coef[0]--;
1244 pb->geqs[e].touched = 1;
1247 /* Returns OMEGA_TRUE when problem PB has a solution. */
1249 static enum omega_result
1250 verify_omega_pb (omega_pb pb)
1252 enum omega_result result;
1254 bool any_color = false;
1255 omega_pb tmp_problem = XNEW (struct omega_pb_d);
1257 omega_copy_problem (tmp_problem, pb);
1258 tmp_problem->safe_vars = 0;
1259 tmp_problem->num_subs = 0;
1261 for (e = pb->num_geqs - 1; e >= 0; e--)
1262 if (pb->geqs[e].color == omega_red)
1268 if (please_no_equalities_in_simplified_problems)
1272 original_problem = no_problem;
1274 original_problem = pb;
1276 if (dump_file && (dump_flags & TDF_DETAILS))
1278 fprintf (dump_file, "verifying problem");
1281 fprintf (dump_file, " (color mode)");
1283 fprintf (dump_file, " :\n");
1284 omega_print_problem (dump_file, pb);
1287 result = omega_solve_problem (tmp_problem, omega_unknown);
1288 original_problem = no_problem;
1291 if (dump_file && (dump_flags & TDF_DETAILS))
1293 if (result != omega_false)
1294 fprintf (dump_file, "verified problem\n");
1296 fprintf (dump_file, "disproved problem\n");
1297 omega_print_problem (dump_file, pb);
1303 /* Add a new equality to problem PB at last position E. */
1306 adding_equality_constraint (omega_pb pb, int e)
1308 if (original_problem != no_problem
1309 && original_problem != pb
1313 int e2 = original_problem->num_eqs++;
1315 if (dump_file && (dump_flags & TDF_DETAILS))
1317 "adding equality constraint %d to outer problem\n", e2);
1318 omega_init_eqn_zero (&original_problem->eqs[e2],
1319 original_problem->num_vars);
1321 for (i = pb->num_vars; i >= 1; i--)
1323 for (j = original_problem->num_vars; j >= 1; j--)
1324 if (original_problem->var[j] == pb->var[i])
1329 if (dump_file && (dump_flags & TDF_DETAILS))
1330 fprintf (dump_file, "retracting\n");
1331 original_problem->num_eqs--;
1334 original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
1337 original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
1339 if (dump_file && (dump_flags & TDF_DETAILS))
1340 omega_print_problem (dump_file, original_problem);
1344 static int *fast_lookup;
1345 static int *fast_lookup_red;
1349 normalize_uncoupled,
1351 } normalize_return_type;
1353 /* Normalizes PB by removing redundant constraints. Returns
1354 normalize_false when the constraints system has no solution,
1355 otherwise returns normalize_coupled or normalize_uncoupled. */
1357 static normalize_return_type
1358 normalize_omega_problem (omega_pb pb)
1360 int e, i, j, k, n_vars;
1361 int coupled_subscripts = 0;
1363 n_vars = pb->num_vars;
1365 for (e = 0; e < pb->num_geqs; e++)
1367 if (!pb->geqs[e].touched)
1369 if (!single_var_geq (&pb->geqs[e], n_vars))
1370 coupled_subscripts = 1;
1374 int g, top_var, i0, hashCode;
1375 int *p = &packing[0];
1377 for (k = 1; k <= n_vars; k++)
1378 if (pb->geqs[e].coef[k])
1381 top_var = (p - &packing[0]) - 1;
1385 if (pb->geqs[e].coef[0] < 0)
1387 if (dump_file && (dump_flags & TDF_DETAILS))
1389 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1390 fprintf (dump_file, "\nequations have no solution \n");
1392 return normalize_false;
1395 omega_delete_geq (pb, e, n_vars);
1399 else if (top_var == 0)
1401 int singlevar = packing[0];
1403 g = pb->geqs[e].coef[singlevar];
1407 pb->geqs[e].coef[singlevar] = 1;
1408 pb->geqs[e].key = singlevar;
1413 pb->geqs[e].coef[singlevar] = -1;
1414 pb->geqs[e].key = -singlevar;
1418 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1423 int hash_key_multiplier = 31;
1425 coupled_subscripts = 1;
1428 g = pb->geqs[e].coef[i];
1429 hashCode = g * (i + 3);
1434 for (; i0 >= 0; i0--)
1439 x = pb->geqs[e].coef[i];
1440 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1455 for (; i0 >= 0; i0--)
1459 x = pb->geqs[e].coef[i];
1460 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1465 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1468 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1469 hashCode = pb->geqs[e].coef[i] * (i + 3);
1471 for (; i0 >= 0; i0--)
1474 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1475 hashCode = hashCode * hash_key_multiplier * (i + 3)
1476 + pb->geqs[e].coef[i];
1480 g2 = abs (hashCode);
1482 if (dump_file && (dump_flags & TDF_DETAILS))
1484 fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
1485 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1486 fprintf (dump_file, "\n");
1489 j = g2 % HASH_TABLE_SIZE;
1492 eqn proto = &(hash_master[j]);
1494 if (proto->touched == g2)
1496 if (proto->coef[0] == top_var)
1499 for (i0 = top_var; i0 >= 0; i0--)
1503 if (pb->geqs[e].coef[i] != proto->coef[i])
1507 for (i0 = top_var; i0 >= 0; i0--)
1511 if (pb->geqs[e].coef[i] != -proto->coef[i])
1518 pb->geqs[e].key = proto->key;
1520 pb->geqs[e].key = -proto->key;
1525 else if (proto->touched < 0)
1527 omega_init_eqn_zero (proto, pb->num_vars);
1529 for (i0 = top_var; i0 >= 0; i0--)
1532 proto->coef[i] = pb->geqs[e].coef[i];
1535 for (i0 = top_var; i0 >= 0; i0--)
1538 proto->coef[i] = -pb->geqs[e].coef[i];
1541 proto->coef[0] = top_var;
1542 proto->touched = g2;
1544 if (dump_file && (dump_flags & TDF_DETAILS))
1545 fprintf (dump_file, " constraint key = %d\n",
1548 proto->key = next_key++;
1550 /* Too many hash keys generated. */
1551 gcc_assert (proto->key <= MAX_KEYS);
1554 pb->geqs[e].key = proto->key;
1556 pb->geqs[e].key = -proto->key;
1561 j = (j + 1) % HASH_TABLE_SIZE;
1565 pb->geqs[e].touched = 0;
1569 int eKey = pb->geqs[e].key;
1573 int cTerm = pb->geqs[e].coef[0];
1574 e2 = fast_lookup[MAX_KEYS - eKey];
1576 if (e2 < e && pb->geqs[e2].key == -eKey
1577 && pb->geqs[e2].color == omega_black)
1579 if (pb->geqs[e2].coef[0] < -cTerm)
1581 if (dump_file && (dump_flags & TDF_DETAILS))
1583 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1584 fprintf (dump_file, "\n");
1585 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1587 "\nequations have no solution \n");
1589 return normalize_false;
1592 if (pb->geqs[e2].coef[0] == -cTerm
1594 || pb->geqs[e].color == omega_black))
1596 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1598 if (pb->geqs[e].color == omega_black)
1599 adding_equality_constraint (pb, pb->num_eqs);
1601 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1605 e2 = fast_lookup_red[MAX_KEYS - eKey];
1607 if (e2 < e && pb->geqs[e2].key == -eKey
1608 && pb->geqs[e2].color == omega_red)
1610 if (pb->geqs[e2].coef[0] < -cTerm)
1612 if (dump_file && (dump_flags & TDF_DETAILS))
1614 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1615 fprintf (dump_file, "\n");
1616 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1618 "\nequations have no solution \n");
1620 return normalize_false;
1623 if (pb->geqs[e2].coef[0] == -cTerm && create_color)
1625 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1627 pb->eqs[pb->num_eqs].color = omega_red;
1629 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1633 e2 = fast_lookup[MAX_KEYS + eKey];
1635 if (e2 < e && pb->geqs[e2].key == eKey
1636 && pb->geqs[e2].color == omega_black)
1638 if (pb->geqs[e2].coef[0] > cTerm)
1640 if (pb->geqs[e].color == omega_black)
1642 if (dump_file && (dump_flags & TDF_DETAILS))
1645 "Removing Redundant Equation: ");
1646 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1647 fprintf (dump_file, "\n");
1649 "[a] Made Redundant by: ");
1650 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1651 fprintf (dump_file, "\n");
1653 pb->geqs[e2].coef[0] = cTerm;
1654 omega_delete_geq (pb, e, n_vars);
1661 if (dump_file && (dump_flags & TDF_DETAILS))
1663 fprintf (dump_file, "Removing Redundant Equation: ");
1664 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1665 fprintf (dump_file, "\n");
1666 fprintf (dump_file, "[b] Made Redundant by: ");
1667 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1668 fprintf (dump_file, "\n");
1670 omega_delete_geq (pb, e, n_vars);
1676 e2 = fast_lookup_red[MAX_KEYS + eKey];
1678 if (e2 < e && pb->geqs[e2].key == eKey
1679 && pb->geqs[e2].color == omega_red)
1681 if (pb->geqs[e2].coef[0] >= cTerm)
1683 if (dump_file && (dump_flags & TDF_DETAILS))
1685 fprintf (dump_file, "Removing Redundant Equation: ");
1686 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1687 fprintf (dump_file, "\n");
1688 fprintf (dump_file, "[c] Made Redundant by: ");
1689 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1690 fprintf (dump_file, "\n");
1692 pb->geqs[e2].coef[0] = cTerm;
1693 pb->geqs[e2].color = pb->geqs[e].color;
1695 else if (pb->geqs[e].color == omega_red)
1697 if (dump_file && (dump_flags & TDF_DETAILS))
1699 fprintf (dump_file, "Removing Redundant Equation: ");
1700 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1701 fprintf (dump_file, "\n");
1702 fprintf (dump_file, "[d] Made Redundant by: ");
1703 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1704 fprintf (dump_file, "\n");
1707 omega_delete_geq (pb, e, n_vars);
1714 if (pb->geqs[e].color == omega_red)
1715 fast_lookup_red[MAX_KEYS + eKey] = e;
1717 fast_lookup[MAX_KEYS + eKey] = e;
1721 create_color = false;
1722 return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
1725 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1726 of variables in EQN. */
1729 divide_eqn_by_gcd (eqn eqn, int n_vars)
1733 for (var = n_vars; var >= 0; var--)
1734 g = gcd (abs (eqn->coef[var]), g);
1737 for (var = n_vars; var >= 0; var--)
1738 eqn->coef[var] = eqn->coef[var] / g;
1741 /* Rewrite some non-safe variables in function of protected
1742 wildcard variables. */
1745 cleanout_wildcards (omega_pb pb)
1748 int n_vars = pb->num_vars;
1749 bool renormalize = false;
1751 for (e = pb->num_eqs - 1; e >= 0; e--)
1752 for (i = n_vars; !omega_safe_var_p (pb, i); i--)
1753 if (pb->eqs[e].coef[i] != 0)
1755 /* i is the last nonzero non-safe variable. */
1757 for (j = i - 1; !omega_safe_var_p (pb, j); j--)
1758 if (pb->eqs[e].coef[j] != 0)
1761 /* j is the next nonzero non-safe variable, or points
1762 to a safe variable: it is then a wildcard variable. */
1765 if (omega_safe_var_p (pb, j))
1767 eqn sub = &(pb->eqs[e]);
1768 int c = pb->eqs[e].coef[i];
1772 if (dump_file && (dump_flags & TDF_DETAILS))
1775 "Found a single wild card equality: ");
1776 omega_print_eq (dump_file, pb, &pb->eqs[e]);
1777 fprintf (dump_file, "\n");
1778 omega_print_problem (dump_file, pb);
1781 for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
1782 if (e != e2 && pb->eqs[e2].coef[i]
1783 && (pb->eqs[e2].color == omega_red
1784 || (pb->eqs[e2].color == omega_black
1785 && pb->eqs[e].color == omega_black)))
1787 eqn eqn = &(pb->eqs[e2]);
1790 for (var = n_vars; var >= 0; var--)
1791 eqn->coef[var] *= a;
1795 for (var = n_vars; var >= 0; var--)
1796 eqn->coef[var] -= sub->coef[var] * k / c;
1799 divide_eqn_by_gcd (eqn, n_vars);
1802 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
1803 if (pb->geqs[e2].coef[i]
1804 && (pb->geqs[e2].color == omega_red
1805 || (pb->eqs[e].color == omega_black
1806 && pb->geqs[e2].color == omega_black)))
1808 eqn eqn = &(pb->geqs[e2]);
1811 for (var = n_vars; var >= 0; var--)
1812 eqn->coef[var] *= a;
1816 for (var = n_vars; var >= 0; var--)
1817 eqn->coef[var] -= sub->coef[var] * k / c;
1824 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
1825 if (pb->subs[e2].coef[i]
1826 && (pb->subs[e2].color == omega_red
1827 || (pb->subs[e2].color == omega_black
1828 && pb->eqs[e].color == omega_black)))
1830 eqn eqn = &(pb->subs[e2]);
1833 for (var = n_vars; var >= 0; var--)
1834 eqn->coef[var] *= a;
1838 for (var = n_vars; var >= 0; var--)
1839 eqn->coef[var] -= sub->coef[var] * k / c;
1842 divide_eqn_by_gcd (eqn, n_vars);
1845 if (dump_file && (dump_flags & TDF_DETAILS))
1847 fprintf (dump_file, "cleaned-out wildcard: ");
1848 omega_print_problem (dump_file, pb);
1855 normalize_omega_problem (pb);
1858 /* Swap values contained in I and J. */
1861 swap (int *i, int *j)
1869 /* Swap values contained in I and J. */
1872 bswap (bool *i, bool *j)
1880 /* Make variable IDX unprotected in PB, by swapping its index at the
1881 PB->safe_vars rank. */
1884 omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
1886 /* If IDX is protected... */
1887 if (*idx < pb->safe_vars)
1889 /* ... swap its index with the last non protected index. */
1890 int j = pb->safe_vars;
1893 for (e = pb->num_geqs - 1; e >= 0; e--)
1895 pb->geqs[e].touched = 1;
1896 swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
1899 for (e = pb->num_eqs - 1; e >= 0; e--)
1900 swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
1902 for (e = pb->num_subs - 1; e >= 0; e--)
1903 swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
1906 bswap (&unprotect[*idx], &unprotect[j]);
1908 swap (&pb->var[*idx], &pb->var[j]);
1909 pb->forwarding_address[pb->var[*idx]] = *idx;
1910 pb->forwarding_address[pb->var[j]] = j;
1914 /* The variable at pb->safe_vars is also unprotected now. */
1918 /* During the Fourier-Motzkin elimination some variables are
1919 substituted with other variables. This function resurrects the
1920 substituted variables in PB. */
1923 resurrect_subs (omega_pb pb)
1925 if (pb->num_subs > 0
1926 && please_no_equalities_in_simplified_problems == 0)
1930 if (dump_file && (dump_flags & TDF_DETAILS))
1933 "problem reduced, bringing variables back to life\n");
1934 omega_print_problem (dump_file, pb);
1937 for (i = 1; omega_safe_var_p (pb, i); i++)
1938 if (omega_wildcard_p (pb, i))
1939 omega_unprotect_1 (pb, &i, NULL);
1943 for (e = pb->num_geqs - 1; e >= 0; e--)
1944 if (single_var_geq (&pb->geqs[e], pb->num_vars))
1946 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
1947 pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
1951 pb->geqs[e].touched = 1;
1952 pb->geqs[e].key = 0;
1955 for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
1957 pb->var[i + m] = pb->var[i];
1959 for (e = pb->num_geqs - 1; e >= 0; e--)
1960 pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
1962 for (e = pb->num_eqs - 1; e >= 0; e--)
1963 pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
1965 for (e = pb->num_subs - 1; e >= 0; e--)
1966 pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
1969 for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
1971 for (e = pb->num_geqs - 1; e >= 0; e--)
1972 pb->geqs[e].coef[i] = 0;
1974 for (e = pb->num_eqs - 1; e >= 0; e--)
1975 pb->eqs[e].coef[i] = 0;
1977 for (e = pb->num_subs - 1; e >= 0; e--)
1978 pb->subs[e].coef[i] = 0;
1983 for (e = pb->num_subs - 1; e >= 0; e--)
1985 pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
1986 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
1988 pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
1989 pb->eqs[pb->num_eqs].color = omega_black;
1991 if (dump_file && (dump_flags & TDF_DETAILS))
1993 fprintf (dump_file, "brought back: ");
1994 omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
1995 fprintf (dump_file, "\n");
1999 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2005 if (dump_file && (dump_flags & TDF_DETAILS))
2007 fprintf (dump_file, "variables brought back to life\n");
2008 omega_print_problem (dump_file, pb);
2011 cleanout_wildcards (pb);
2016 implies (unsigned int a, unsigned int b)
2018 return (a == (a & b));
2021 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2022 extra step is performed. Returns omega_false when there exist no
2023 solution, omega_true otherwise. */
2026 omega_eliminate_redundant (omega_pb pb, bool expensive)
2028 int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
2029 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2030 omega_pb tmp_problem;
2032 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2033 unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2034 unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2035 unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2037 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2038 unsigned int pp, pz, pn;
2040 if (dump_file && (dump_flags & TDF_DETAILS))
2042 fprintf (dump_file, "in eliminate Redundant:\n");
2043 omega_print_problem (dump_file, pb);
2046 for (e = pb->num_geqs - 1; e >= 0; e--)
2051 peqs[e] = zeqs[e] = neqs[e] = 0;
2053 for (i = pb->num_vars; i >= 1; i--)
2055 if (pb->geqs[e].coef[i] > 0)
2057 else if (pb->geqs[e].coef[i] < 0)
2067 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2069 for (e2 = e1 - 1; e2 >= 0; e2--)
2072 for (p = pb->num_vars; p > 1; p--)
2073 for (q = p - 1; q > 0; q--)
2074 if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
2075 - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
2081 pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
2082 | (neqs[e1] & peqs[e2]));
2083 pp = peqs[e1] | peqs[e2];
2084 pn = neqs[e1] | neqs[e2];
2086 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2087 if (e3 != e1 && e3 != e2)
2089 if (!implies (zeqs[e3], pz))
2092 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2093 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2094 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2095 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2098 if (alpha1 * alpha2 <= 0)
2110 /* Trying to prove e3 is redundant. */
2111 if (!implies (peqs[e3], pp)
2112 || !implies (neqs[e3], pn))
2115 if (pb->geqs[e3].color == omega_black
2116 && (pb->geqs[e1].color == omega_red
2117 || pb->geqs[e2].color == omega_red))
2120 for (k = pb->num_vars; k >= 1; k--)
2121 if (alpha3 * pb->geqs[e3].coef[k]
2122 != (alpha1 * pb->geqs[e1].coef[k]
2123 + alpha2 * pb->geqs[e2].coef[k]))
2126 c = (alpha1 * pb->geqs[e1].coef[0]
2127 + alpha2 * pb->geqs[e2].coef[0]);
2129 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2131 if (dump_file && (dump_flags & TDF_DETAILS))
2134 "found redundant inequality\n");
2136 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2137 alpha1, alpha2, alpha3);
2139 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2140 fprintf (dump_file, "\n");
2141 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2142 fprintf (dump_file, "\n=> ");
2143 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2144 fprintf (dump_file, "\n\n");
2152 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2153 or trying to prove e3 < 0, and therefore the
2154 problem has no solutions. */
2155 if (!implies (peqs[e3], pn)
2156 || !implies (neqs[e3], pp))
2159 if (pb->geqs[e1].color == omega_red
2160 || pb->geqs[e2].color == omega_red
2161 || pb->geqs[e3].color == omega_red)
2164 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2165 for (k = pb->num_vars; k >= 1; k--)
2166 if (alpha3 * pb->geqs[e3].coef[k]
2167 != (alpha1 * pb->geqs[e1].coef[k]
2168 + alpha2 * pb->geqs[e2].coef[k]))
2171 c = (alpha1 * pb->geqs[e1].coef[0]
2172 + alpha2 * pb->geqs[e2].coef[0]);
2174 if (c < alpha3 * (pb->geqs[e3].coef[0]))
2176 /* We just proved e3 < 0, so no solutions exist. */
2177 if (dump_file && (dump_flags & TDF_DETAILS))
2180 "found implied over tight inequality\n");
2182 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2183 alpha1, alpha2, -alpha3);
2184 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2185 fprintf (dump_file, "\n");
2186 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2187 fprintf (dump_file, "\n=> not ");
2188 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2189 fprintf (dump_file, "\n\n");
2197 else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2199 /* We just proved that e3 <=0, so e3 = 0. */
2200 if (dump_file && (dump_flags & TDF_DETAILS))
2203 "found implied tight inequality\n");
2205 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2206 alpha1, alpha2, -alpha3);
2207 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2208 fprintf (dump_file, "\n");
2209 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2210 fprintf (dump_file, "\n=> inverse ");
2211 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2212 fprintf (dump_file, "\n\n");
2215 omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2216 &pb->geqs[e3], pb->num_vars);
2217 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2218 adding_equality_constraint (pb, pb->num_eqs - 1);
2226 /* Delete the inequalities that were marked as dead. */
2227 for (e = pb->num_geqs - 1; e >= 0; e--)
2229 omega_delete_geq (pb, e, pb->num_vars);
2232 goto eliminate_redundant_done;
2234 tmp_problem = XNEW (struct omega_pb_d);
2237 for (e = pb->num_geqs - 1; e >= 0; e--)
2239 if (dump_file && (dump_flags & TDF_DETAILS))
2242 "checking equation %d to see if it is redundant: ", e);
2243 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2244 fprintf (dump_file, "\n");
2247 omega_copy_problem (tmp_problem, pb);
2248 omega_negate_geq (tmp_problem, e);
2249 tmp_problem->safe_vars = 0;
2250 tmp_problem->variables_freed = false;
2252 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2253 omega_delete_geq (pb, e, pb->num_vars);
2259 if (!omega_reduce_with_subs)
2261 resurrect_subs (pb);
2262 gcc_assert (please_no_equalities_in_simplified_problems
2263 || pb->num_subs == 0);
2266 eliminate_redundant_done:
2274 /* For each inequality that has coefficients bigger than 20, try to
2275 create a new constraint that cannot be derived from the original
2276 constraint and that has smaller coefficients. Add the new
2277 constraint at the end of geqs. Return the number of inequalities
2278 that have been added to PB. */
2281 smooth_weird_equations (omega_pb pb)
2283 int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2288 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2289 if (pb->geqs[e1].color == omega_black)
2293 for (v = pb->num_vars; v >= 1; v--)
2294 if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2295 g = abs (pb->geqs[e1].coef[v]);
2302 for (v = pb->num_vars; v >= 1; v--)
2303 pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2306 pb->geqs[e3].color = omega_black;
2307 pb->geqs[e3].touched = 1;
2309 pb->geqs[e3].coef[0] = 9997;
2311 if (dump_file && (dump_flags & TDF_DETAILS))
2313 fprintf (dump_file, "Checking to see if we can derive: ");
2314 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2315 fprintf (dump_file, "\n from: ");
2316 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2317 fprintf (dump_file, "\n");
2320 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2321 if (e1 != e2 && pb->geqs[e2].color == omega_black)
2323 for (p = pb->num_vars; p > 1; p--)
2325 for (q = p - 1; q > 0; q--)
2328 (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2329 pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2338 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2339 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2340 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2341 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2344 if (alpha1 * alpha2 <= 0)
2356 /* Try to prove e3 is redundant: verify
2357 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2358 for (k = pb->num_vars; k >= 1; k--)
2359 if (alpha3 * pb->geqs[e3].coef[k]
2360 != (alpha1 * pb->geqs[e1].coef[k]
2361 + alpha2 * pb->geqs[e2].coef[k]))
2364 c = alpha1 * pb->geqs[e1].coef[0]
2365 + alpha2 * pb->geqs[e2].coef[0];
2367 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2368 pb->geqs[e3].coef[0] = int_div (c, alpha3);
2373 if (pb->geqs[e3].coef[0] < 9997)
2378 if (dump_file && (dump_flags & TDF_DETAILS))
2381 "Smoothing weird equations; adding:\n");
2382 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2383 fprintf (dump_file, "\nto:\n");
2384 omega_print_problem (dump_file, pb);
2385 fprintf (dump_file, "\n\n");
2393 /* Replace tuples of inequalities, that define upper and lower half
2394 spaces, with an equation. */
2397 coalesce (omega_pb pb)
2402 int found_something = 0;
2404 for (e = 0; e < pb->num_geqs; e++)
2405 if (pb->geqs[e].color == omega_red)
2411 is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2413 for (e = 0; e < pb->num_geqs; e++)
2416 for (e = 0; e < pb->num_geqs; e++)
2417 if (pb->geqs[e].color == omega_red
2418 && !pb->geqs[e].touched)
2419 for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2420 if (!pb->geqs[e2].touched
2421 && pb->geqs[e].key == -pb->geqs[e2].key
2422 && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2423 && pb->geqs[e2].color == omega_red)
2425 omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2427 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2433 for (e = pb->num_geqs - 1; e >= 0; e--)
2435 omega_delete_geq (pb, e, pb->num_vars);
2437 if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2439 fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2441 omega_print_problem (dump_file, pb);
2447 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2448 true, continue to eliminate all the red inequalities. */
2451 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2453 int e, e2, e3, i, j, k, a, alpha1, alpha2;
2455 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2458 omega_pb tmp_problem;
2460 if (dump_file && (dump_flags & TDF_DETAILS))
2462 fprintf (dump_file, "in eliminate RED:\n");
2463 omega_print_problem (dump_file, pb);
2466 if (pb->num_eqs > 0)
2467 omega_simplify_problem (pb);
2469 for (e = pb->num_geqs - 1; e >= 0; e--)
2472 for (e = pb->num_geqs - 1; e >= 0; e--)
2473 if (pb->geqs[e].color == omega_black && !is_dead[e])
2474 for (e2 = e - 1; e2 >= 0; e2--)
2475 if (pb->geqs[e2].color == omega_black
2480 for (i = pb->num_vars; i > 1; i--)
2481 for (j = i - 1; j > 0; j--)
2482 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2483 - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2489 if (dump_file && (dump_flags & TDF_DETAILS))
2492 "found two equations to combine, i = %s, ",
2493 omega_variable_to_str (pb, i));
2494 fprintf (dump_file, "j = %s, alpha = %d\n",
2495 omega_variable_to_str (pb, j), a);
2496 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2497 fprintf (dump_file, "\n");
2498 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2499 fprintf (dump_file, "\n");
2502 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2503 if (pb->geqs[e3].color == omega_red)
2505 alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2506 - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2507 alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2508 - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2510 if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2511 || (a < 0 && alpha1 < 0 && alpha2 < 0))
2513 if (dump_file && (dump_flags & TDF_DETAILS))
2516 "alpha1 = %d, alpha2 = %d;"
2517 "comparing against: ",
2519 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2520 fprintf (dump_file, "\n");
2523 for (k = pb->num_vars; k >= 0; k--)
2525 c = (alpha1 * pb->geqs[e].coef[k]
2526 + alpha2 * pb->geqs[e2].coef[k]);
2528 if (c != a * pb->geqs[e3].coef[k])
2531 if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2532 fprintf (dump_file, " %s: %d, %d\n",
2533 omega_variable_to_str (pb, k), c,
2534 a * pb->geqs[e3].coef[k]);
2539 ((a > 0 && c < a * pb->geqs[e3].coef[k])
2540 || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2542 if (dump_file && (dump_flags & TDF_DETAILS))
2546 "red equation#%d is dead "
2547 "(%d dead so far, %d remain)\n",
2549 pb->num_geqs - dead_count);
2550 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2551 fprintf (dump_file, "\n");
2552 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2553 fprintf (dump_file, "\n");
2554 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2555 fprintf (dump_file, "\n");
2563 for (e = pb->num_geqs - 1; e >= 0; e--)
2565 omega_delete_geq (pb, e, pb->num_vars);
2569 if (dump_file && (dump_flags & TDF_DETAILS))
2571 fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2572 omega_print_problem (dump_file, pb);
2575 for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2576 if (pb->geqs[e].color == omega_red)
2581 if (dump_file && (dump_flags & TDF_DETAILS))
2582 fprintf (dump_file, "fast checks worked\n");
2584 if (!omega_reduce_with_subs)
2585 gcc_assert (please_no_equalities_in_simplified_problems
2586 || pb->num_subs == 0);
2591 if (!omega_verify_simplification
2592 && verify_omega_pb (pb) == omega_false)
2596 tmp_problem = XNEW (struct omega_pb_d);
2598 for (e = pb->num_geqs - 1; e >= 0; e--)
2599 if (pb->geqs[e].color == omega_red)
2601 if (dump_file && (dump_flags & TDF_DETAILS))
2604 "checking equation %d to see if it is redundant: ", e);
2605 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2606 fprintf (dump_file, "\n");
2609 omega_copy_problem (tmp_problem, pb);
2610 omega_negate_geq (tmp_problem, e);
2611 tmp_problem->safe_vars = 0;
2612 tmp_problem->variables_freed = false;
2613 tmp_problem->num_subs = 0;
2615 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2617 if (dump_file && (dump_flags & TDF_DETAILS))
2618 fprintf (dump_file, "it is redundant\n");
2619 omega_delete_geq (pb, e, pb->num_vars);
2623 if (dump_file && (dump_flags & TDF_DETAILS))
2624 fprintf (dump_file, "it is not redundant\n");
2628 if (dump_file && (dump_flags & TDF_DETAILS))
2629 fprintf (dump_file, "no need to check other red equations\n");
2637 /* omega_simplify_problem (pb); */
2639 if (!omega_reduce_with_subs)
2640 gcc_assert (please_no_equalities_in_simplified_problems
2641 || pb->num_subs == 0);
2644 /* Transform some wildcard variables to non-safe variables. */
2647 chain_unprotect (omega_pb pb)
2650 bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2652 for (i = 1; omega_safe_var_p (pb, i); i++)
2654 unprotect[i] = omega_wildcard_p (pb, i);
2656 for (e = pb->num_subs - 1; e >= 0; e--)
2657 if (pb->subs[e].coef[i])
2658 unprotect[i] = false;
2661 if (dump_file && (dump_flags & TDF_DETAILS))
2663 fprintf (dump_file, "Doing chain reaction unprotection\n");
2664 omega_print_problem (dump_file, pb);
2666 for (i = 1; omega_safe_var_p (pb, i); i++)
2668 fprintf (dump_file, "unprotecting %s\n",
2669 omega_variable_to_str (pb, i));
2672 for (i = 1; omega_safe_var_p (pb, i); i++)
2674 omega_unprotect_1 (pb, &i, unprotect);
2676 if (dump_file && (dump_flags & TDF_DETAILS))
2678 fprintf (dump_file, "After chain reactions\n");
2679 omega_print_problem (dump_file, pb);
2685 /* Reduce problem PB. */
2688 omega_problem_reduced (omega_pb pb)
2690 if (omega_verify_simplification
2691 && !in_approximate_mode
2692 && verify_omega_pb (pb) == omega_false)
2695 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2696 && !omega_eliminate_redundant (pb, true))
2699 omega_found_reduction = omega_true;
2701 if (!please_no_equalities_in_simplified_problems)
2704 if (omega_reduce_with_subs
2705 || please_no_equalities_in_simplified_problems)
2706 chain_unprotect (pb);
2708 resurrect_subs (pb);
2710 if (!return_single_result)
2714 for (i = 1; omega_safe_var_p (pb, i); i++)
2715 pb->forwarding_address[pb->var[i]] = i;
2717 for (i = 0; i < pb->num_subs; i++)
2718 pb->forwarding_address[pb->subs[i].key] = -i - 1;
2720 (*omega_when_reduced) (pb);
2723 if (dump_file && (dump_flags & TDF_DETAILS))
2725 fprintf (dump_file, "-------------------------------------------\n");
2726 fprintf (dump_file, "problem reduced:\n");
2727 omega_print_problem (dump_file, pb);
2728 fprintf (dump_file, "-------------------------------------------\n");
2732 /* Eliminates all the free variables for problem PB, that is all the
2733 variables from FV to PB->NUM_VARS. */
2736 omega_free_eliminations (omega_pb pb, int fv)
2738 bool try_again = true;
2740 int n_vars = pb->num_vars;
2746 for (i = n_vars; i > fv; i--)
2748 for (e = pb->num_geqs - 1; e >= 0; e--)
2749 if (pb->geqs[e].coef[i])
2754 else if (pb->geqs[e].coef[i] > 0)
2756 for (e2 = e - 1; e2 >= 0; e2--)
2757 if (pb->geqs[e2].coef[i] < 0)
2762 for (e2 = e - 1; e2 >= 0; e2--)
2763 if (pb->geqs[e2].coef[i] > 0)
2770 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2771 if (pb->subs[e3].coef[i])
2777 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2778 if (pb->eqs[e3].coef[i])
2784 if (dump_file && (dump_flags & TDF_DETAILS))
2785 fprintf (dump_file, "a free elimination of %s\n",
2786 omega_variable_to_str (pb, i));
2790 omega_delete_geq (pb, e, n_vars);
2792 for (e--; e >= 0; e--)
2793 if (pb->geqs[e].coef[i])
2794 omega_delete_geq (pb, e, n_vars);
2796 try_again = (i < n_vars);
2799 omega_delete_variable (pb, i);
2800 n_vars = pb->num_vars;
2805 if (dump_file && (dump_flags & TDF_DETAILS))
2807 fprintf (dump_file, "\nafter free eliminations:\n");
2808 omega_print_problem (dump_file, pb);
2809 fprintf (dump_file, "\n");
2813 /* Do free red eliminations. */
2816 free_red_eliminations (omega_pb pb)
2818 bool try_again = true;
2820 int n_vars = pb->num_vars;
2821 bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2822 bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2823 bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2825 for (i = n_vars; i > 0; i--)
2827 is_red_var[i] = false;
2828 is_dead_var[i] = false;
2831 for (e = pb->num_geqs - 1; e >= 0; e--)
2833 is_dead_geq[e] = false;
2835 if (pb->geqs[e].color == omega_red)
2836 for (i = n_vars; i > 0; i--)
2837 if (pb->geqs[e].coef[i] != 0)
2838 is_red_var[i] = true;
2844 for (i = n_vars; i > 0; i--)
2845 if (!is_red_var[i] && !is_dead_var[i])
2847 for (e = pb->num_geqs - 1; e >= 0; e--)
2848 if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2853 else if (pb->geqs[e].coef[i] > 0)
2855 for (e2 = e - 1; e2 >= 0; e2--)
2856 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2861 for (e2 = e - 1; e2 >= 0; e2--)
2862 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2869 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2870 if (pb->subs[e3].coef[i])
2876 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2877 if (pb->eqs[e3].coef[i])
2883 if (dump_file && (dump_flags & TDF_DETAILS))
2884 fprintf (dump_file, "a free red elimination of %s\n",
2885 omega_variable_to_str (pb, i));
2888 if (pb->geqs[e].coef[i])
2889 is_dead_geq[e] = true;
2892 is_dead_var[i] = true;
2897 for (e = pb->num_geqs - 1; e >= 0; e--)
2899 omega_delete_geq (pb, e, n_vars);
2901 for (i = n_vars; i > 0; i--)
2903 omega_delete_variable (pb, i);
2905 if (dump_file && (dump_flags & TDF_DETAILS))
2907 fprintf (dump_file, "\nafter free red eliminations:\n");
2908 omega_print_problem (dump_file, pb);
2909 fprintf (dump_file, "\n");
2917 /* For equation EQ of the form "0 = EQN", insert in PB two
2918 inequalities "0 <= EQN" and "0 <= -EQN". */
2921 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2925 if (dump_file && (dump_flags & TDF_DETAILS))
2926 fprintf (dump_file, "Converting Eq to Geqs\n");
2928 /* Insert "0 <= EQN". */
2929 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2930 pb->geqs[pb->num_geqs].touched = 1;
2933 /* Insert "0 <= -EQN". */
2934 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2935 pb->geqs[pb->num_geqs].touched = 1;
2937 for (i = 0; i <= pb->num_vars; i++)
2938 pb->geqs[pb->num_geqs].coef[i] *= -1;
2942 if (dump_file && (dump_flags & TDF_DETAILS))
2943 omega_print_problem (dump_file, pb);
2946 /* Eliminates variable I from PB. */
2949 omega_do_elimination (omega_pb pb, int e, int i)
2951 eqn sub = omega_alloc_eqns (0, 1);
2953 int n_vars = pb->num_vars;
2955 if (dump_file && (dump_flags & TDF_DETAILS))
2956 fprintf (dump_file, "eliminating variable %s\n",
2957 omega_variable_to_str (pb, i));
2959 omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
2962 if (c == 1 || c == -1)
2964 if (pb->eqs[e].color == omega_red)
2967 omega_substitute_red (pb, sub, i, c, &fB);
2969 omega_convert_eq_to_geqs (pb, e);
2971 omega_delete_variable (pb, i);
2975 omega_substitute (pb, sub, i, c);
2976 omega_delete_variable (pb, i);
2984 if (dump_file && (dump_flags & TDF_DETAILS))
2985 fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
2987 for (e = pb->num_eqs - 1; e >= 0; e--)
2988 if (pb->eqs[e].coef[i])
2990 eqn eqn = &(pb->eqs[e]);
2992 for (j = n_vars; j >= 0; j--)
2996 if (sub->color == omega_red)
2997 eqn->color = omega_red;
2998 for (j = n_vars; j >= 0; j--)
2999 eqn->coef[j] -= sub->coef[j] * k / c;
3002 for (e = pb->num_geqs - 1; e >= 0; e--)
3003 if (pb->geqs[e].coef[i])
3005 eqn eqn = &(pb->geqs[e]);
3008 if (sub->color == omega_red)
3009 eqn->color = omega_red;
3011 for (j = n_vars; j >= 0; j--)
3018 for (j = n_vars; j >= 0; j--)
3019 eqn->coef[j] -= sub->coef[j] * k / c;
3023 for (e = pb->num_subs - 1; e >= 0; e--)
3024 if (pb->subs[e].coef[i])
3026 eqn eqn = &(pb->subs[e]);
3029 gcc_assert (sub->color == omega_black);
3030 for (j = n_vars; j >= 0; j--)
3034 for (j = n_vars; j >= 0; j--)
3035 eqn->coef[j] -= sub->coef[j] * k / c;
3038 if (in_approximate_mode)
3039 omega_delete_variable (pb, i);
3041 omega_convert_eq_to_geqs (pb, e2);
3044 omega_free_eqns (sub, 1);
3047 /* Helper function for printing "sorry, no solution". */
3049 static inline enum omega_result
3050 omega_problem_has_no_solution (void)
3052 if (dump_file && (dump_flags & TDF_DETAILS))
3053 fprintf (dump_file, "\nequations have no solution \n");
3058 /* Helper function: solve equations in PB one at a time, following the
3059 DESIRED_RES result. */
3061 static enum omega_result
3062 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3069 if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3071 fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3072 desired_res, may_be_red);
3073 omega_print_problem (dump_file, pb);
3074 fprintf (dump_file, "\n");
3080 j = pb->num_eqs - 1;
3086 while (i <= j && pb->eqs[i].color == omega_red)
3089 while (i <= j && pb->eqs[j].color == omega_black)
3095 eq = omega_alloc_eqns (0, 1);
3096 omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3097 omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3098 omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3099 omega_free_eqns (eq, 1);
3105 /* Eliminate all EQ equations */
3106 for (e = pb->num_eqs - 1; e >= 0; e--)
3108 eqn eqn = &(pb->eqs[e]);
3111 if (dump_file && (dump_flags & TDF_DETAILS))
3112 fprintf (dump_file, "----\n");
3114 for (i = pb->num_vars; i > 0; i--)
3120 for (j = i - 1; j > 0; j--)
3124 /* i is the position of last nonzero coefficient,
3125 g is the coefficient of i,
3126 j is the position of next nonzero coefficient. */
3130 if (eqn->coef[0] % g != 0)
3131 return omega_problem_has_no_solution ();
3133 eqn->coef[0] = eqn->coef[0] / g;
3136 omega_do_elimination (pb, e, i);
3142 if (eqn->coef[0] != 0)
3143 return omega_problem_has_no_solution ();
3155 omega_do_elimination (pb, e, i);
3161 bool promotion_possible =
3162 (omega_safe_var_p (pb, j)
3163 && pb->safe_vars + 1 == i
3164 && !omega_eqn_is_red (eqn, desired_res)
3165 && !in_approximate_mode);
3167 if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3168 fprintf (dump_file, " Promotion possible\n");
3171 if (!omega_safe_var_p (pb, j))
3173 for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3174 g = gcd (abs (eqn->coef[j]), g);
3177 else if (!omega_safe_var_p (pb, i))
3182 for (; g != 1 && j > 0; j--)
3183 g = gcd (abs (eqn->coef[j]), g);
3187 if (eqn->coef[0] % g != 0)
3188 return omega_problem_has_no_solution ();
3190 for (j = 0; j <= pb->num_vars; j++)
3200 for (e2 = e - 1; e2 >= 0; e2--)
3201 if (pb->eqs[e2].coef[i])
3205 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3206 if (pb->geqs[e2].coef[i])
3210 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3211 if (pb->subs[e2].coef[i])
3216 bool change = false;
3218 if (dump_file && (dump_flags & TDF_DETAILS))
3220 fprintf (dump_file, "Ha! We own it! \n");
3221 omega_print_eq (dump_file, pb, eqn);
3222 fprintf (dump_file, " \n");
3228 for (j = i - 1; j >= 0; j--)
3230 int t = int_mod (eqn->coef[j], g);
3235 if (t != eqn->coef[j])
3244 if (dump_file && (dump_flags & TDF_DETAILS))
3245 fprintf (dump_file, "So what?\n");
3250 omega_name_wild_card (pb, i);
3252 if (dump_file && (dump_flags & TDF_DETAILS))
3254 omega_print_eq (dump_file, pb, eqn);
3255 fprintf (dump_file, " \n");
3264 if (promotion_possible)
3266 if (dump_file && (dump_flags & TDF_DETAILS))
3268 fprintf (dump_file, "promoting %s to safety\n",
3269 omega_variable_to_str (pb, i));
3270 omega_print_vars (dump_file, pb);
3275 if (!omega_wildcard_p (pb, i))
3276 omega_name_wild_card (pb, i);
3278 promotion_possible = false;
3283 if (g2 > 1 && !in_approximate_mode)
3285 if (pb->eqs[e].color == omega_red)
3287 if (dump_file && (dump_flags & TDF_DETAILS))
3288 fprintf (dump_file, "handling red equality\n");
3291 omega_do_elimination (pb, e, i);
3295 if (dump_file && (dump_flags & TDF_DETAILS))
3298 "adding equation to handle safe variable \n");
3299 omega_print_eq (dump_file, pb, eqn);
3300 fprintf (dump_file, "\n----\n");
3301 omega_print_problem (dump_file, pb);
3302 fprintf (dump_file, "\n----\n");
3303 fprintf (dump_file, "\n----\n");
3306 i = omega_add_new_wild_card (pb);
3308 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3309 omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3310 omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3312 for (j = pb->num_vars; j >= 0; j--)
3314 pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3316 if (2 * pb->eqs[e + 1].coef[j] >= g2)
3317 pb->eqs[e + 1].coef[j] -= g2;
3320 pb->eqs[e + 1].coef[i] = g2;
3323 if (dump_file && (dump_flags & TDF_DETAILS))
3324 omega_print_problem (dump_file, pb);
3333 /* Find variable to eliminate. */
3336 gcc_assert (in_approximate_mode);
3338 if (dump_file && (dump_flags & TDF_DETAILS))
3340 fprintf (dump_file, "non-exact elimination: ");
3341 omega_print_eq (dump_file, pb, eqn);
3342 fprintf (dump_file, "\n");
3343 omega_print_problem (dump_file, pb);
3346 for (i = pb->num_vars; i > sv; i--)
3347 if (pb->eqs[e].coef[i] != 0)
3351 for (i = pb->num_vars; i > sv; i--)
3352 if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3358 omega_do_elimination (pb, e, i);
3360 if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3362 fprintf (dump_file, "result of non-exact elimination:\n");
3363 omega_print_problem (dump_file, pb);
3368 int factor = (INT_MAX);
3371 if (dump_file && (dump_flags & TDF_DETAILS))
3372 fprintf (dump_file, "doing moding\n");
3374 for (i = pb->num_vars; i != sv; i--)
3375 if ((pb->eqs[e].coef[i] & 1) != 0)
3380 for (; i != sv; i--)
3381 if ((pb->eqs[e].coef[i] & 1) != 0)
3387 if (j != 0 && i == sv)
3389 omega_do_mod (pb, 2, e, j);
3395 for (i = pb->num_vars; i != sv; i--)
3396 if (pb->eqs[e].coef[i] != 0
3397 && factor > abs (pb->eqs[e].coef[i]) + 1)
3399 factor = abs (pb->eqs[e].coef[i]) + 1;
3405 if (dump_file && (dump_flags & TDF_DETAILS))
3406 fprintf (dump_file, "should not have happened\n");
3410 omega_do_mod (pb, factor, e, j);
3411 /* Go back and try this equation again. */
3418 return omega_unknown;
3421 /* Transform an inequation E to an equality, then solve DIFF problems
3422 based on PB, and only differing by the constant part that is
3423 diminished by one, trying to figure out which of the constants
3426 static enum omega_result
3427 parallel_splinter (omega_pb pb, int e, int diff,
3428 enum omega_result desired_res)
3430 omega_pb tmp_problem;
3433 if (dump_file && (dump_flags & TDF_DETAILS))
3435 fprintf (dump_file, "Using parallel splintering\n");
3436 omega_print_problem (dump_file, pb);
3439 tmp_problem = XNEW (struct omega_pb_d);
3440 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3443 for (i = 0; i <= diff; i++)
3445 omega_copy_problem (tmp_problem, pb);
3447 if (dump_file && (dump_flags & TDF_DETAILS))
3449 fprintf (dump_file, "Splinter # %i\n", i);
3450 omega_print_problem (dump_file, pb);
3453 if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3459 pb->eqs[0].coef[0]--;
3466 /* Helper function: solve equations one at a time. */
3468 static enum omega_result
3469 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3473 enum omega_result result;
3474 bool coupled_subscripts = false;
3475 bool smoothed = false;
3476 bool eliminate_again;
3477 bool tried_eliminating_redundant = false;
3479 if (desired_res != omega_simplify)
3487 gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3489 /* Verify that there are not too many inequalities. */
3490 gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3492 if (dump_file && (dump_flags & TDF_DETAILS))
3494 fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3495 desired_res, please_no_equalities_in_simplified_problems);
3496 omega_print_problem (dump_file, pb);
3497 fprintf (dump_file, "\n");
3500 n_vars = pb->num_vars;
3504 enum omega_eqn_color u_color = omega_black;
3505 enum omega_eqn_color l_color = omega_black;
3506 int upper_bound = pos_infinity;
3507 int lower_bound = neg_infinity;
3509 for (e = pb->num_geqs - 1; e >= 0; e--)
3511 int a = pb->geqs[e].coef[1];
3512 int c = pb->geqs[e].coef[0];
3514 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3518 return omega_problem_has_no_solution ();
3525 if (lower_bound < -c
3526 || (lower_bound == -c
3527 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3530 l_color = pb->geqs[e].color;
3536 c = int_div (c, -a);
3539 || (upper_bound == c
3540 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3543 u_color = pb->geqs[e].color;
3548 if (dump_file && (dump_flags & TDF_DETAILS))
3550 fprintf (dump_file, "upper bound = %d\n", upper_bound);
3551 fprintf (dump_file, "lower bound = %d\n", lower_bound);
3554 if (lower_bound > upper_bound)
3555 return omega_problem_has_no_solution ();
3557 if (desired_res == omega_simplify)
3560 if (pb->safe_vars == 1)
3563 if (lower_bound == upper_bound
3564 && u_color == omega_black
3565 && l_color == omega_black)
3567 pb->eqs[0].coef[0] = -lower_bound;
3568 pb->eqs[0].coef[1] = 1;
3569 pb->eqs[0].color = omega_black;
3571 return omega_solve_problem (pb, desired_res);
3575 if (lower_bound > neg_infinity)
3577 pb->geqs[0].coef[0] = -lower_bound;
3578 pb->geqs[0].coef[1] = 1;
3579 pb->geqs[0].key = 1;
3580 pb->geqs[0].color = l_color;
3581 pb->geqs[0].touched = 0;
3585 if (upper_bound < pos_infinity)
3587 pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3588 pb->geqs[pb->num_geqs].coef[1] = -1;
3589 pb->geqs[pb->num_geqs].key = -1;
3590 pb->geqs[pb->num_geqs].color = u_color;
3591 pb->geqs[pb->num_geqs].touched = 0;
3599 omega_problem_reduced (pb);
3603 if (original_problem != no_problem
3604 && l_color == omega_black
3605 && u_color == omega_black
3607 && lower_bound == upper_bound)
3609 pb->eqs[0].coef[0] = -lower_bound;
3610 pb->eqs[0].coef[1] = 1;
3612 adding_equality_constraint (pb, 0);
3618 if (!pb->variables_freed)
3620 pb->variables_freed = true;
3622 if (desired_res != omega_simplify)
3623 omega_free_eliminations (pb, 0);
3625 omega_free_eliminations (pb, pb->safe_vars);
3627 n_vars = pb->num_vars;
3633 switch (normalize_omega_problem (pb))
3635 case normalize_false:
3639 case normalize_coupled:
3640 coupled_subscripts = true;
3643 case normalize_uncoupled:
3644 coupled_subscripts = false;
3651 n_vars = pb->num_vars;
3653 if (dump_file && (dump_flags & TDF_DETAILS))
3655 fprintf (dump_file, "\nafter normalization:\n");
3656 omega_print_problem (dump_file, pb);
3657 fprintf (dump_file, "\n");
3658 fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3662 int parallel_difference = INT_MAX;
3663 int best_parallel_eqn = -1;
3664 int minC, maxC, minCj = 0;
3665 int lower_bound_count = 0;
3667 bool possible_easy_int_solution;
3668 int max_splinters = 1;
3670 bool lucky_exact = false;
3671 int best = (INT_MAX);
3672 int j = 0, jLe = 0, jLowerBoundCount = 0;
3675 eliminate_again = false;
3677 if (pb->num_eqs > 0)
3678 return omega_solve_problem (pb, desired_res);
3680 if (!coupled_subscripts)
3682 if (pb->safe_vars == 0)
3685 for (e = pb->num_geqs - 1; e >= 0; e--)
3686 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3687 omega_delete_geq (pb, e, n_vars);
3689 pb->num_vars = pb->safe_vars;
3691 if (desired_res == omega_simplify)
3693 omega_problem_reduced (pb);
3700 if (desired_res != omega_simplify)
3705 if (pb->num_geqs == 0)
3707 if (desired_res == omega_simplify)
3709 pb->num_vars = pb->safe_vars;
3710 omega_problem_reduced (pb);
3716 if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3718 omega_problem_reduced (pb);
3722 if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3723 || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3725 if (dump_file && (dump_flags & TDF_DETAILS))
3727 "TOO MANY EQUATIONS; "
3728 "%d equations, %d variables, "
3729 "ELIMINATING REDUNDANT ONES\n",
3730 pb->num_geqs, n_vars);
3732 if (!omega_eliminate_redundant (pb, false))
3735 n_vars = pb->num_vars;
3737 if (pb->num_eqs > 0)
3738 return omega_solve_problem (pb, desired_res);
3740 if (dump_file && (dump_flags & TDF_DETAILS))
3741 fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3744 if (desired_res != omega_simplify)
3749 for (i = n_vars; i != fv; i--)
3755 int upper_bound_count = 0;
3757 lower_bound_count = 0;
3760 for (e = pb->num_geqs - 1; e >= 0; e--)
3761 if (pb->geqs[e].coef[i] < 0)
3763 minC = MIN (minC, pb->geqs[e].coef[i]);
3764 upper_bound_count++;
3765 if (pb->geqs[e].coef[i] < -1)
3773 else if (pb->geqs[e].coef[i] > 0)
3775 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3776 lower_bound_count++;
3778 if (pb->geqs[e].coef[i] > 1)
3787 if (lower_bound_count == 0
3788 || upper_bound_count == 0)
3790 lower_bound_count = 0;
3794 if (ub >= 0 && lb >= 0
3795 && pb->geqs[lb].key == -pb->geqs[ub].key)
3797 int Lc = pb->geqs[lb].coef[i];
3798 int Uc = -pb->geqs[ub].coef[i];
3800 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3801 lucky = (diff >= (Uc - 1) * (Lc - 1));
3807 || in_approximate_mode)
3809 score = upper_bound_count * lower_bound_count;
3811 if (dump_file && (dump_flags & TDF_DETAILS))
3813 "For %s, exact, score = %d*%d, range = %d ... %d,"
3814 "\nlucky = %d, in_approximate_mode=%d \n",
3815 omega_variable_to_str (pb, i),
3817 lower_bound_count, minC, maxC, lucky,
3818 in_approximate_mode);
3828 jLowerBoundCount = lower_bound_count;
3830 lucky_exact = lucky;
3837 if (dump_file && (dump_flags & TDF_DETAILS))
3839 "For %s, non-exact, score = %d*%d,"
3840 "range = %d ... %d \n",
3841 omega_variable_to_str (pb, i),
3843 lower_bound_count, minC, maxC);
3845 score = maxC - minC;
3853 jLowerBoundCount = lower_bound_count;
3858 if (lower_bound_count == 0)
3860 omega_free_eliminations (pb, pb->safe_vars);
3861 n_vars = pb->num_vars;
3862 eliminate_again = true;
3869 lower_bound_count = jLowerBoundCount;
3871 for (e = pb->num_geqs - 1; e >= 0; e--)
3872 if (pb->geqs[e].coef[i] > 0)
3874 if (pb->geqs[e].coef[i] == -minC)
3875 max_splinters += -minC - 1;
3878 pos_mul_hwi ((pb->geqs[e].coef[i] - 1),
3879 (-minC - 1)) / (-minC) + 1;
3883 /* Trying to produce exact elimination by finding redundant
3885 if (!exact && !tried_eliminating_redundant)
3887 omega_eliminate_redundant (pb, false);
3888 tried_eliminating_redundant = true;
3889 eliminate_again = true;
3892 tried_eliminating_redundant = false;
3895 if (return_single_result && desired_res == omega_simplify && !exact)
3897 omega_problem_reduced (pb);
3901 /* #ifndef Omega3 */
3902 /* Trying to produce exact elimination by finding redundant
3904 if (!exact && !tried_eliminating_redundant)
3906 omega_eliminate_redundant (pb, false);
3907 tried_eliminating_redundant = true;
3910 tried_eliminating_redundant = false;
3917 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3918 if (pb->geqs[e1].color == omega_black)
3919 for (e2 = e1 - 1; e2 >= 0; e2--)
3920 if (pb->geqs[e2].color == omega_black
3921 && pb->geqs[e1].key == -pb->geqs[e2].key
3922 && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3923 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3924 / 2 < parallel_difference))
3926 parallel_difference =
3927 (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3928 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3930 best_parallel_eqn = e1;
3933 if (dump_file && (dump_flags & TDF_DETAILS)
3934 && best_parallel_eqn >= 0)
3937 "Possible parallel projection, diff = %d, in ",
3938 parallel_difference);
3939 omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3940 fprintf (dump_file, "\n");
3941 omega_print_problem (dump_file, pb);
3945 if (dump_file && (dump_flags & TDF_DETAILS))
3947 fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
3948 omega_variable_to_str (pb, i), i, minC,
3950 omega_print_problem (dump_file, pb);
3953 fprintf (dump_file, "(a lucky exact elimination)\n");
3956 fprintf (dump_file, "(an exact elimination)\n");
3958 fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
3961 gcc_assert (max_splinters >= 1);
3963 if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
3964 && parallel_difference <= max_splinters)
3965 return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
3973 int j = pb->num_vars;
3975 if (dump_file && (dump_flags & TDF_DETAILS))
3977 fprintf (dump_file, "Swapping %d and %d\n", i, j);
3978 omega_print_problem (dump_file, pb);
3981 swap (&pb->var[i], &pb->var[j]);
3983 for (e = pb->num_geqs - 1; e >= 0; e--)
3984 if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
3986 pb->geqs[e].touched = 1;
3987 t = pb->geqs[e].coef[i];
3988 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
3989 pb->geqs[e].coef[j] = t;
3992 for (e = pb->num_subs - 1; e >= 0; e--)
3993 if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
3995 t = pb->subs[e].coef[i];
3996 pb->subs[e].coef[i] = pb->subs[e].coef[j];
3997 pb->subs[e].coef[j] = t;
4000 if (dump_file && (dump_flags & TDF_DETAILS))
4002 fprintf (dump_file, "Swapping complete \n");
4003 omega_print_problem (dump_file, pb);
4004 fprintf (dump_file, "\n");
4010 else if (dump_file && (dump_flags & TDF_DETAILS))
4012 fprintf (dump_file, "No swap needed\n");
4013 omega_print_problem (dump_file, pb);
4017 n_vars = pb->num_vars;
4023 int upper_bound = pos_infinity;
4024 int lower_bound = neg_infinity;
4025 enum omega_eqn_color ub_color = omega_black;
4026 enum omega_eqn_color lb_color = omega_black;
4027 int topeqn = pb->num_geqs - 1;
4028 int Lc = pb->geqs[Le].coef[i];
4030 for (Le = topeqn; Le >= 0; Le--)
4031 if ((Lc = pb->geqs[Le].coef[i]) == 0)
4033 if (pb->geqs[Le].coef[1] == 1)
4035 int constantTerm = -pb->geqs[Le].coef[0];
4037 if (constantTerm > lower_bound ||
4038 (constantTerm == lower_bound &&
4039 !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
4041 lower_bound = constantTerm;
4042 lb_color = pb->geqs[Le].color;
4045 if (dump_file && (dump_flags & TDF_DETAILS))
4047 if (pb->geqs[Le].color == omega_black)
4048 fprintf (dump_file, " :::=> %s >= %d\n",
4049 omega_variable_to_str (pb, 1),
4053 " :::=> [%s >= %d]\n",
4054 omega_variable_to_str (pb, 1),
4060 int constantTerm = pb->geqs[Le].coef[0];
4061 if (constantTerm < upper_bound ||
4062 (constantTerm == upper_bound
4063 && !omega_eqn_is_red (&pb->geqs[Le],
4066 upper_bound = constantTerm;
4067 ub_color = pb->geqs[Le].color;
4070 if (dump_file && (dump_flags & TDF_DETAILS))
4072 if (pb->geqs[Le].color == omega_black)
4073 fprintf (dump_file, " :::=> %s <= %d\n",
4074 omega_variable_to_str (pb, 1),
4078 " :::=> [%s <= %d]\n",
4079 omega_variable_to_str (pb, 1),
4085 for (Ue = topeqn; Ue >= 0; Ue--)
4086 if (pb->geqs[Ue].coef[i] < 0
4087 && pb->geqs[Le].key != -pb->geqs[Ue].key)
4089 int Uc = -pb->geqs[Ue].coef[i];
4090 int coefficient = pb->geqs[Ue].coef[1] * Lc
4091 + pb->geqs[Le].coef[1] * Uc;
4092 int constantTerm = pb->geqs[Ue].coef[0] * Lc
4093 + pb->geqs[Le].coef[0] * Uc;
4095 if (dump_file && (dump_flags & TDF_DETAILS))
4097 omega_print_geq_extra (dump_file, pb,
4099 fprintf (dump_file, "\n");
4100 omega_print_geq_extra (dump_file, pb,
4102 fprintf (dump_file, "\n");
4105 if (coefficient > 0)
4107 constantTerm = -int_div (constantTerm, coefficient);
4109 if (constantTerm > lower_bound
4110 || (constantTerm == lower_bound
4111 && (desired_res != omega_simplify
4112 || (pb->geqs[Ue].color == omega_black
4113 && pb->geqs[Le].color == omega_black))))
4115 lower_bound = constantTerm;
4116 lb_color = (pb->geqs[Ue].color == omega_red
4117 || pb->geqs[Le].color == omega_red)
4118 ? omega_red : omega_black;
4121 if (dump_file && (dump_flags & TDF_DETAILS))
4123 if (pb->geqs[Ue].color == omega_red
4124 || pb->geqs[Le].color == omega_red)
4126 " ::=> [%s >= %d]\n",
4127 omega_variable_to_str (pb, 1),
4132 omega_variable_to_str (pb, 1),
4138 constantTerm = int_div (constantTerm, -coefficient);
4139 if (constantTerm < upper_bound
4140 || (constantTerm == upper_bound
4141 && pb->geqs[Ue].color == omega_black
4142 && pb->geqs[Le].color == omega_black))
4144 upper_bound = constantTerm;
4145 ub_color = (pb->geqs[Ue].color == omega_red
4146 || pb->geqs[Le].color == omega_red)
4147 ? omega_red : omega_black;
4151 && (dump_flags & TDF_DETAILS))
4153 if (pb->geqs[Ue].color == omega_red
4154 || pb->geqs[Le].color == omega_red)
4156 " ::=> [%s <= %d]\n",
4157 omega_variable_to_str (pb, 1),
4162 omega_variable_to_str (pb, 1),
4170 if (dump_file && (dump_flags & TDF_DETAILS))
4172 " therefore, %c%d <= %c%s%c <= %d%c\n",
4173 lb_color == omega_red ? '[' : ' ', lower_bound,
4174 (lb_color == omega_red && ub_color == omega_black)
4176 omega_variable_to_str (pb, 1),
4177 (lb_color == omega_black && ub_color == omega_red)
4179 upper_bound, ub_color == omega_red ? ']' : ' ');
4181 if (lower_bound > upper_bound)
4184 if (pb->safe_vars == 1)
4186 if (upper_bound == lower_bound
4187 && !(ub_color == omega_red || lb_color == omega_red)
4188 && !please_no_equalities_in_simplified_problems)
4191 pb->eqs[0].coef[1] = -1;
4192 pb->eqs[0].coef[0] = upper_bound;
4194 if (ub_color == omega_red
4195 || lb_color == omega_red)
4196 pb->eqs[0].color = omega_red;
4198 if (desired_res == omega_simplify
4199 && pb->eqs[0].color == omega_black)
4200 return omega_solve_problem (pb, desired_res);
4203 if (upper_bound != pos_infinity)
4205 pb->geqs[0].coef[1] = -1;
4206 pb->geqs[0].coef[0] = upper_bound;
4207 pb->geqs[0].color = ub_color;
4208 pb->geqs[0].key = -1;
4209 pb->geqs[0].touched = 0;
4213 if (lower_bound != neg_infinity)
4215 pb->geqs[pb->num_geqs].coef[1] = 1;
4216 pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
4217 pb->geqs[pb->num_geqs].color = lb_color;
4218 pb->geqs[pb->num_geqs].key = 1;
4219 pb->geqs[pb->num_geqs].touched = 0;
4224 if (desired_res == omega_simplify)
4226 omega_problem_reduced (pb);
4232 && (desired_res != omega_simplify
4233 || (lb_color == omega_black
4234 && ub_color == omega_black))
4235 && original_problem != no_problem
4236 && lower_bound == upper_bound)
4238 for (i = original_problem->num_vars; i >= 0; i--)
4239 if (original_problem->var[i] == pb->var[1])
4245 e = original_problem->num_eqs++;
4246 omega_init_eqn_zero (&original_problem->eqs[e],
4247 original_problem->num_vars);
4248 original_problem->eqs[e].coef[i] = -1;
4249 original_problem->eqs[e].coef[0] = upper_bound;
4251 if (dump_file && (dump_flags & TDF_DETAILS))
4254 "adding equality %d to outer problem\n", e);
4255 omega_print_problem (dump_file, original_problem);
4262 eliminate_again = true;
4264 if (lower_bound_count == 1)
4266 eqn lbeqn = omega_alloc_eqns (0, 1);
4267 int Lc = pb->geqs[Le].coef[i];
4269 if (dump_file && (dump_flags & TDF_DETAILS))
4270 fprintf (dump_file, "an inplace elimination\n");
4272 omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
4273 omega_delete_geq_extra (pb, Le, n_vars + 1);
4275 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4276 if (pb->geqs[Ue].coef[i] < 0)
4278 if (lbeqn->key == -pb->geqs[Ue].key)
4279 omega_delete_geq_extra (pb, Ue, n_vars + 1);
4283 int Uc = -pb->geqs[Ue].coef[i];
4284 pb->geqs[Ue].touched = 1;
4285 eliminate_again = false;
4287 if (lbeqn->color == omega_red)
4288 pb->geqs[Ue].color = omega_red;
4290 for (k = 0; k <= n_vars; k++)
4291 pb->geqs[Ue].coef[k] =
4292 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4293 mul_hwi (lbeqn->coef[k], Uc);
4295 if (dump_file && (dump_flags & TDF_DETAILS))
4297 omega_print_geq (dump_file, pb,
4299 fprintf (dump_file, "\n");
4304 omega_free_eqns (lbeqn, 1);
4309 int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
4310 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
4312 int top_eqn = pb->num_geqs - 1;
4313 lower_bound_count--;
4315 if (dump_file && (dump_flags & TDF_DETAILS))
4316 fprintf (dump_file, "lower bound count = %d\n",
4319 for (Le = top_eqn; Le >= 0; Le--)
4320 if (pb->geqs[Le].coef[i] > 0)
4322 int Lc = pb->geqs[Le].coef[i];
4323 for (Ue = top_eqn; Ue >= 0; Ue--)
4324 if (pb->geqs[Ue].coef[i] < 0)
4326 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4329 int Uc = -pb->geqs[Ue].coef[i];
4332 e2 = pb->num_geqs++;
4334 e2 = dead_eqns[--num_dead];
4336 gcc_assert (e2 < OMEGA_MAX_GEQS);
4338 if (dump_file && (dump_flags & TDF_DETAILS))
4341 "Le = %d, Ue = %d, gen = %d\n",
4343 omega_print_geq_extra (dump_file, pb,
4345 fprintf (dump_file, "\n");
4346 omega_print_geq_extra (dump_file, pb,
4348 fprintf (dump_file, "\n");
4351 eliminate_again = false;
4353 for (k = n_vars; k >= 0; k--)
4354 pb->geqs[e2].coef[k] =
4355 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4356 mul_hwi (pb->geqs[Le].coef[k], Uc);
4358 pb->geqs[e2].coef[n_vars + 1] = 0;
4359 pb->geqs[e2].touched = 1;
4361 if (pb->geqs[Ue].color == omega_red
4362 || pb->geqs[Le].color == omega_red)
4363 pb->geqs[e2].color = omega_red;
4365 pb->geqs[e2].color = omega_black;
4367 if (dump_file && (dump_flags & TDF_DETAILS))
4369 omega_print_geq (dump_file, pb,
4371 fprintf (dump_file, "\n");
4375 if (lower_bound_count == 0)
4377 dead_eqns[num_dead++] = Ue;
4379 if (dump_file && (dump_flags & TDF_DETAILS))
4380 fprintf (dump_file, "Killed %d\n", Ue);
4384 lower_bound_count--;
4385 dead_eqns[num_dead++] = Le;
4387 if (dump_file && (dump_flags & TDF_DETAILS))
4388 fprintf (dump_file, "Killed %d\n", Le);
4391 for (e = pb->num_geqs - 1; e >= 0; e--)
4394 while (num_dead > 0)
4395 is_dead[dead_eqns[--num_dead]] = true;
4397 for (e = pb->num_geqs - 1; e >= 0; e--)
4399 omega_delete_geq_extra (pb, e, n_vars + 1);
4410 rS = omega_alloc_problem (0, 0);
4411 iS = omega_alloc_problem (0, 0);
4413 possible_easy_int_solution = true;
4415 for (e = 0; e < pb->num_geqs; e++)
4416 if (pb->geqs[e].coef[i] == 0)
4418 omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
4420 omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
4423 if (dump_file && (dump_flags & TDF_DETAILS))
4426 fprintf (dump_file, "Copying (%d, %d): ", i,
4427 pb->geqs[e].coef[i]);
4428 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
4429 fprintf (dump_file, "\n");
4430 for (t = 0; t <= n_vars + 1; t++)
4431 fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
4432 fprintf (dump_file, "\n");
4436 gcc_assert (e2 < OMEGA_MAX_GEQS);
4439 for (Le = pb->num_geqs - 1; Le >= 0; Le--)
4440 if (pb->geqs[Le].coef[i] > 0)
4441 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4442 if (pb->geqs[Ue].coef[i] < 0)
4445 int Lc = pb->geqs[Le].coef[i];
4446 int Uc = -pb->geqs[Ue].coef[i];
4448 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4451 rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
4453 if (dump_file && (dump_flags & TDF_DETAILS))
4455 fprintf (dump_file, "---\n");
4457 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4458 Le, Lc, Ue, Uc, e2);
4459 omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
4460 fprintf (dump_file, "\n");
4461 omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
4462 fprintf (dump_file, "\n");
4467 for (k = n_vars; k >= 0; k--)
4468 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4469 pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
4471 iS->geqs[e2].coef[0] -= (Uc - 1);
4475 for (k = n_vars; k >= 0; k--)
4476 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4477 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4478 mul_hwi (pb->geqs[Le].coef[k], Uc);
4480 iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
4483 if (pb->geqs[Ue].color == omega_red
4484 || pb->geqs[Le].color == omega_red)
4485 iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
4487 iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
4489 if (dump_file && (dump_flags & TDF_DETAILS))
4491 omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
4492 fprintf (dump_file, "\n");
4496 gcc_assert (e2 < OMEGA_MAX_GEQS);
4498 else if (pb->geqs[Ue].coef[0] * Lc +
4499 pb->geqs[Le].coef[0] * Uc -
4500 (Uc - 1) * (Lc - 1) < 0)
4501 possible_easy_int_solution = false;
4504 iS->variables_initialized = rS->variables_initialized = true;
4505 iS->num_vars = rS->num_vars = pb->num_vars;
4506 iS->num_geqs = rS->num_geqs = e2;
4507 iS->num_eqs = rS->num_eqs = 0;
4508 iS->num_subs = rS->num_subs = pb->num_subs;
4509 iS->safe_vars = rS->safe_vars = pb->safe_vars;
4511 for (e = n_vars; e >= 0; e--)
4512 rS->var[e] = pb->var[e];
4514 for (e = n_vars; e >= 0; e--)
4515 iS->var[e] = pb->var[e];
4517 for (e = pb->num_subs - 1; e >= 0; e--)
4519 omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
4520 omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
4524 n_vars = pb->num_vars;
4526 if (desired_res != omega_true)
4528 if (original_problem == no_problem)
4530 original_problem = pb;
4531 result = omega_solve_geq (rS, omega_false);
4532 original_problem = no_problem;
4535 result = omega_solve_geq (rS, omega_false);
4537 if (result == omega_false)
4544 if (pb->num_eqs > 0)
4546 /* An equality constraint must have been found */
4549 return omega_solve_problem (pb, desired_res);
4553 if (desired_res != omega_false)
4556 int lower_bounds = 0;
4557 int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
4559 if (possible_easy_int_solution)
4562 result = omega_solve_geq (iS, desired_res);
4565 if (result != omega_false)
4574 if (!exact && best_parallel_eqn >= 0
4575 && parallel_difference <= max_splinters)
4580 return parallel_splinter (pb, best_parallel_eqn,
4581 parallel_difference,
4585 if (dump_file && (dump_flags & TDF_DETAILS))
4586 fprintf (dump_file, "have to do exact analysis\n");
4590 for (e = 0; e < pb->num_geqs; e++)
4591 if (pb->geqs[e].coef[i] > 1)
4592 lower_bound[lower_bounds++] = e;
4594 /* Sort array LOWER_BOUND. */
4595 for (j = 0; j < lower_bounds; j++)
4597 int k, smallest = j;
4599 for (k = j + 1; k < lower_bounds; k++)
4600 if (pb->geqs[lower_bound[smallest]].coef[i] >
4601 pb->geqs[lower_bound[k]].coef[i])
4604 k = lower_bound[smallest];
4605 lower_bound[smallest] = lower_bound[j];
4609 if (dump_file && (dump_flags & TDF_DETAILS))
4611 fprintf (dump_file, "lower bound coefficients = ");
4613 for (j = 0; j < lower_bounds; j++)
4614 fprintf (dump_file, " %d",
4615 pb->geqs[lower_bound[j]].coef[i]);
4617 fprintf (dump_file, "\n");
4620 for (j = 0; j < lower_bounds; j++)
4624 int worst_lower_bound_constant = -minC;
4627 max_incr = (((pb->geqs[e].coef[i] - 1) *
4628 (worst_lower_bound_constant - 1) - 1)
4629 / worst_lower_bound_constant);
4630 /* max_incr += 2; */
4632 if (dump_file && (dump_flags & TDF_DETAILS))
4634 fprintf (dump_file, "for equation ");
4635 omega_print_geq (dump_file, pb, &pb->geqs[e]);
4637 "\ntry decrements from 0 to %d\n",
4639 omega_print_problem (dump_file, pb);
4642 if (max_incr > 50 && !smoothed
4643 && smooth_weird_equations (pb))
4649 goto solve_geq_start;
4652 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4654 pb->eqs[0].color = omega_black;
4655 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4656 pb->geqs[e].touched = 1;
4659 for (c = max_incr; c >= 0; c--)
4661 if (dump_file && (dump_flags & TDF_DETAILS))
4664 "trying next decrement of %d\n",
4666 omega_print_problem (dump_file, pb);
4669 omega_copy_problem (rS, pb);
4671 if (dump_file && (dump_flags & TDF_DETAILS))
4672 omega_print_problem (dump_file, rS);
4674 result = omega_solve_problem (rS, desired_res);
4676 if (result == omega_true)
4685 pb->eqs[0].coef[0]--;
4688 if (j + 1 < lower_bounds)
4691 omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4693 pb->geqs[e].touched = 1;
4694 pb->geqs[e].color = omega_black;
4695 omega_copy_problem (rS, pb);
4697 if (dump_file && (dump_flags & TDF_DETAILS))
4699 "exhausted lower bound, "
4700 "checking if still feasible ");
4702 result = omega_solve_problem (rS, omega_false);
4704 if (result == omega_false)
4709 if (dump_file && (dump_flags & TDF_DETAILS))
4710 fprintf (dump_file, "fall-off the end\n");
4722 return omega_unknown;
4723 } while (eliminate_again);
4727 /* Because the omega solver is recursive, this counter limits the
4729 static int omega_solve_depth = 0;
4731 /* Return omega_true when the problem PB has a solution following the
4735 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4737 enum omega_result result;
4739 gcc_assert (pb->num_vars >= pb->safe_vars);
4740 omega_solve_depth++;
4742 if (desired_res != omega_simplify)
4745 if (omega_solve_depth > 50)
4747 if (dump_file && (dump_flags & TDF_DETAILS))
4750 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4751 omega_solve_depth, in_approximate_mode);
4752 omega_print_problem (dump_file, pb);
4757 if (omega_solve_eq (pb, desired_res) == omega_false)
4759 omega_solve_depth--;
4763 if (in_approximate_mode && !pb->num_geqs)
4765 result = omega_true;
4766 pb->num_vars = pb->safe_vars;
4767 omega_problem_reduced (pb);
4770 result = omega_solve_geq (pb, desired_res);
4772 omega_solve_depth--;
4774 if (!omega_reduce_with_subs)
4776 resurrect_subs (pb);
4777 gcc_assert (please_no_equalities_in_simplified_problems
4778 || !result || pb->num_subs == 0);
4784 /* Return true if red equations constrain the set of possible solutions.
4785 We assume that there are solutions to the black equations by
4786 themselves, so if there is no solution to the combined problem, we
4790 omega_problem_has_red_equations (omega_pb pb)
4796 if (dump_file && (dump_flags & TDF_DETAILS))
4798 fprintf (dump_file, "Checking for red equations:\n");
4799 omega_print_problem (dump_file, pb);
4802 please_no_equalities_in_simplified_problems++;
4805 if (omega_single_result)
4806 return_single_result++;
4808 create_color = true;
4809 result = (omega_simplify_problem (pb) == omega_false);
4811 if (omega_single_result)
4812 return_single_result--;
4815 please_no_equalities_in_simplified_problems--;
4819 if (dump_file && (dump_flags & TDF_DETAILS))
4820 fprintf (dump_file, "Gist is FALSE\n");
4825 pb->eqs[0].color = omega_red;
4827 for (i = pb->num_vars; i > 0; i--)
4828 pb->eqs[0].coef[i] = 0;
4830 pb->eqs[0].coef[0] = 1;
4834 free_red_eliminations (pb);
4835 gcc_assert (pb->num_eqs == 0);
4837 for (e = pb->num_geqs - 1; e >= 0; e--)
4838 if (pb->geqs[e].color == omega_red)
4844 for (i = pb->safe_vars; i >= 1; i--)
4849 for (e = pb->num_geqs - 1; e >= 0; e--)
4851 if (pb->geqs[e].coef[i])
4853 if (pb->geqs[e].coef[i] > 0)
4854 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4857 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4861 if (ub == 2 || lb == 2)
4864 if (dump_file && (dump_flags & TDF_DETAILS))
4865 fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4867 if (!omega_reduce_with_subs)
4869 resurrect_subs (pb);
4870 gcc_assert (pb->num_subs == 0);
4878 if (dump_file && (dump_flags & TDF_DETAILS))
4880 "*** Doing potentially expensive elimination tests "
4881 "for red equations\n");
4883 please_no_equalities_in_simplified_problems++;
4884 omega_eliminate_red (pb, true);
4885 please_no_equalities_in_simplified_problems--;
4888 gcc_assert (pb->num_eqs == 0);
4890 for (e = pb->num_geqs - 1; e >= 0; e--)
4891 if (pb->geqs[e].color == omega_red)
4894 if (dump_file && (dump_flags & TDF_DETAILS))
4898 "******************** Redundant Red Equations eliminated!!\n");
4901 "******************** Red Equations remain\n");
4903 omega_print_problem (dump_file, pb);
4906 if (!omega_reduce_with_subs)
4908 normalize_return_type r;
4910 resurrect_subs (pb);
4911 r = normalize_omega_problem (pb);
4912 gcc_assert (r != normalize_false);
4915 cleanout_wildcards (pb);
4916 gcc_assert (pb->num_subs == 0);
4922 /* Calls omega_simplify_problem in approximate mode. */
4925 omega_simplify_approximate (omega_pb pb)
4927 enum omega_result result;
4929 if (dump_file && (dump_flags & TDF_DETAILS))
4930 fprintf (dump_file, "(Entering approximate mode\n");
4932 in_approximate_mode = true;
4933 result = omega_simplify_problem (pb);
4934 in_approximate_mode = false;
4936 gcc_assert (pb->num_vars == pb->safe_vars);
4937 if (!omega_reduce_with_subs)
4938 gcc_assert (pb->num_subs == 0);
4940 if (dump_file && (dump_flags & TDF_DETAILS))
4941 fprintf (dump_file, "Leaving approximate mode)\n");
4947 /* Simplifies problem PB by eliminating redundant constraints and
4948 reducing the constraints system to a minimal form. Returns
4949 omega_true when the problem was successfully reduced, omega_unknown
4950 when the solver is unable to determine an answer. */
4953 omega_simplify_problem (omega_pb pb)
4957 omega_found_reduction = omega_false;
4959 if (!pb->variables_initialized)
4960 omega_initialize_variables (pb);
4962 if (next_key * 3 > MAX_KEYS)
4967 next_key = OMEGA_MAX_VARS + 1;
4969 for (e = pb->num_geqs - 1; e >= 0; e--)
4970 pb->geqs[e].touched = 1;
4972 for (i = 0; i < HASH_TABLE_SIZE; i++)
4973 hash_master[i].touched = -1;
4975 pb->hash_version = hash_version;
4978 else if (pb->hash_version != hash_version)
4982 for (e = pb->num_geqs - 1; e >= 0; e--)
4983 pb->geqs[e].touched = 1;
4985 pb->hash_version = hash_version;
4988 if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
4989 omega_free_eliminations (pb, pb->safe_vars);
4991 if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
4993 omega_found_reduction = omega_solve_problem (pb, omega_unknown);
4995 if (omega_found_reduction != omega_false
4996 && !return_single_result)
5000 (*omega_when_reduced) (pb);
5003 return omega_found_reduction;
5006 omega_solve_problem (pb, omega_simplify);
5008 if (omega_found_reduction != omega_false)
5010 for (i = 1; omega_safe_var_p (pb, i); i++)
5011 pb->forwarding_address[pb->var[i]] = i;
5013 for (i = 0; i < pb->num_subs; i++)
5014 pb->forwarding_address[pb->subs[i].key] = -i - 1;
5017 if (!omega_reduce_with_subs)
5018 gcc_assert (please_no_equalities_in_simplified_problems
5019 || omega_found_reduction == omega_false
5020 || pb->num_subs == 0);
5022 return omega_found_reduction;
5025 /* Make variable VAR unprotected: it then can be eliminated. */
5028 omega_unprotect_variable (omega_pb pb, int var)
5031 idx = pb->forwarding_address[var];
5038 if (idx < pb->num_subs)
5040 omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5042 pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5047 int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5050 for (e = pb->num_subs - 1; e >= 0; e--)
5051 bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5053 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5054 if (bring_to_life[e2])
5059 if (pb->safe_vars < pb->num_vars)
5061 for (e = pb->num_geqs - 1; e >= 0; e--)
5063 pb->geqs[e].coef[pb->num_vars] =
5064 pb->geqs[e].coef[pb->safe_vars];
5066 pb->geqs[e].coef[pb->safe_vars] = 0;
5069 for (e = pb->num_eqs - 1; e >= 0; e--)
5071 pb->eqs[e].coef[pb->num_vars] =
5072 pb->eqs[e].coef[pb->safe_vars];
5074 pb->eqs[e].coef[pb->safe_vars] = 0;
5077 for (e = pb->num_subs - 1; e >= 0; e--)
5079 pb->subs[e].coef[pb->num_vars] =
5080 pb->subs[e].coef[pb->safe_vars];
5082 pb->subs[e].coef[pb->safe_vars] = 0;
5085 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5086 pb->forwarding_address[pb->var[pb->num_vars]] =
5091 for (e = pb->num_geqs - 1; e >= 0; e--)
5092 pb->geqs[e].coef[pb->safe_vars] = 0;
5094 for (e = pb->num_eqs - 1; e >= 0; e--)
5095 pb->eqs[e].coef[pb->safe_vars] = 0;
5097 for (e = pb->num_subs - 1; e >= 0; e--)
5098 pb->subs[e].coef[pb->safe_vars] = 0;
5101 pb->var[pb->safe_vars] = pb->subs[e2].key;
5102 pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5104 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5106 pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5107 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5109 if (e2 < pb->num_subs - 1)
5110 omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5116 omega_unprotect_1 (pb, &idx, NULL);
5117 free (bring_to_life);
5120 chain_unprotect (pb);
5123 /* Unprotects VAR and simplifies PB. */
5126 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5129 int n_vars = pb->num_vars;
5131 int k = pb->forwarding_address[var];
5140 omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5142 for (j = 0; j <= n_vars; j++)
5143 pb->geqs[e].coef[j] *= sign;
5145 pb->geqs[e].coef[0]--;
5146 pb->geqs[e].touched = 1;
5147 pb->geqs[e].color = color;
5152 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5153 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5154 pb->eqs[e].color = color;
5160 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5161 pb->geqs[e].coef[k] = sign;
5162 pb->geqs[e].coef[0] = -1;
5163 pb->geqs[e].touched = 1;
5164 pb->geqs[e].color = color;
5169 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5170 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5171 pb->eqs[e].coef[k] = 1;
5172 pb->eqs[e].color = color;
5175 omega_unprotect_variable (pb, var);
5176 return omega_simplify_problem (pb);
5179 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5182 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5186 int k = pb->forwarding_address[var];
5192 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5193 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5194 pb->eqs[e].coef[0] -= value;
5199 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5200 pb->eqs[e].coef[k] = 1;
5201 pb->eqs[e].coef[0] = -value;
5204 pb->eqs[e].color = color;
5207 /* Return false when the upper and lower bounds are not coupled.
5208 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5212 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5214 int n_vars = pb->num_vars;
5217 bool coupled = false;
5219 *lower_bound = neg_infinity;
5220 *upper_bound = pos_infinity;
5221 i = pb->forwarding_address[i];
5227 for (j = 1; j <= n_vars; j++)
5228 if (pb->subs[i].coef[j] != 0)
5231 *upper_bound = *lower_bound = pb->subs[i].coef[0];
5235 for (e = pb->num_subs - 1; e >= 0; e--)
5236 if (pb->subs[e].coef[i] != 0)
5239 for (e = pb->num_eqs - 1; e >= 0; e--)
5240 if (pb->eqs[e].coef[i] != 0)
5244 for (j = 1; j <= n_vars; j++)
5245 if (i != j && pb->eqs[e].coef[j] != 0)
5256 *lower_bound = *upper_bound =
5257 -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5262 for (e = pb->num_geqs - 1; e >= 0; e--)
5263 if (pb->geqs[e].coef[i] != 0)
5265 if (pb->geqs[e].key == i)
5266 *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5268 else if (pb->geqs[e].key == -i)
5269 *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5278 /* Sets the lower bound L and upper bound U for the values of variable
5279 I, and sets COULD_BE_ZERO to true if variable I might take value
5280 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5284 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5285 bool *could_be_zero, int lower_bound, int upper_bound)
5292 /* Preconditions. */
5293 gcc_assert (abs (pb->forwarding_address[i]) == 1
5294 && pb->num_vars + pb->num_subs == 2
5295 && pb->num_eqs + pb->num_subs == 1);
5297 /* Define variable I in terms of variable V. */
5298 if (pb->forwarding_address[i] == -1)
5307 sign = -eqn->coef[1];
5311 for (e = pb->num_geqs - 1; e >= 0; e--)
5312 if (pb->geqs[e].coef[v] != 0)
5314 if (pb->geqs[e].coef[v] == 1)
5315 lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5318 upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5321 if (lower_bound > upper_bound)
5329 if (lower_bound == neg_infinity)
5331 if (eqn->coef[v] > 0)
5332 b1 = sign * neg_infinity;
5335 b1 = -sign * neg_infinity;
5338 b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5340 if (upper_bound == pos_infinity)
5342 if (eqn->coef[v] > 0)
5343 b2 = sign * pos_infinity;
5346 b2 = -sign * pos_infinity;
5349 b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5351 *l = MAX (*l, b1 <= b2 ? b1 : b2);
5352 *u = MIN (*u, b1 <= b2 ? b2 : b1);
5354 *could_be_zero = (*l <= 0 && 0 <= *u
5355 && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5358 /* Return false when a lower bound L and an upper bound U for variable
5359 I in problem PB have been initialized. */
5362 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5367 if (!omega_query_variable (pb, i, l, u)
5368 || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5371 if (abs (pb->forwarding_address[i]) == 1
5372 && pb->num_vars + pb->num_subs == 2
5373 && pb->num_eqs + pb->num_subs == 1)
5376 query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5384 /* For problem PB, return an integer that represents the classic data
5385 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5386 masks that are added to the result. When DIST_KNOWN is true, DIST
5387 is set to the classic data dependence distance. LOWER_BOUND and
5388 UPPER_BOUND are bounds on the value of variable I, for example, it
5389 is possible to narrow the iteration domain with safe approximations
5390 of loop counts, and thus discard some data dependences that cannot
5394 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5395 int dd_eq, int dd_gt, int lower_bound,
5396 int upper_bound, bool *dist_known, int *dist)
5405 omega_query_variable (pb, i, &l, &u);
5406 query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5425 *dist_known = false;
5430 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5431 safe variables. Safe variables are not eliminated during the
5432 Fourier-Motzkin elimination. Safe variables are all those
5433 variables that are placed at the beginning of the array of
5434 variables: P->var[0, ..., NPROT - 1]. */
5437 omega_alloc_problem (int nvars, int nprot)
5441 gcc_assert (nvars <= OMEGA_MAX_VARS);
5442 omega_initialize ();
5444 /* Allocate and initialize PB. */
5445 pb = XCNEW (struct omega_pb_d);
5446 pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5447 pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5448 pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5449 pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5450 pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5452 pb->hash_version = hash_version;
5453 pb->num_vars = nvars;
5454 pb->safe_vars = nprot;
5455 pb->variables_initialized = false;
5456 pb->variables_freed = false;
5463 /* Keeps the state of the initialization. */
5464 static bool omega_initialized = false;
5466 /* Initialization of the Omega solver. */
5469 omega_initialize (void)
5473 if (omega_initialized)
5477 next_key = OMEGA_MAX_VARS + 1;
5478 packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5479 fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5480 fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5481 hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5483 for (i = 0; i < HASH_TABLE_SIZE; i++)
5484 hash_master[i].touched = -1;
5486 sprintf (wild_name[0], "1");
5487 sprintf (wild_name[1], "a");
5488 sprintf (wild_name[2], "b");
5489 sprintf (wild_name[3], "c");
5490 sprintf (wild_name[4], "d");
5491 sprintf (wild_name[5], "e");
5492 sprintf (wild_name[6], "f");
5493 sprintf (wild_name[7], "g");
5494 sprintf (wild_name[8], "h");
5495 sprintf (wild_name[9], "i");
5496 sprintf (wild_name[10], "j");
5497 sprintf (wild_name[11], "k");
5498 sprintf (wild_name[12], "l");
5499 sprintf (wild_name[13], "m");
5500 sprintf (wild_name[14], "n");
5501 sprintf (wild_name[15], "o");
5502 sprintf (wild_name[16], "p");
5503 sprintf (wild_name[17], "q");
5504 sprintf (wild_name[18], "r");
5505 sprintf (wild_name[19], "s");
5506 sprintf (wild_name[20], "t");
5507 sprintf (wild_name[40 - 1], "alpha");
5508 sprintf (wild_name[40 - 2], "beta");
5509 sprintf (wild_name[40 - 3], "gamma");
5510 sprintf (wild_name[40 - 4], "delta");
5511 sprintf (wild_name[40 - 5], "tau");
5512 sprintf (wild_name[40 - 6], "sigma");
5513 sprintf (wild_name[40 - 7], "chi");
5514 sprintf (wild_name[40 - 8], "omega");
5515 sprintf (wild_name[40 - 9], "pi");
5516 sprintf (wild_name[40 - 10], "ni");
5517 sprintf (wild_name[40 - 11], "Alpha");
5518 sprintf (wild_name[40 - 12], "Beta");
5519 sprintf (wild_name[40 - 13], "Gamma");
5520 sprintf (wild_name[40 - 14], "Delta");
5521 sprintf (wild_name[40 - 15], "Tau");
5522 sprintf (wild_name[40 - 16], "Sigma");
5523 sprintf (wild_name[40 - 17], "Chi");
5524 sprintf (wild_name[40 - 18], "Omega");
5525 sprintf (wild_name[40 - 19], "xxx");
5527 omega_initialized = true;