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-2015 Free Software Foundation, Inc.
9 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
11 This file is part of GCC.
13 GCC is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free
15 Software Foundation; either version 3, or (at your option) any later
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"
39 #include "double-int.h"
47 #include "diagnostic-core.h"
51 /* When set to true, keep substitution variables. When set to false,
52 resurrect substitution variables (convert substitutions back to EQs). */
53 static bool omega_reduce_with_subs
= true;
55 /* When set to true, omega_simplify_problem checks for problem with no
56 solutions, calling verify_omega_pb. */
57 static bool omega_verify_simplification
= false;
59 /* When set to true, only produce a single simplified result. */
60 static bool omega_single_result
= false;
62 /* Set return_single_result to 1 when omega_single_result is true. */
63 static int return_single_result
= 0;
65 /* Hash table for equations generated by the solver. */
66 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
67 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
68 static eqn hash_master
;
70 static int hash_version
= 0;
72 /* Set to true for making the solver enter in approximation mode. */
73 static bool in_approximate_mode
= false;
75 /* When set to zero, the solver is allowed to add new equalities to
76 the problem to be solved. */
77 static int conservative
= 0;
79 /* Set to omega_true when the problem was successfully reduced, set to
80 omega_unknown when the solver is unable to determine an answer. */
81 static enum omega_result omega_found_reduction
;
83 /* Set to true when the solver is allowed to add omega_red equations. */
84 static bool create_color
= false;
86 /* Set to nonzero when the problem to be solved can be reduced. */
87 static int may_be_red
= 0;
89 /* When false, there should be no substitution equations in the
90 simplified problem. */
91 static int please_no_equalities_in_simplified_problems
= 0;
93 /* Variables names for pretty printing. */
94 static char wild_name
[200][40];
96 /* Pointer to the void problem. */
97 static omega_pb no_problem
= (omega_pb
) 0;
99 /* Pointer to the problem to be solved. */
100 static omega_pb original_problem
= (omega_pb
) 0;
103 /* Return the integer A divided by B. */
106 int_div (int a
, int b
)
111 return -((-a
+ b
- 1)/b
);
114 /* Return the integer A modulo B. */
117 int_mod (int a
, int b
)
119 return a
- b
* int_div (a
, b
);
122 /* Test whether equation E is red. */
125 omega_eqn_is_red (eqn e
, int desired_res
)
127 return (desired_res
== omega_simplify
&& e
->color
== omega_red
);
130 /* Return a string for VARIABLE. */
133 omega_var_to_str (int variable
)
135 if (0 <= variable
&& variable
<= 20)
136 return wild_name
[variable
];
138 if (-20 < variable
&& variable
< 0)
139 return wild_name
[40 + variable
];
141 /* Collapse all the entries that would have overflowed. */
142 return wild_name
[21];
145 /* Return a string for variable I in problem PB. */
148 omega_variable_to_str (omega_pb pb
, int i
)
150 return omega_var_to_str (pb
->var
[i
]);
153 /* Do nothing function: used for default initializations. */
156 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED
)
160 void (*omega_when_reduced
) (omega_pb
) = omega_no_procedure
;
162 /* Print to FILE from PB equation E with all its coefficients
166 omega_print_term (FILE *file
, omega_pb pb
, eqn e
, int c
)
170 int n
= pb
->num_vars
;
173 for (i
= 1; i
<= n
; i
++)
174 if (c
* e
->coef
[i
] > 0)
179 if (c
* e
->coef
[i
] == 1)
180 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
182 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
183 omega_variable_to_str (pb
, i
));
187 for (i
= 1; i
<= n
; i
++)
188 if (i
!= went_first
&& c
* e
->coef
[i
] != 0)
190 if (!first
&& c
* e
->coef
[i
] > 0)
191 fprintf (file
, " + ");
195 if (c
* e
->coef
[i
] == 1)
196 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
197 else if (c
* e
->coef
[i
] == -1)
198 fprintf (file
, " - %s", omega_variable_to_str (pb
, i
));
200 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
201 omega_variable_to_str (pb
, i
));
204 if (!first
&& c
* e
->coef
[0] > 0)
205 fprintf (file
, " + ");
207 if (first
|| c
* e
->coef
[0] != 0)
208 fprintf (file
, "%d", c
* e
->coef
[0]);
211 /* Print to FILE the equation E of problem PB. */
214 omega_print_eqn (FILE *file
, omega_pb pb
, eqn e
, bool test
, int extra
)
217 int n
= pb
->num_vars
+ extra
;
218 bool is_lt
= test
&& e
->coef
[0] == -1;
226 else if (e
->key
!= 0)
227 fprintf (file
, "%d: ", e
->key
);
230 if (e
->color
== omega_red
)
235 for (i
= is_lt
? 1 : 0; i
<= n
; i
++)
239 fprintf (file
, " + ");
244 fprintf (file
, "%d", -e
->coef
[i
]);
245 else if (e
->coef
[i
] == -1)
246 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
248 fprintf (file
, "%d * %s", -e
->coef
[i
],
249 omega_variable_to_str (pb
, i
));
264 fprintf (file
, " = ");
266 fprintf (file
, " < ");
268 fprintf (file
, " <= ");
272 for (i
= 0; i
<= n
; i
++)
276 fprintf (file
, " + ");
281 fprintf (file
, "%d", e
->coef
[i
]);
282 else if (e
->coef
[i
] == 1)
283 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
285 fprintf (file
, "%d * %s", e
->coef
[i
],
286 omega_variable_to_str (pb
, i
));
292 if (e
->color
== omega_red
)
296 /* Print to FILE all the variables of problem PB. */
299 omega_print_vars (FILE *file
, omega_pb pb
)
303 fprintf (file
, "variables = ");
305 if (pb
->safe_vars
> 0)
306 fprintf (file
, "protected (");
308 for (i
= 1; i
<= pb
->num_vars
; i
++)
310 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
312 if (i
== pb
->safe_vars
)
315 if (i
< pb
->num_vars
)
316 fprintf (file
, ", ");
319 fprintf (file
, "\n");
322 /* Dump problem PB. */
325 debug (omega_pb_d
&ref
)
327 omega_print_problem (stderr
, &ref
);
331 debug (omega_pb_d
*ptr
)
336 fprintf (stderr
, "<nil>\n");
339 /* Debug problem PB. */
342 debug_omega_problem (omega_pb pb
)
344 omega_print_problem (stderr
, pb
);
347 /* Print to FILE problem PB. */
350 omega_print_problem (FILE *file
, omega_pb pb
)
354 if (!pb
->variables_initialized
)
355 omega_initialize_variables (pb
);
357 omega_print_vars (file
, pb
);
359 for (e
= 0; e
< pb
->num_eqs
; e
++)
361 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
362 fprintf (file
, "\n");
365 fprintf (file
, "Done with EQ\n");
367 for (e
= 0; e
< pb
->num_geqs
; e
++)
369 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
370 fprintf (file
, "\n");
373 fprintf (file
, "Done with GEQ\n");
375 for (e
= 0; e
< pb
->num_subs
; e
++)
377 eqn eq
= &pb
->subs
[e
];
379 if (eq
->color
== omega_red
)
383 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
385 fprintf (file
, "#%d := ", eq
->key
);
387 omega_print_term (file
, pb
, eq
, 1);
389 if (eq
->color
== omega_red
)
392 fprintf (file
, "\n");
396 /* Return the number of equations in PB tagged omega_red. */
399 omega_count_red_equations (omega_pb pb
)
404 for (e
= 0; e
< pb
->num_eqs
; e
++)
405 if (pb
->eqs
[e
].color
== omega_red
)
407 for (i
= pb
->num_vars
; i
> 0; i
--)
408 if (pb
->geqs
[e
].coef
[i
])
411 if (i
== 0 && pb
->geqs
[e
].coef
[0] == 1)
417 for (e
= 0; e
< pb
->num_geqs
; e
++)
418 if (pb
->geqs
[e
].color
== omega_red
)
421 for (e
= 0; e
< pb
->num_subs
; e
++)
422 if (pb
->subs
[e
].color
== omega_red
)
428 /* Print to FILE all the equations in PB that are tagged omega_red. */
431 omega_print_red_equations (FILE *file
, omega_pb pb
)
435 if (!pb
->variables_initialized
)
436 omega_initialize_variables (pb
);
438 omega_print_vars (file
, pb
);
440 for (e
= 0; e
< pb
->num_eqs
; e
++)
441 if (pb
->eqs
[e
].color
== omega_red
)
443 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
444 fprintf (file
, "\n");
447 for (e
= 0; e
< pb
->num_geqs
; e
++)
448 if (pb
->geqs
[e
].color
== omega_red
)
450 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
451 fprintf (file
, "\n");
454 for (e
= 0; e
< pb
->num_subs
; e
++)
455 if (pb
->subs
[e
].color
== omega_red
)
457 eqn eq
= &pb
->subs
[e
];
461 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
463 fprintf (file
, "#%d := ", eq
->key
);
465 omega_print_term (file
, pb
, eq
, 1);
466 fprintf (file
, "]\n");
470 /* Pretty print PB to FILE. */
473 omega_pretty_print_problem (FILE *file
, omega_pb pb
)
475 int e
, v
, v1
, v2
, v3
, t
;
476 bool *live
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
477 int stuffPrinted
= 0;
482 } partial_order_type
;
484 partial_order_type
**po
= XNEWVEC (partial_order_type
*,
485 OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
486 int **po_eq
= XNEWVEC (int *, OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
487 int *last_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
488 int *first_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
489 int *chain_length
= XNEWVEC (int, OMEGA_MAX_VARS
);
490 int *chain
= XNEWVEC (int, OMEGA_MAX_VARS
);
494 if (!pb
->variables_initialized
)
495 omega_initialize_variables (pb
);
497 if (pb
->num_vars
> 0)
499 omega_eliminate_redundant (pb
, false);
501 for (e
= 0; e
< pb
->num_eqs
; e
++)
504 fprintf (file
, "; ");
507 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
510 for (e
= 0; e
< pb
->num_geqs
; e
++)
515 for (v
= 1; v
<= pb
->num_vars
; v
++)
517 last_links
[v
] = first_links
[v
] = 0;
520 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
524 for (e
= 0; e
< pb
->num_geqs
; e
++)
527 for (v
= 1; v
<= pb
->num_vars
; v
++)
528 if (pb
->geqs
[e
].coef
[v
] == 1)
530 else if (pb
->geqs
[e
].coef
[v
] == -1)
535 while (v1
> 0 && pb
->geqs
[e
].coef
[v1
] == 0)
540 while (v2
> 0 && pb
->geqs
[e
].coef
[v2
] == 0)
545 while (v3
> 0 && pb
->geqs
[e
].coef
[v3
] == 0)
548 if (pb
->geqs
[e
].coef
[0] > 0 || pb
->geqs
[e
].coef
[0] < -1
550 || pb
->geqs
[e
].coef
[v1
] * pb
->geqs
[e
].coef
[v2
] != -1)
552 /* Not a partial order relation. */
556 if (pb
->geqs
[e
].coef
[v1
] == 1)
563 /* Relation is v1 <= v2 or v1 < v2. */
564 po
[v1
][v2
] = ((pb
->geqs
[e
].coef
[0] == 0) ? le
: lt
);
568 for (v
= 1; v
<= pb
->num_vars
; v
++)
569 chain_length
[v
] = last_links
[v
];
571 /* Just in case pb->num_vars <= 0. */
573 for (t
= 0; t
< pb
->num_vars
; t
++)
577 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
578 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
579 if (po
[v1
][v2
] != none
&&
580 chain_length
[v1
] <= chain_length
[v2
])
582 chain_length
[v1
] = chain_length
[v2
] + 1;
587 /* Caught in cycle. */
588 gcc_assert (!change
);
590 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
591 if (chain_length
[v1
] == 0)
596 for (v1
= 2; v1
<= pb
->num_vars
; v1
++)
597 if (chain_length
[v1
] + first_links
[v1
] >
598 chain_length
[v
] + first_links
[v
])
601 if (chain_length
[v
] + first_links
[v
] == 0)
605 fprintf (file
, "; ");
609 /* Chain starts at v. */
614 for (e
= 0; e
< pb
->num_geqs
; e
++)
615 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == 1)
618 fprintf (file
, ", ");
620 tmp
= pb
->geqs
[e
].coef
[v
];
621 pb
->geqs
[e
].coef
[v
] = 0;
622 omega_print_term (file
, pb
, &pb
->geqs
[e
], -1);
623 pb
->geqs
[e
].coef
[v
] = tmp
;
629 fprintf (file
, " <= ");
638 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
639 if (po
[v
][v2
] && chain_length
[v
] == 1 + chain_length
[v2
])
642 if (v2
> pb
->num_vars
)
649 fprintf (file
, "%s", omega_variable_to_str (pb
, chain
[0]));
651 for (multiprint
= false, i
= 1; i
< m
; i
++)
657 fprintf (file
, " <= ");
659 fprintf (file
, " < ");
661 fprintf (file
, "%s", omega_variable_to_str (pb
, v2
));
662 live
[po_eq
[v
][v2
]] = false;
664 if (!multiprint
&& i
< m
- 1)
665 for (v3
= 1; v3
<= pb
->num_vars
; v3
++)
667 if (v
== v3
|| v2
== v3
668 || po
[v
][v2
] != po
[v
][v3
]
669 || po
[v2
][chain
[i
+ 1]] != po
[v3
][chain
[i
+ 1]])
672 fprintf (file
, ",%s", omega_variable_to_str (pb
, v3
));
673 live
[po_eq
[v
][v3
]] = false;
674 live
[po_eq
[v3
][chain
[i
+ 1]]] = false;
682 /* Print last_links. */
687 for (e
= 0; e
< pb
->num_geqs
; e
++)
688 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == -1)
691 fprintf (file
, ", ");
693 fprintf (file
, " <= ");
695 tmp
= pb
->geqs
[e
].coef
[v
];
696 pb
->geqs
[e
].coef
[v
] = 0;
697 omega_print_term (file
, pb
, &pb
->geqs
[e
], 1);
698 pb
->geqs
[e
].coef
[v
] = tmp
;
705 for (e
= 0; e
< pb
->num_geqs
; e
++)
709 fprintf (file
, "; ");
711 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
714 for (e
= 0; e
< pb
->num_subs
; e
++)
716 eqn eq
= &pb
->subs
[e
];
719 fprintf (file
, "; ");
724 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
726 fprintf (file
, "#%d := ", eq
->key
);
728 omega_print_term (file
, pb
, eq
, 1);
741 /* Assign to variable I in PB the next wildcard name. The name of a
742 wildcard is a negative number. */
743 static int next_wild_card
= 0;
746 omega_name_wild_card (omega_pb pb
, int i
)
749 if (next_wild_card
< -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS
))
751 pb
->var
[i
] = next_wild_card
;
754 /* Return the index of the last protected (or safe) variable in PB,
755 after having added a new wildcard variable. */
758 omega_add_new_wild_card (omega_pb pb
)
761 int i
= ++pb
->safe_vars
;
764 /* Make a free place in the protected (safe) variables, by moving
765 the non protected variable pointed by "I" at the end, ie. at
766 offset pb->num_vars. */
767 if (pb
->num_vars
!= i
)
769 /* Move "I" for all the inequalities. */
770 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
772 if (pb
->geqs
[e
].coef
[i
])
773 pb
->geqs
[e
].touched
= 1;
775 pb
->geqs
[e
].coef
[pb
->num_vars
] = pb
->geqs
[e
].coef
[i
];
778 /* Move "I" for all the equalities. */
779 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
780 pb
->eqs
[e
].coef
[pb
->num_vars
] = pb
->eqs
[e
].coef
[i
];
782 /* Move "I" for all the substitutions. */
783 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
784 pb
->subs
[e
].coef
[pb
->num_vars
] = pb
->subs
[e
].coef
[i
];
786 /* Move the identifier. */
787 pb
->var
[pb
->num_vars
] = pb
->var
[i
];
790 /* Initialize at zero all the coefficients */
791 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
792 pb
->geqs
[e
].coef
[i
] = 0;
794 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
795 pb
->eqs
[e
].coef
[i
] = 0;
797 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
798 pb
->subs
[e
].coef
[i
] = 0;
800 /* And give it a name. */
801 omega_name_wild_card (pb
, i
);
805 /* Delete inequality E from problem PB that has N_VARS variables. */
808 omega_delete_geq (omega_pb pb
, int e
, int n_vars
)
810 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
812 fprintf (dump_file
, "Deleting %d (last:%d): ", e
, pb
->num_geqs
- 1);
813 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
814 fprintf (dump_file
, "\n");
817 if (e
< pb
->num_geqs
- 1)
818 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
823 /* Delete extra inequality E from problem PB that has N_VARS
827 omega_delete_geq_extra (omega_pb pb
, int e
, int n_vars
)
829 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
831 fprintf (dump_file
, "Deleting %d: ",e
);
832 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
833 fprintf (dump_file
, "\n");
836 if (e
< pb
->num_geqs
- 1)
837 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
843 /* Remove variable I from problem PB. */
846 omega_delete_variable (omega_pb pb
, int i
)
848 int n_vars
= pb
->num_vars
;
851 if (omega_safe_var_p (pb
, i
))
853 int j
= pb
->safe_vars
;
855 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
857 pb
->geqs
[e
].touched
= 1;
858 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[j
];
859 pb
->geqs
[e
].coef
[j
] = pb
->geqs
[e
].coef
[n_vars
];
862 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
864 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[j
];
865 pb
->eqs
[e
].coef
[j
] = pb
->eqs
[e
].coef
[n_vars
];
868 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
870 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[j
];
871 pb
->subs
[e
].coef
[j
] = pb
->subs
[e
].coef
[n_vars
];
874 pb
->var
[i
] = pb
->var
[j
];
875 pb
->var
[j
] = pb
->var
[n_vars
];
879 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
880 if (pb
->geqs
[e
].coef
[n_vars
])
882 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[n_vars
];
883 pb
->geqs
[e
].touched
= 1;
886 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
887 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[n_vars
];
889 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
890 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[n_vars
];
892 pb
->var
[i
] = pb
->var
[n_vars
];
895 if (omega_safe_var_p (pb
, i
))
901 /* Because the coefficients of an equation are sparse, PACKING records
902 indices for non null coefficients. */
905 /* Set up the coefficients of PACKING, following the coefficients of
906 equation EQN that has NUM_VARS variables. */
909 setup_packing (eqn eqn
, int num_vars
)
914 for (k
= num_vars
; k
>= 0; k
--)
921 /* Computes a linear combination of EQ and SUB at VAR with coefficient
922 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
923 non null indices of SUB stored in PACKING. */
926 omega_substitute_red_1 (eqn eq
, eqn sub
, int var
, int c
, bool *found_black
,
929 if (eq
->coef
[var
] != 0)
931 if (eq
->color
== omega_black
)
935 int j
, k
= eq
->coef
[var
];
939 for (j
= top_var
; j
>= 0; j
--)
940 eq
->coef
[packing
[j
]] -= sub
->coef
[packing
[j
]] * k
* c
;
945 /* Substitute in PB variable VAR with "C * SUB". */
948 omega_substitute_red (omega_pb pb
, eqn sub
, int var
, int c
, bool *found_black
)
950 int e
, top_var
= setup_packing (sub
, pb
->num_vars
);
952 *found_black
= false;
954 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
956 if (sub
->color
== omega_red
)
957 fprintf (dump_file
, "[");
959 fprintf (dump_file
, "substituting using %s := ",
960 omega_variable_to_str (pb
, var
));
961 omega_print_term (dump_file
, pb
, sub
, -c
);
963 if (sub
->color
== omega_red
)
964 fprintf (dump_file
, "]");
966 fprintf (dump_file
, "\n");
967 omega_print_vars (dump_file
, pb
);
970 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
972 eqn eqn
= &(pb
->eqs
[e
]);
974 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
976 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
978 omega_print_eq (dump_file
, pb
, eqn
);
979 fprintf (dump_file
, "\n");
983 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
985 eqn eqn
= &(pb
->geqs
[e
]);
987 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
989 if (eqn
->coef
[var
] && eqn
->color
== omega_red
)
992 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
994 omega_print_geq (dump_file
, pb
, eqn
);
995 fprintf (dump_file
, "\n");
999 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1001 eqn eqn
= &(pb
->subs
[e
]);
1003 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
1005 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1007 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1008 omega_print_term (dump_file
, pb
, eqn
, 1);
1009 fprintf (dump_file
, "\n");
1013 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1014 fprintf (dump_file
, "---\n\n");
1016 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1017 *found_black
= true;
1020 /* Substitute in PB variable VAR with "C * SUB". */
1023 omega_substitute (omega_pb pb
, eqn sub
, int var
, int c
)
1026 int top_var
= setup_packing (sub
, pb
->num_vars
);
1028 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1030 fprintf (dump_file
, "substituting using %s := ",
1031 omega_variable_to_str (pb
, var
));
1032 omega_print_term (dump_file
, pb
, sub
, -c
);
1033 fprintf (dump_file
, "\n");
1034 omega_print_vars (dump_file
, pb
);
1039 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1040 pb
->eqs
[e
].coef
[var
] = 0;
1042 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1043 if (pb
->geqs
[e
].coef
[var
] != 0)
1045 pb
->geqs
[e
].touched
= 1;
1046 pb
->geqs
[e
].coef
[var
] = 0;
1049 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1050 pb
->subs
[e
].coef
[var
] = 0;
1052 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1055 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1057 for (k
= pb
->num_vars
; k
>= 0; k
--)
1060 eqn
->key
= pb
->var
[var
];
1061 eqn
->color
= omega_black
;
1064 else if (top_var
== 0 && packing
[0] == 0)
1066 c
= -sub
->coef
[0] * c
;
1068 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1070 pb
->eqs
[e
].coef
[0] += pb
->eqs
[e
].coef
[var
] * c
;
1071 pb
->eqs
[e
].coef
[var
] = 0;
1074 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1075 if (pb
->geqs
[e
].coef
[var
] != 0)
1077 pb
->geqs
[e
].coef
[0] += pb
->geqs
[e
].coef
[var
] * c
;
1078 pb
->geqs
[e
].coef
[var
] = 0;
1079 pb
->geqs
[e
].touched
= 1;
1082 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1084 pb
->subs
[e
].coef
[0] += pb
->subs
[e
].coef
[var
] * c
;
1085 pb
->subs
[e
].coef
[var
] = 0;
1088 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1091 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1093 for (k
= pb
->num_vars
; k
>= 1; k
--)
1097 eqn
->key
= pb
->var
[var
];
1098 eqn
->color
= omega_black
;
1101 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1103 fprintf (dump_file
, "---\n\n");
1104 omega_print_problem (dump_file
, pb
);
1105 fprintf (dump_file
, "===\n\n");
1110 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1112 eqn eqn
= &(pb
->eqs
[e
]);
1113 int k
= eqn
->coef
[var
];
1120 for (j
= top_var
; j
>= 0; j
--)
1123 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1127 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1129 omega_print_eq (dump_file
, pb
, eqn
);
1130 fprintf (dump_file
, "\n");
1134 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1136 eqn eqn
= &(pb
->geqs
[e
]);
1137 int k
= eqn
->coef
[var
];
1145 for (j
= top_var
; j
>= 0; j
--)
1148 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1152 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1154 omega_print_geq (dump_file
, pb
, eqn
);
1155 fprintf (dump_file
, "\n");
1159 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1161 eqn eqn
= &(pb
->subs
[e
]);
1162 int k
= eqn
->coef
[var
];
1169 for (j
= top_var
; j
>= 0; j
--)
1172 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1176 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1178 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1179 omega_print_term (dump_file
, pb
, eqn
, 1);
1180 fprintf (dump_file
, "\n");
1184 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1186 fprintf (dump_file
, "---\n\n");
1187 omega_print_problem (dump_file
, pb
);
1188 fprintf (dump_file
, "===\n\n");
1191 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1194 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1197 for (k
= pb
->num_vars
; k
>= 0; k
--)
1198 eqn
->coef
[k
] = c
* (sub
->coef
[k
]);
1200 eqn
->key
= pb
->var
[var
];
1201 eqn
->color
= sub
->color
;
1206 /* Solve e = factor alpha for x_j and substitute. */
1209 omega_do_mod (omega_pb pb
, int factor
, int e
, int j
)
1212 eqn eq
= omega_alloc_eqns (0, 1);
1214 bool kill_j
= false;
1216 omega_copy_eqn (eq
, &pb
->eqs
[e
], pb
->num_vars
);
1218 for (k
= pb
->num_vars
; k
>= 0; k
--)
1220 eq
->coef
[k
] = int_mod (eq
->coef
[k
], factor
);
1222 if (2 * eq
->coef
[k
] >= factor
)
1223 eq
->coef
[k
] -= factor
;
1226 nfactor
= eq
->coef
[j
];
1228 if (omega_safe_var_p (pb
, j
) && !omega_wildcard_p (pb
, j
))
1230 i
= omega_add_new_wild_card (pb
);
1231 eq
->coef
[pb
->num_vars
] = eq
->coef
[i
];
1233 eq
->coef
[i
] = -factor
;
1238 eq
->coef
[j
] = -factor
;
1239 if (!omega_wildcard_p (pb
, j
))
1240 omega_name_wild_card (pb
, j
);
1243 omega_substitute (pb
, eq
, j
, nfactor
);
1245 for (k
= pb
->num_vars
; k
>= 0; k
--)
1246 pb
->eqs
[e
].coef
[k
] = pb
->eqs
[e
].coef
[k
] / factor
;
1249 omega_delete_variable (pb
, j
);
1251 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1253 fprintf (dump_file
, "Mod-ing and normalizing produces:\n");
1254 omega_print_problem (dump_file
, pb
);
1257 omega_free_eqns (eq
, 1);
1260 /* Multiplies by -1 inequality E. */
1263 omega_negate_geq (omega_pb pb
, int e
)
1267 for (i
= pb
->num_vars
; i
>= 0; i
--)
1268 pb
->geqs
[e
].coef
[i
] *= -1;
1270 pb
->geqs
[e
].coef
[0]--;
1271 pb
->geqs
[e
].touched
= 1;
1274 /* Returns OMEGA_TRUE when problem PB has a solution. */
1276 static enum omega_result
1277 verify_omega_pb (omega_pb pb
)
1279 enum omega_result result
;
1281 bool any_color
= false;
1282 omega_pb tmp_problem
= XNEW (struct omega_pb_d
);
1284 omega_copy_problem (tmp_problem
, pb
);
1285 tmp_problem
->safe_vars
= 0;
1286 tmp_problem
->num_subs
= 0;
1288 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1289 if (pb
->geqs
[e
].color
== omega_red
)
1295 if (please_no_equalities_in_simplified_problems
)
1299 original_problem
= no_problem
;
1301 original_problem
= pb
;
1303 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1305 fprintf (dump_file
, "verifying problem");
1308 fprintf (dump_file
, " (color mode)");
1310 fprintf (dump_file
, " :\n");
1311 omega_print_problem (dump_file
, pb
);
1314 result
= omega_solve_problem (tmp_problem
, omega_unknown
);
1315 original_problem
= no_problem
;
1318 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1320 if (result
!= omega_false
)
1321 fprintf (dump_file
, "verified problem\n");
1323 fprintf (dump_file
, "disproved problem\n");
1324 omega_print_problem (dump_file
, pb
);
1330 /* Add a new equality to problem PB at last position E. */
1333 adding_equality_constraint (omega_pb pb
, int e
)
1335 if (original_problem
!= no_problem
1336 && original_problem
!= pb
1340 int e2
= original_problem
->num_eqs
++;
1342 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1344 "adding equality constraint %d to outer problem\n", e2
);
1345 omega_init_eqn_zero (&original_problem
->eqs
[e2
],
1346 original_problem
->num_vars
);
1348 for (i
= pb
->num_vars
; i
>= 1; i
--)
1350 for (j
= original_problem
->num_vars
; j
>= 1; j
--)
1351 if (original_problem
->var
[j
] == pb
->var
[i
])
1356 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1357 fprintf (dump_file
, "retracting\n");
1358 original_problem
->num_eqs
--;
1361 original_problem
->eqs
[e2
].coef
[j
] = pb
->eqs
[e
].coef
[i
];
1364 original_problem
->eqs
[e2
].coef
[0] = pb
->eqs
[e
].coef
[0];
1366 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1367 omega_print_problem (dump_file
, original_problem
);
1371 static int *fast_lookup
;
1372 static int *fast_lookup_red
;
1376 normalize_uncoupled
,
1378 } normalize_return_type
;
1380 /* Normalizes PB by removing redundant constraints. Returns
1381 normalize_false when the constraints system has no solution,
1382 otherwise returns normalize_coupled or normalize_uncoupled. */
1384 static normalize_return_type
1385 normalize_omega_problem (omega_pb pb
)
1387 int e
, i
, j
, k
, n_vars
;
1388 int coupled_subscripts
= 0;
1390 n_vars
= pb
->num_vars
;
1392 for (e
= 0; e
< pb
->num_geqs
; e
++)
1394 if (!pb
->geqs
[e
].touched
)
1396 if (!single_var_geq (&pb
->geqs
[e
], n_vars
))
1397 coupled_subscripts
= 1;
1401 int g
, top_var
, i0
, hashCode
;
1402 int *p
= &packing
[0];
1404 for (k
= 1; k
<= n_vars
; k
++)
1405 if (pb
->geqs
[e
].coef
[k
])
1408 top_var
= (p
- &packing
[0]) - 1;
1412 if (pb
->geqs
[e
].coef
[0] < 0)
1414 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1416 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1417 fprintf (dump_file
, "\nequations have no solution \n");
1419 return normalize_false
;
1422 omega_delete_geq (pb
, e
, n_vars
);
1426 else if (top_var
== 0)
1428 int singlevar
= packing
[0];
1430 g
= pb
->geqs
[e
].coef
[singlevar
];
1434 pb
->geqs
[e
].coef
[singlevar
] = 1;
1435 pb
->geqs
[e
].key
= singlevar
;
1440 pb
->geqs
[e
].coef
[singlevar
] = -1;
1441 pb
->geqs
[e
].key
= -singlevar
;
1445 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1450 int hash_key_multiplier
= 31;
1452 coupled_subscripts
= 1;
1455 g
= pb
->geqs
[e
].coef
[i
];
1456 hashCode
= g
* (i
+ 3);
1461 for (; i0
>= 0; i0
--)
1466 x
= pb
->geqs
[e
].coef
[i
];
1467 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1482 for (; i0
>= 0; i0
--)
1486 x
= pb
->geqs
[e
].coef
[i
];
1487 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1492 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1495 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1496 hashCode
= pb
->geqs
[e
].coef
[i
] * (i
+ 3);
1498 for (; i0
>= 0; i0
--)
1501 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1502 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3)
1503 + pb
->geqs
[e
].coef
[i
];
1507 g2
= abs (hashCode
);
1509 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1511 fprintf (dump_file
, "Hash code = %d, eqn = ", hashCode
);
1512 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1513 fprintf (dump_file
, "\n");
1516 j
= g2
% HASH_TABLE_SIZE
;
1519 eqn proto
= &(hash_master
[j
]);
1521 if (proto
->touched
== g2
)
1523 if (proto
->coef
[0] == top_var
)
1526 for (i0
= top_var
; i0
>= 0; i0
--)
1530 if (pb
->geqs
[e
].coef
[i
] != proto
->coef
[i
])
1534 for (i0
= top_var
; i0
>= 0; i0
--)
1538 if (pb
->geqs
[e
].coef
[i
] != -proto
->coef
[i
])
1545 pb
->geqs
[e
].key
= proto
->key
;
1547 pb
->geqs
[e
].key
= -proto
->key
;
1552 else if (proto
->touched
< 0)
1554 omega_init_eqn_zero (proto
, pb
->num_vars
);
1556 for (i0
= top_var
; i0
>= 0; i0
--)
1559 proto
->coef
[i
] = pb
->geqs
[e
].coef
[i
];
1562 for (i0
= top_var
; i0
>= 0; i0
--)
1565 proto
->coef
[i
] = -pb
->geqs
[e
].coef
[i
];
1568 proto
->coef
[0] = top_var
;
1569 proto
->touched
= g2
;
1571 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1572 fprintf (dump_file
, " constraint key = %d\n",
1575 proto
->key
= next_key
++;
1577 /* Too many hash keys generated. */
1578 gcc_assert (proto
->key
<= MAX_KEYS
);
1581 pb
->geqs
[e
].key
= proto
->key
;
1583 pb
->geqs
[e
].key
= -proto
->key
;
1588 j
= (j
+ 1) % HASH_TABLE_SIZE
;
1592 pb
->geqs
[e
].touched
= 0;
1596 int eKey
= pb
->geqs
[e
].key
;
1600 int cTerm
= pb
->geqs
[e
].coef
[0];
1601 e2
= fast_lookup
[MAX_KEYS
- eKey
];
1603 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1604 && pb
->geqs
[e2
].color
== omega_black
)
1606 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1608 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1610 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1611 fprintf (dump_file
, "\n");
1612 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1614 "\nequations have no solution \n");
1616 return normalize_false
;
1619 if (pb
->geqs
[e2
].coef
[0] == -cTerm
1621 || pb
->geqs
[e
].color
== omega_black
))
1623 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1625 if (pb
->geqs
[e
].color
== omega_black
)
1626 adding_equality_constraint (pb
, pb
->num_eqs
);
1628 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1632 e2
= fast_lookup_red
[MAX_KEYS
- eKey
];
1634 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1635 && pb
->geqs
[e2
].color
== omega_red
)
1637 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1639 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1641 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1642 fprintf (dump_file
, "\n");
1643 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1645 "\nequations have no solution \n");
1647 return normalize_false
;
1650 if (pb
->geqs
[e2
].coef
[0] == -cTerm
&& create_color
)
1652 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1654 pb
->eqs
[pb
->num_eqs
].color
= omega_red
;
1656 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1660 e2
= fast_lookup
[MAX_KEYS
+ eKey
];
1662 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1663 && pb
->geqs
[e2
].color
== omega_black
)
1665 if (pb
->geqs
[e2
].coef
[0] > cTerm
)
1667 if (pb
->geqs
[e
].color
== omega_black
)
1669 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1672 "Removing Redundant Equation: ");
1673 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1674 fprintf (dump_file
, "\n");
1676 "[a] Made Redundant by: ");
1677 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1678 fprintf (dump_file
, "\n");
1680 pb
->geqs
[e2
].coef
[0] = cTerm
;
1681 omega_delete_geq (pb
, e
, n_vars
);
1688 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1690 fprintf (dump_file
, "Removing Redundant Equation: ");
1691 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1692 fprintf (dump_file
, "\n");
1693 fprintf (dump_file
, "[b] Made Redundant by: ");
1694 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1695 fprintf (dump_file
, "\n");
1697 omega_delete_geq (pb
, e
, n_vars
);
1703 e2
= fast_lookup_red
[MAX_KEYS
+ eKey
];
1705 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1706 && pb
->geqs
[e2
].color
== omega_red
)
1708 if (pb
->geqs
[e2
].coef
[0] >= cTerm
)
1710 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1712 fprintf (dump_file
, "Removing Redundant Equation: ");
1713 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1714 fprintf (dump_file
, "\n");
1715 fprintf (dump_file
, "[c] Made Redundant by: ");
1716 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1717 fprintf (dump_file
, "\n");
1719 pb
->geqs
[e2
].coef
[0] = cTerm
;
1720 pb
->geqs
[e2
].color
= pb
->geqs
[e
].color
;
1722 else if (pb
->geqs
[e
].color
== omega_red
)
1724 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1726 fprintf (dump_file
, "Removing Redundant Equation: ");
1727 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1728 fprintf (dump_file
, "\n");
1729 fprintf (dump_file
, "[d] Made Redundant by: ");
1730 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1731 fprintf (dump_file
, "\n");
1734 omega_delete_geq (pb
, e
, n_vars
);
1741 if (pb
->geqs
[e
].color
== omega_red
)
1742 fast_lookup_red
[MAX_KEYS
+ eKey
] = e
;
1744 fast_lookup
[MAX_KEYS
+ eKey
] = e
;
1748 create_color
= false;
1749 return coupled_subscripts
? normalize_coupled
: normalize_uncoupled
;
1752 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1753 of variables in EQN. */
1756 divide_eqn_by_gcd (eqn eqn
, int n_vars
)
1760 for (var
= n_vars
; var
>= 0; var
--)
1761 g
= gcd (abs (eqn
->coef
[var
]), g
);
1764 for (var
= n_vars
; var
>= 0; var
--)
1765 eqn
->coef
[var
] = eqn
->coef
[var
] / g
;
1768 /* Rewrite some non-safe variables in function of protected
1769 wildcard variables. */
1772 cleanout_wildcards (omega_pb pb
)
1775 int n_vars
= pb
->num_vars
;
1776 bool renormalize
= false;
1778 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1779 for (i
= n_vars
; !omega_safe_var_p (pb
, i
); i
--)
1780 if (pb
->eqs
[e
].coef
[i
] != 0)
1782 /* i is the last nonzero non-safe variable. */
1784 for (j
= i
- 1; !omega_safe_var_p (pb
, j
); j
--)
1785 if (pb
->eqs
[e
].coef
[j
] != 0)
1788 /* j is the next nonzero non-safe variable, or points
1789 to a safe variable: it is then a wildcard variable. */
1792 if (omega_safe_var_p (pb
, j
))
1794 eqn sub
= &(pb
->eqs
[e
]);
1795 int c
= pb
->eqs
[e
].coef
[i
];
1799 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1802 "Found a single wild card equality: ");
1803 omega_print_eq (dump_file
, pb
, &pb
->eqs
[e
]);
1804 fprintf (dump_file
, "\n");
1805 omega_print_problem (dump_file
, pb
);
1808 for (e2
= pb
->num_eqs
- 1; e2
>= 0; e2
--)
1809 if (e
!= e2
&& pb
->eqs
[e2
].coef
[i
]
1810 && (pb
->eqs
[e2
].color
== omega_red
1811 || (pb
->eqs
[e2
].color
== omega_black
1812 && pb
->eqs
[e
].color
== omega_black
)))
1814 eqn eqn
= &(pb
->eqs
[e2
]);
1817 for (var
= n_vars
; var
>= 0; var
--)
1818 eqn
->coef
[var
] *= a
;
1822 for (var
= n_vars
; var
>= 0; var
--)
1823 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1826 divide_eqn_by_gcd (eqn
, n_vars
);
1829 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
1830 if (pb
->geqs
[e2
].coef
[i
]
1831 && (pb
->geqs
[e2
].color
== omega_red
1832 || (pb
->eqs
[e
].color
== omega_black
1833 && pb
->geqs
[e2
].color
== omega_black
)))
1835 eqn eqn
= &(pb
->geqs
[e2
]);
1838 for (var
= n_vars
; var
>= 0; var
--)
1839 eqn
->coef
[var
] *= a
;
1843 for (var
= n_vars
; var
>= 0; var
--)
1844 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1851 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
1852 if (pb
->subs
[e2
].coef
[i
]
1853 && (pb
->subs
[e2
].color
== omega_red
1854 || (pb
->subs
[e2
].color
== omega_black
1855 && pb
->eqs
[e
].color
== omega_black
)))
1857 eqn eqn
= &(pb
->subs
[e2
]);
1860 for (var
= n_vars
; var
>= 0; var
--)
1861 eqn
->coef
[var
] *= a
;
1865 for (var
= n_vars
; var
>= 0; var
--)
1866 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1869 divide_eqn_by_gcd (eqn
, n_vars
);
1872 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1874 fprintf (dump_file
, "cleaned-out wildcard: ");
1875 omega_print_problem (dump_file
, pb
);
1882 normalize_omega_problem (pb
);
1885 /* Make variable IDX unprotected in PB, by swapping its index at the
1886 PB->safe_vars rank. */
1889 omega_unprotect_1 (omega_pb pb
, int *idx
, bool *unprotect
)
1891 /* If IDX is protected... */
1892 if (*idx
< pb
->safe_vars
)
1894 /* ... swap its index with the last non protected index. */
1895 int j
= pb
->safe_vars
;
1898 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1900 pb
->geqs
[e
].touched
= 1;
1901 std::swap (pb
->geqs
[e
].coef
[*idx
], pb
->geqs
[e
].coef
[j
]);
1904 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1905 std::swap (pb
->eqs
[e
].coef
[*idx
], pb
->eqs
[e
].coef
[j
]);
1907 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1908 std::swap (pb
->subs
[e
].coef
[*idx
], pb
->subs
[e
].coef
[j
]);
1911 std::swap (unprotect
[*idx
], unprotect
[j
]);
1913 std::swap (pb
->var
[*idx
], pb
->var
[j
]);
1914 pb
->forwarding_address
[pb
->var
[*idx
]] = *idx
;
1915 pb
->forwarding_address
[pb
->var
[j
]] = j
;
1919 /* The variable at pb->safe_vars is also unprotected now. */
1923 /* During the Fourier-Motzkin elimination some variables are
1924 substituted with other variables. This function resurrects the
1925 substituted variables in PB. */
1928 resurrect_subs (omega_pb pb
)
1930 if (pb
->num_subs
> 0
1931 && please_no_equalities_in_simplified_problems
== 0)
1935 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1938 "problem reduced, bringing variables back to life\n");
1939 omega_print_problem (dump_file
, pb
);
1942 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
1943 if (omega_wildcard_p (pb
, i
))
1944 omega_unprotect_1 (pb
, &i
, NULL
);
1948 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1949 if (single_var_geq (&pb
->geqs
[e
], pb
->num_vars
))
1951 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
1952 pb
->geqs
[e
].key
+= (pb
->geqs
[e
].key
> 0 ? m
: -m
);
1956 pb
->geqs
[e
].touched
= 1;
1957 pb
->geqs
[e
].key
= 0;
1960 for (i
= pb
->num_vars
; !omega_safe_var_p (pb
, i
); i
--)
1962 pb
->var
[i
+ m
] = pb
->var
[i
];
1964 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1965 pb
->geqs
[e
].coef
[i
+ m
] = pb
->geqs
[e
].coef
[i
];
1967 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1968 pb
->eqs
[e
].coef
[i
+ m
] = pb
->eqs
[e
].coef
[i
];
1970 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1971 pb
->subs
[e
].coef
[i
+ m
] = pb
->subs
[e
].coef
[i
];
1974 for (i
= pb
->safe_vars
+ m
; !omega_safe_var_p (pb
, i
); i
--)
1976 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1977 pb
->geqs
[e
].coef
[i
] = 0;
1979 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1980 pb
->eqs
[e
].coef
[i
] = 0;
1982 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1983 pb
->subs
[e
].coef
[i
] = 0;
1988 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1990 pb
->var
[pb
->safe_vars
+ 1 + e
] = pb
->subs
[e
].key
;
1991 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e
]),
1993 pb
->eqs
[pb
->num_eqs
].coef
[pb
->safe_vars
+ 1 + e
] = -1;
1994 pb
->eqs
[pb
->num_eqs
].color
= omega_black
;
1996 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1998 fprintf (dump_file
, "brought back: ");
1999 omega_print_eq (dump_file
, pb
, &pb
->eqs
[pb
->num_eqs
]);
2000 fprintf (dump_file
, "\n");
2004 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2010 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2012 fprintf (dump_file
, "variables brought back to life\n");
2013 omega_print_problem (dump_file
, pb
);
2016 cleanout_wildcards (pb
);
2021 implies (unsigned int a
, unsigned int b
)
2023 return (a
== (a
& b
));
2026 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2027 extra step is performed. Returns omega_false when there exist no
2028 solution, omega_true otherwise. */
2031 omega_eliminate_redundant (omega_pb pb
, bool expensive
)
2033 int c
, e
, e1
, e2
, e3
, p
, q
, i
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2034 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2035 omega_pb tmp_problem
;
2037 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2038 unsigned int *peqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2039 unsigned int *zeqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2040 unsigned int *neqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2042 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2043 unsigned int pp
, pz
, pn
;
2045 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2047 fprintf (dump_file
, "in eliminate Redundant:\n");
2048 omega_print_problem (dump_file
, pb
);
2051 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2056 peqs
[e
] = zeqs
[e
] = neqs
[e
] = 0;
2058 for (i
= pb
->num_vars
; i
>= 1; i
--)
2060 if (pb
->geqs
[e
].coef
[i
] > 0)
2062 else if (pb
->geqs
[e
].coef
[i
] < 0)
2072 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2074 for (e2
= e1
- 1; e2
>= 0; e2
--)
2077 for (p
= pb
->num_vars
; p
> 1; p
--)
2078 for (q
= p
- 1; q
> 0; q
--)
2079 if ((alpha
= pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
]
2080 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]) != 0)
2086 pz
= ((zeqs
[e1
] & zeqs
[e2
]) | (peqs
[e1
] & neqs
[e2
])
2087 | (neqs
[e1
] & peqs
[e2
]));
2088 pp
= peqs
[e1
] | peqs
[e2
];
2089 pn
= neqs
[e1
] | neqs
[e2
];
2091 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2092 if (e3
!= e1
&& e3
!= e2
)
2094 if (!implies (zeqs
[e3
], pz
))
2097 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2098 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2099 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2100 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2103 if (alpha1
* alpha2
<= 0)
2115 /* Trying to prove e3 is redundant. */
2116 if (!implies (peqs
[e3
], pp
)
2117 || !implies (neqs
[e3
], pn
))
2120 if (pb
->geqs
[e3
].color
== omega_black
2121 && (pb
->geqs
[e1
].color
== omega_red
2122 || pb
->geqs
[e2
].color
== omega_red
))
2125 for (k
= pb
->num_vars
; k
>= 1; k
--)
2126 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2127 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2128 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2131 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2132 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2134 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2136 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2139 "found redundant inequality\n");
2141 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2142 alpha1
, alpha2
, alpha3
);
2144 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2145 fprintf (dump_file
, "\n");
2146 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2147 fprintf (dump_file
, "\n=> ");
2148 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2149 fprintf (dump_file
, "\n\n");
2157 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2158 or trying to prove e3 < 0, and therefore the
2159 problem has no solutions. */
2160 if (!implies (peqs
[e3
], pn
)
2161 || !implies (neqs
[e3
], pp
))
2164 if (pb
->geqs
[e1
].color
== omega_red
2165 || pb
->geqs
[e2
].color
== omega_red
2166 || pb
->geqs
[e3
].color
== omega_red
)
2169 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2170 for (k
= pb
->num_vars
; k
>= 1; k
--)
2171 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2172 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2173 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2176 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2177 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2179 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0]))
2181 /* We just proved e3 < 0, so no solutions exist. */
2182 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2185 "found implied over tight inequality\n");
2187 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2188 alpha1
, alpha2
, -alpha3
);
2189 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2190 fprintf (dump_file
, "\n");
2191 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2192 fprintf (dump_file
, "\n=> not ");
2193 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2194 fprintf (dump_file
, "\n\n");
2202 else if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] - 1))
2204 /* We just proved that e3 <=0, so e3 = 0. */
2205 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2208 "found implied tight inequality\n");
2210 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2211 alpha1
, alpha2
, -alpha3
);
2212 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2213 fprintf (dump_file
, "\n");
2214 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2215 fprintf (dump_file
, "\n=> inverse ");
2216 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2217 fprintf (dump_file
, "\n\n");
2220 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++],
2221 &pb
->geqs
[e3
], pb
->num_vars
);
2222 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2223 adding_equality_constraint (pb
, pb
->num_eqs
- 1);
2231 /* Delete the inequalities that were marked as dead. */
2232 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2234 omega_delete_geq (pb
, e
, pb
->num_vars
);
2237 goto eliminate_redundant_done
;
2239 tmp_problem
= XNEW (struct omega_pb_d
);
2242 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2244 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2247 "checking equation %d to see if it is redundant: ", e
);
2248 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2249 fprintf (dump_file
, "\n");
2252 omega_copy_problem (tmp_problem
, pb
);
2253 omega_negate_geq (tmp_problem
, e
);
2254 tmp_problem
->safe_vars
= 0;
2255 tmp_problem
->variables_freed
= false;
2257 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2258 omega_delete_geq (pb
, e
, pb
->num_vars
);
2264 if (!omega_reduce_with_subs
)
2266 resurrect_subs (pb
);
2267 gcc_assert (please_no_equalities_in_simplified_problems
2268 || pb
->num_subs
== 0);
2271 eliminate_redundant_done
:
2279 /* For each inequality that has coefficients bigger than 20, try to
2280 create a new constraint that cannot be derived from the original
2281 constraint and that has smaller coefficients. Add the new
2282 constraint at the end of geqs. Return the number of inequalities
2283 that have been added to PB. */
2286 smooth_weird_equations (omega_pb pb
)
2288 int e1
, e2
, e3
, p
, q
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2293 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2294 if (pb
->geqs
[e1
].color
== omega_black
)
2298 for (v
= pb
->num_vars
; v
>= 1; v
--)
2299 if (pb
->geqs
[e1
].coef
[v
] != 0 && abs (pb
->geqs
[e1
].coef
[v
]) < g
)
2300 g
= abs (pb
->geqs
[e1
].coef
[v
]);
2307 for (v
= pb
->num_vars
; v
>= 1; v
--)
2308 pb
->geqs
[e3
].coef
[v
] = int_div (6 * pb
->geqs
[e1
].coef
[v
] + g
/ 2,
2311 pb
->geqs
[e3
].color
= omega_black
;
2312 pb
->geqs
[e3
].touched
= 1;
2314 pb
->geqs
[e3
].coef
[0] = 9997;
2316 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2318 fprintf (dump_file
, "Checking to see if we can derive: ");
2319 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2320 fprintf (dump_file
, "\n from: ");
2321 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e1
]);
2322 fprintf (dump_file
, "\n");
2325 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
2326 if (e1
!= e2
&& pb
->geqs
[e2
].color
== omega_black
)
2328 for (p
= pb
->num_vars
; p
> 1; p
--)
2330 for (q
= p
- 1; q
> 0; q
--)
2333 (pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
] -
2334 pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]);
2343 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2344 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2345 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2346 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2349 if (alpha1
* alpha2
<= 0)
2361 /* Try to prove e3 is redundant: verify
2362 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2363 for (k
= pb
->num_vars
; k
>= 1; k
--)
2364 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2365 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2366 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2369 c
= alpha1
* pb
->geqs
[e1
].coef
[0]
2370 + alpha2
* pb
->geqs
[e2
].coef
[0];
2372 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2373 pb
->geqs
[e3
].coef
[0] = int_div (c
, alpha3
);
2378 if (pb
->geqs
[e3
].coef
[0] < 9997)
2383 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2386 "Smoothing weird equations; adding:\n");
2387 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2388 fprintf (dump_file
, "\nto:\n");
2389 omega_print_problem (dump_file
, pb
);
2390 fprintf (dump_file
, "\n\n");
2398 /* Replace tuples of inequalities, that define upper and lower half
2399 spaces, with an equation. */
2402 coalesce (omega_pb pb
)
2407 int found_something
= 0;
2409 for (e
= 0; e
< pb
->num_geqs
; e
++)
2410 if (pb
->geqs
[e
].color
== omega_red
)
2416 is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2418 for (e
= 0; e
< pb
->num_geqs
; e
++)
2421 for (e
= 0; e
< pb
->num_geqs
; e
++)
2422 if (pb
->geqs
[e
].color
== omega_red
2423 && !pb
->geqs
[e
].touched
)
2424 for (e2
= e
+ 1; e2
< pb
->num_geqs
; e2
++)
2425 if (!pb
->geqs
[e2
].touched
2426 && pb
->geqs
[e
].key
== -pb
->geqs
[e2
].key
2427 && pb
->geqs
[e
].coef
[0] == -pb
->geqs
[e2
].coef
[0]
2428 && pb
->geqs
[e2
].color
== omega_red
)
2430 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++], &pb
->geqs
[e
],
2432 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2438 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2440 omega_delete_geq (pb
, e
, pb
->num_vars
);
2442 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && found_something
)
2444 fprintf (dump_file
, "Coalesced pb->geqs into %d EQ's:\n",
2446 omega_print_problem (dump_file
, pb
);
2452 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2453 true, continue to eliminate all the red inequalities. */
2456 omega_eliminate_red (omega_pb pb
, bool eliminate_all
)
2458 int e
, e2
, e3
, i
, j
, k
, a
, alpha1
, alpha2
;
2460 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2463 omega_pb tmp_problem
;
2465 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2467 fprintf (dump_file
, "in eliminate RED:\n");
2468 omega_print_problem (dump_file
, pb
);
2471 if (pb
->num_eqs
> 0)
2472 omega_simplify_problem (pb
);
2474 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2477 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2478 if (pb
->geqs
[e
].color
== omega_black
&& !is_dead
[e
])
2479 for (e2
= e
- 1; e2
>= 0; e2
--)
2480 if (pb
->geqs
[e2
].color
== omega_black
2485 for (i
= pb
->num_vars
; i
> 1; i
--)
2486 for (j
= i
- 1; j
> 0; j
--)
2487 if ((a
= (pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e2
].coef
[j
]
2488 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e
].coef
[j
])) != 0)
2494 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2497 "found two equations to combine, i = %s, ",
2498 omega_variable_to_str (pb
, i
));
2499 fprintf (dump_file
, "j = %s, alpha = %d\n",
2500 omega_variable_to_str (pb
, j
), a
);
2501 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2502 fprintf (dump_file
, "\n");
2503 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2504 fprintf (dump_file
, "\n");
2507 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2508 if (pb
->geqs
[e3
].color
== omega_red
)
2510 alpha1
= (pb
->geqs
[e2
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2511 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2512 alpha2
= -(pb
->geqs
[e
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2513 - pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2515 if ((a
> 0 && alpha1
> 0 && alpha2
> 0)
2516 || (a
< 0 && alpha1
< 0 && alpha2
< 0))
2518 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2521 "alpha1 = %d, alpha2 = %d;"
2522 "comparing against: ",
2524 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2525 fprintf (dump_file
, "\n");
2528 for (k
= pb
->num_vars
; k
>= 0; k
--)
2530 c
= (alpha1
* pb
->geqs
[e
].coef
[k
]
2531 + alpha2
* pb
->geqs
[e2
].coef
[k
]);
2533 if (c
!= a
* pb
->geqs
[e3
].coef
[k
])
2536 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && k
> 0)
2537 fprintf (dump_file
, " %s: %d, %d\n",
2538 omega_variable_to_str (pb
, k
), c
,
2539 a
* pb
->geqs
[e3
].coef
[k
]);
2544 ((a
> 0 && c
< a
* pb
->geqs
[e3
].coef
[k
])
2545 || (a
< 0 && c
> a
* pb
->geqs
[e3
].coef
[k
]))))
2547 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2551 "red equation#%d is dead "
2552 "(%d dead so far, %d remain)\n",
2554 pb
->num_geqs
- dead_count
);
2555 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2556 fprintf (dump_file
, "\n");
2557 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2558 fprintf (dump_file
, "\n");
2559 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2560 fprintf (dump_file
, "\n");
2568 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2570 omega_delete_geq (pb
, e
, pb
->num_vars
);
2574 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2576 fprintf (dump_file
, "in eliminate RED, easy tests done:\n");
2577 omega_print_problem (dump_file
, pb
);
2580 for (red_found
= 0, e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2581 if (pb
->geqs
[e
].color
== omega_red
)
2589 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2590 fprintf (dump_file
, "fast checks worked\n");
2592 if (!omega_reduce_with_subs
)
2593 gcc_assert (please_no_equalities_in_simplified_problems
2594 || pb
->num_subs
== 0);
2599 if (!omega_verify_simplification
2600 && verify_omega_pb (pb
) == omega_false
)
2604 tmp_problem
= XNEW (struct omega_pb_d
);
2606 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2607 if (pb
->geqs
[e
].color
== omega_red
)
2609 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2612 "checking equation %d to see if it is redundant: ", e
);
2613 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2614 fprintf (dump_file
, "\n");
2617 omega_copy_problem (tmp_problem
, pb
);
2618 omega_negate_geq (tmp_problem
, e
);
2619 tmp_problem
->safe_vars
= 0;
2620 tmp_problem
->variables_freed
= false;
2621 tmp_problem
->num_subs
= 0;
2623 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2625 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2626 fprintf (dump_file
, "it is redundant\n");
2627 omega_delete_geq (pb
, e
, pb
->num_vars
);
2631 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2632 fprintf (dump_file
, "it is not redundant\n");
2636 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2637 fprintf (dump_file
, "no need to check other red equations\n");
2645 /* omega_simplify_problem (pb); */
2647 if (!omega_reduce_with_subs
)
2648 gcc_assert (please_no_equalities_in_simplified_problems
2649 || pb
->num_subs
== 0);
2652 /* Transform some wildcard variables to non-safe variables. */
2655 chain_unprotect (omega_pb pb
)
2658 bool *unprotect
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2660 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2662 unprotect
[i
] = omega_wildcard_p (pb
, i
);
2664 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2665 if (pb
->subs
[e
].coef
[i
])
2666 unprotect
[i
] = false;
2669 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2671 fprintf (dump_file
, "Doing chain reaction unprotection\n");
2672 omega_print_problem (dump_file
, pb
);
2674 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2676 fprintf (dump_file
, "unprotecting %s\n",
2677 omega_variable_to_str (pb
, i
));
2680 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2682 omega_unprotect_1 (pb
, &i
, unprotect
);
2684 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2686 fprintf (dump_file
, "After chain reactions\n");
2687 omega_print_problem (dump_file
, pb
);
2693 /* Reduce problem PB. */
2696 omega_problem_reduced (omega_pb pb
)
2698 if (omega_verify_simplification
2699 && !in_approximate_mode
2700 && verify_omega_pb (pb
) == omega_false
)
2703 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS
)
2704 && !omega_eliminate_redundant (pb
, true))
2707 omega_found_reduction
= omega_true
;
2709 if (!please_no_equalities_in_simplified_problems
)
2712 if (omega_reduce_with_subs
2713 || please_no_equalities_in_simplified_problems
)
2714 chain_unprotect (pb
);
2716 resurrect_subs (pb
);
2718 if (!return_single_result
)
2722 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2723 pb
->forwarding_address
[pb
->var
[i
]] = i
;
2725 for (i
= 0; i
< pb
->num_subs
; i
++)
2726 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
2728 (*omega_when_reduced
) (pb
);
2731 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2733 fprintf (dump_file
, "-------------------------------------------\n");
2734 fprintf (dump_file
, "problem reduced:\n");
2735 omega_print_problem (dump_file
, pb
);
2736 fprintf (dump_file
, "-------------------------------------------\n");
2740 /* Eliminates all the free variables for problem PB, that is all the
2741 variables from FV to PB->NUM_VARS. */
2744 omega_free_eliminations (omega_pb pb
, int fv
)
2746 bool try_again
= true;
2748 int n_vars
= pb
->num_vars
;
2754 for (i
= n_vars
; i
> fv
; i
--)
2756 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2757 if (pb
->geqs
[e
].coef
[i
])
2762 else if (pb
->geqs
[e
].coef
[i
] > 0)
2764 for (e2
= e
- 1; e2
>= 0; e2
--)
2765 if (pb
->geqs
[e2
].coef
[i
] < 0)
2770 for (e2
= e
- 1; e2
>= 0; e2
--)
2771 if (pb
->geqs
[e2
].coef
[i
] > 0)
2778 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2779 if (pb
->subs
[e3
].coef
[i
])
2785 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2786 if (pb
->eqs
[e3
].coef
[i
])
2792 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2793 fprintf (dump_file
, "a free elimination of %s\n",
2794 omega_variable_to_str (pb
, i
));
2798 omega_delete_geq (pb
, e
, n_vars
);
2800 for (e
--; e
>= 0; e
--)
2801 if (pb
->geqs
[e
].coef
[i
])
2802 omega_delete_geq (pb
, e
, n_vars
);
2804 try_again
= (i
< n_vars
);
2807 omega_delete_variable (pb
, i
);
2808 n_vars
= pb
->num_vars
;
2813 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2815 fprintf (dump_file
, "\nafter free eliminations:\n");
2816 omega_print_problem (dump_file
, pb
);
2817 fprintf (dump_file
, "\n");
2821 /* Do free red eliminations. */
2824 free_red_eliminations (omega_pb pb
)
2826 bool try_again
= true;
2828 int n_vars
= pb
->num_vars
;
2829 bool *is_red_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2830 bool *is_dead_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2831 bool *is_dead_geq
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2833 for (i
= n_vars
; i
> 0; i
--)
2835 is_red_var
[i
] = false;
2836 is_dead_var
[i
] = false;
2839 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2841 is_dead_geq
[e
] = false;
2843 if (pb
->geqs
[e
].color
== omega_red
)
2844 for (i
= n_vars
; i
> 0; i
--)
2845 if (pb
->geqs
[e
].coef
[i
] != 0)
2846 is_red_var
[i
] = true;
2852 for (i
= n_vars
; i
> 0; i
--)
2853 if (!is_red_var
[i
] && !is_dead_var
[i
])
2855 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2856 if (!is_dead_geq
[e
] && pb
->geqs
[e
].coef
[i
])
2861 else if (pb
->geqs
[e
].coef
[i
] > 0)
2863 for (e2
= e
- 1; e2
>= 0; e2
--)
2864 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] < 0)
2869 for (e2
= e
- 1; e2
>= 0; e2
--)
2870 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] > 0)
2877 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2878 if (pb
->subs
[e3
].coef
[i
])
2884 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2885 if (pb
->eqs
[e3
].coef
[i
])
2891 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2892 fprintf (dump_file
, "a free red elimination of %s\n",
2893 omega_variable_to_str (pb
, i
));
2896 if (pb
->geqs
[e
].coef
[i
])
2897 is_dead_geq
[e
] = true;
2900 is_dead_var
[i
] = true;
2905 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2907 omega_delete_geq (pb
, e
, n_vars
);
2909 for (i
= n_vars
; i
> 0; i
--)
2911 omega_delete_variable (pb
, i
);
2913 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2915 fprintf (dump_file
, "\nafter free red eliminations:\n");
2916 omega_print_problem (dump_file
, pb
);
2917 fprintf (dump_file
, "\n");
2925 /* For equation EQ of the form "0 = EQN", insert in PB two
2926 inequalities "0 <= EQN" and "0 <= -EQN". */
2929 omega_convert_eq_to_geqs (omega_pb pb
, int eq
)
2933 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2934 fprintf (dump_file
, "Converting Eq to Geqs\n");
2936 /* Insert "0 <= EQN". */
2937 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2938 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2941 /* Insert "0 <= -EQN". */
2942 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2943 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2945 for (i
= 0; i
<= pb
->num_vars
; i
++)
2946 pb
->geqs
[pb
->num_geqs
].coef
[i
] *= -1;
2950 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2951 omega_print_problem (dump_file
, pb
);
2954 /* Eliminates variable I from PB. */
2957 omega_do_elimination (omega_pb pb
, int e
, int i
)
2959 eqn sub
= omega_alloc_eqns (0, 1);
2961 int n_vars
= pb
->num_vars
;
2963 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2964 fprintf (dump_file
, "eliminating variable %s\n",
2965 omega_variable_to_str (pb
, i
));
2967 omega_copy_eqn (sub
, &pb
->eqs
[e
], pb
->num_vars
);
2970 if (c
== 1 || c
== -1)
2972 if (pb
->eqs
[e
].color
== omega_red
)
2975 omega_substitute_red (pb
, sub
, i
, c
, &fB
);
2977 omega_convert_eq_to_geqs (pb
, e
);
2979 omega_delete_variable (pb
, i
);
2983 omega_substitute (pb
, sub
, i
, c
);
2984 omega_delete_variable (pb
, i
);
2992 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2993 fprintf (dump_file
, "performing non-exact elimination, c = %d\n", c
);
2995 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
2996 if (pb
->eqs
[e
].coef
[i
])
2998 eqn eqn
= &(pb
->eqs
[e
]);
3000 for (j
= n_vars
; j
>= 0; j
--)
3004 if (sub
->color
== omega_red
)
3005 eqn
->color
= omega_red
;
3006 for (j
= n_vars
; j
>= 0; j
--)
3007 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3010 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3011 if (pb
->geqs
[e
].coef
[i
])
3013 eqn eqn
= &(pb
->geqs
[e
]);
3016 if (sub
->color
== omega_red
)
3017 eqn
->color
= omega_red
;
3019 for (j
= n_vars
; j
>= 0; j
--)
3026 for (j
= n_vars
; j
>= 0; j
--)
3027 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3031 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3032 if (pb
->subs
[e
].coef
[i
])
3034 eqn eqn
= &(pb
->subs
[e
]);
3037 gcc_assert (sub
->color
== omega_black
);
3038 for (j
= n_vars
; j
>= 0; j
--)
3042 for (j
= n_vars
; j
>= 0; j
--)
3043 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3046 if (in_approximate_mode
)
3047 omega_delete_variable (pb
, i
);
3049 omega_convert_eq_to_geqs (pb
, e2
);
3052 omega_free_eqns (sub
, 1);
3055 /* Helper function for printing "sorry, no solution". */
3057 static inline enum omega_result
3058 omega_problem_has_no_solution (void)
3060 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3061 fprintf (dump_file
, "\nequations have no solution \n");
3066 /* Helper function: solve equations in PB one at a time, following the
3067 DESIRED_RES result. */
3069 static enum omega_result
3070 omega_solve_eq (omega_pb pb
, enum omega_result desired_res
)
3077 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && pb
->num_eqs
> 0)
3079 fprintf (dump_file
, "\nomega_solve_eq (%d, %d)\n",
3080 desired_res
, may_be_red
);
3081 omega_print_problem (dump_file
, pb
);
3082 fprintf (dump_file
, "\n");
3088 j
= pb
->num_eqs
- 1;
3094 while (i
<= j
&& pb
->eqs
[i
].color
== omega_red
)
3097 while (i
<= j
&& pb
->eqs
[j
].color
== omega_black
)
3103 eq
= omega_alloc_eqns (0, 1);
3104 omega_copy_eqn (eq
, &pb
->eqs
[i
], pb
->num_vars
);
3105 omega_copy_eqn (&pb
->eqs
[i
], &pb
->eqs
[j
], pb
->num_vars
);
3106 omega_copy_eqn (&pb
->eqs
[j
], eq
, pb
->num_vars
);
3107 omega_free_eqns (eq
, 1);
3113 /* Eliminate all EQ equations */
3114 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
3116 eqn eqn
= &(pb
->eqs
[e
]);
3119 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3120 fprintf (dump_file
, "----\n");
3122 for (i
= pb
->num_vars
; i
> 0; i
--)
3128 for (j
= i
- 1; j
> 0; j
--)
3132 /* i is the position of last nonzero coefficient,
3133 g is the coefficient of i,
3134 j is the position of next nonzero coefficient. */
3138 if (eqn
->coef
[0] % g
!= 0)
3139 return omega_problem_has_no_solution ();
3141 eqn
->coef
[0] = eqn
->coef
[0] / g
;
3144 omega_do_elimination (pb
, e
, i
);
3150 if (eqn
->coef
[0] != 0)
3151 return omega_problem_has_no_solution ();
3163 omega_do_elimination (pb
, e
, i
);
3169 bool promotion_possible
=
3170 (omega_safe_var_p (pb
, j
)
3171 && pb
->safe_vars
+ 1 == i
3172 && !omega_eqn_is_red (eqn
, desired_res
)
3173 && !in_approximate_mode
);
3175 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && promotion_possible
)
3176 fprintf (dump_file
, " Promotion possible\n");
3179 if (!omega_safe_var_p (pb
, j
))
3181 for (; g
!= 1 && !omega_safe_var_p (pb
, j
); j
--)
3182 g
= gcd (abs (eqn
->coef
[j
]), g
);
3185 else if (!omega_safe_var_p (pb
, i
))
3190 for (; g
!= 1 && j
> 0; j
--)
3191 g
= gcd (abs (eqn
->coef
[j
]), g
);
3195 if (eqn
->coef
[0] % g
!= 0)
3196 return omega_problem_has_no_solution ();
3198 for (j
= 0; j
<= pb
->num_vars
; j
++)
3208 for (e2
= e
- 1; e2
>= 0; e2
--)
3209 if (pb
->eqs
[e2
].coef
[i
])
3213 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
3214 if (pb
->geqs
[e2
].coef
[i
])
3218 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
3219 if (pb
->subs
[e2
].coef
[i
])
3224 bool change
= false;
3226 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3228 fprintf (dump_file
, "Ha! We own it! \n");
3229 omega_print_eq (dump_file
, pb
, eqn
);
3230 fprintf (dump_file
, " \n");
3236 for (j
= i
- 1; j
>= 0; j
--)
3238 int t
= int_mod (eqn
->coef
[j
], g
);
3243 if (t
!= eqn
->coef
[j
])
3252 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3253 fprintf (dump_file
, "So what?\n");
3258 omega_name_wild_card (pb
, i
);
3260 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3262 omega_print_eq (dump_file
, pb
, eqn
);
3263 fprintf (dump_file
, " \n");
3272 if (promotion_possible
)
3274 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3276 fprintf (dump_file
, "promoting %s to safety\n",
3277 omega_variable_to_str (pb
, i
));
3278 omega_print_vars (dump_file
, pb
);
3283 if (!omega_wildcard_p (pb
, i
))
3284 omega_name_wild_card (pb
, i
);
3286 promotion_possible
= false;
3291 if (g2
> 1 && !in_approximate_mode
)
3293 if (pb
->eqs
[e
].color
== omega_red
)
3295 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3296 fprintf (dump_file
, "handling red equality\n");
3299 omega_do_elimination (pb
, e
, i
);
3303 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3306 "adding equation to handle safe variable \n");
3307 omega_print_eq (dump_file
, pb
, eqn
);
3308 fprintf (dump_file
, "\n----\n");
3309 omega_print_problem (dump_file
, pb
);
3310 fprintf (dump_file
, "\n----\n");
3311 fprintf (dump_file
, "\n----\n");
3314 i
= omega_add_new_wild_card (pb
);
3316 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
3317 omega_init_eqn_zero (&pb
->eqs
[e
+ 1], pb
->num_vars
);
3318 omega_copy_eqn (&pb
->eqs
[e
+ 1], eqn
, pb
->safe_vars
);
3320 for (j
= pb
->num_vars
; j
>= 0; j
--)
3322 pb
->eqs
[e
+ 1].coef
[j
] = int_mod (pb
->eqs
[e
+ 1].coef
[j
], g2
);
3324 if (2 * pb
->eqs
[e
+ 1].coef
[j
] >= g2
)
3325 pb
->eqs
[e
+ 1].coef
[j
] -= g2
;
3328 pb
->eqs
[e
+ 1].coef
[i
] = g2
;
3331 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3332 omega_print_problem (dump_file
, pb
);
3341 /* Find variable to eliminate. */
3344 gcc_assert (in_approximate_mode
);
3346 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3348 fprintf (dump_file
, "non-exact elimination: ");
3349 omega_print_eq (dump_file
, pb
, eqn
);
3350 fprintf (dump_file
, "\n");
3351 omega_print_problem (dump_file
, pb
);
3354 for (i
= pb
->num_vars
; i
> sv
; i
--)
3355 if (pb
->eqs
[e
].coef
[i
] != 0)
3359 for (i
= pb
->num_vars
; i
> sv
; i
--)
3360 if (pb
->eqs
[e
].coef
[i
] == 1 || pb
->eqs
[e
].coef
[i
] == -1)
3366 omega_do_elimination (pb
, e
, i
);
3368 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && g2
> 1)
3370 fprintf (dump_file
, "result of non-exact elimination:\n");
3371 omega_print_problem (dump_file
, pb
);
3376 int factor
= (INT_MAX
);
3379 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3380 fprintf (dump_file
, "doing moding\n");
3382 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3383 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3388 for (; i
!= sv
; i
--)
3389 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3395 if (j
!= 0 && i
== sv
)
3397 omega_do_mod (pb
, 2, e
, j
);
3403 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3404 if (pb
->eqs
[e
].coef
[i
] != 0
3405 && factor
> abs (pb
->eqs
[e
].coef
[i
]) + 1)
3407 factor
= abs (pb
->eqs
[e
].coef
[i
]) + 1;
3413 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3414 fprintf (dump_file
, "should not have happened\n");
3418 omega_do_mod (pb
, factor
, e
, j
);
3419 /* Go back and try this equation again. */
3426 return omega_unknown
;
3429 /* Transform an inequation E to an equality, then solve DIFF problems
3430 based on PB, and only differing by the constant part that is
3431 diminished by one, trying to figure out which of the constants
3434 static enum omega_result
3435 parallel_splinter (omega_pb pb
, int e
, int diff
,
3436 enum omega_result desired_res
)
3438 omega_pb tmp_problem
;
3441 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3443 fprintf (dump_file
, "Using parallel splintering\n");
3444 omega_print_problem (dump_file
, pb
);
3447 tmp_problem
= XNEW (struct omega_pb_d
);
3448 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
], pb
->num_vars
);
3451 for (i
= 0; i
<= diff
; i
++)
3453 omega_copy_problem (tmp_problem
, pb
);
3455 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3457 fprintf (dump_file
, "Splinter # %i\n", i
);
3458 omega_print_problem (dump_file
, pb
);
3461 if (omega_solve_problem (tmp_problem
, desired_res
) == omega_true
)
3467 pb
->eqs
[0].coef
[0]--;
3474 /* Helper function: solve equations one at a time. */
3476 static enum omega_result
3477 omega_solve_geq (omega_pb pb
, enum omega_result desired_res
)
3481 enum omega_result result
;
3482 bool coupled_subscripts
= false;
3483 bool smoothed
= false;
3484 bool eliminate_again
;
3485 bool tried_eliminating_redundant
= false;
3487 if (desired_res
!= omega_simplify
)
3495 gcc_assert (desired_res
== omega_simplify
|| pb
->num_subs
== 0);
3497 /* Verify that there are not too many inequalities. */
3498 gcc_assert (pb
->num_geqs
<= OMEGA_MAX_GEQS
);
3500 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3502 fprintf (dump_file
, "\nomega_solve_geq (%d,%d):\n",
3503 desired_res
, please_no_equalities_in_simplified_problems
);
3504 omega_print_problem (dump_file
, pb
);
3505 fprintf (dump_file
, "\n");
3508 n_vars
= pb
->num_vars
;
3512 enum omega_eqn_color u_color
= omega_black
;
3513 enum omega_eqn_color l_color
= omega_black
;
3514 int upper_bound
= pos_infinity
;
3515 int lower_bound
= neg_infinity
;
3517 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3519 int a
= pb
->geqs
[e
].coef
[1];
3520 int c
= pb
->geqs
[e
].coef
[0];
3522 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3526 return omega_problem_has_no_solution ();
3533 if (lower_bound
< -c
3534 || (lower_bound
== -c
3535 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3538 l_color
= pb
->geqs
[e
].color
;
3544 c
= int_div (c
, -a
);
3547 || (upper_bound
== c
3548 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3551 u_color
= pb
->geqs
[e
].color
;
3556 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3558 fprintf (dump_file
, "upper bound = %d\n", upper_bound
);
3559 fprintf (dump_file
, "lower bound = %d\n", lower_bound
);
3562 if (lower_bound
> upper_bound
)
3563 return omega_problem_has_no_solution ();
3565 if (desired_res
== omega_simplify
)
3568 if (pb
->safe_vars
== 1)
3571 if (lower_bound
== upper_bound
3572 && u_color
== omega_black
3573 && l_color
== omega_black
)
3575 pb
->eqs
[0].coef
[0] = -lower_bound
;
3576 pb
->eqs
[0].coef
[1] = 1;
3577 pb
->eqs
[0].color
= omega_black
;
3579 return omega_solve_problem (pb
, desired_res
);
3583 if (lower_bound
> neg_infinity
)
3585 pb
->geqs
[0].coef
[0] = -lower_bound
;
3586 pb
->geqs
[0].coef
[1] = 1;
3587 pb
->geqs
[0].key
= 1;
3588 pb
->geqs
[0].color
= l_color
;
3589 pb
->geqs
[0].touched
= 0;
3593 if (upper_bound
< pos_infinity
)
3595 pb
->geqs
[pb
->num_geqs
].coef
[0] = upper_bound
;
3596 pb
->geqs
[pb
->num_geqs
].coef
[1] = -1;
3597 pb
->geqs
[pb
->num_geqs
].key
= -1;
3598 pb
->geqs
[pb
->num_geqs
].color
= u_color
;
3599 pb
->geqs
[pb
->num_geqs
].touched
= 0;
3607 omega_problem_reduced (pb
);
3611 if (original_problem
!= no_problem
3612 && l_color
== omega_black
3613 && u_color
== omega_black
3615 && lower_bound
== upper_bound
)
3617 pb
->eqs
[0].coef
[0] = -lower_bound
;
3618 pb
->eqs
[0].coef
[1] = 1;
3620 adding_equality_constraint (pb
, 0);
3626 if (!pb
->variables_freed
)
3628 pb
->variables_freed
= true;
3630 if (desired_res
!= omega_simplify
)
3631 omega_free_eliminations (pb
, 0);
3633 omega_free_eliminations (pb
, pb
->safe_vars
);
3635 n_vars
= pb
->num_vars
;
3641 switch (normalize_omega_problem (pb
))
3643 case normalize_false
:
3647 case normalize_coupled
:
3648 coupled_subscripts
= true;
3651 case normalize_uncoupled
:
3652 coupled_subscripts
= false;
3659 n_vars
= pb
->num_vars
;
3661 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3663 fprintf (dump_file
, "\nafter normalization:\n");
3664 omega_print_problem (dump_file
, pb
);
3665 fprintf (dump_file
, "\n");
3666 fprintf (dump_file
, "eliminating variable using Fourier-Motzkin.\n");
3670 int parallel_difference
= INT_MAX
;
3671 int best_parallel_eqn
= -1;
3672 int minC
, maxC
, minCj
= 0;
3673 int lower_bound_count
= 0;
3675 bool possible_easy_int_solution
;
3676 int max_splinters
= 1;
3678 bool lucky_exact
= false;
3679 int best
= (INT_MAX
);
3680 int j
= 0, jLe
= 0, jLowerBoundCount
= 0;
3683 eliminate_again
= false;
3685 if (pb
->num_eqs
> 0)
3686 return omega_solve_problem (pb
, desired_res
);
3688 if (!coupled_subscripts
)
3690 if (pb
->safe_vars
== 0)
3693 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3694 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
3695 omega_delete_geq (pb
, e
, n_vars
);
3697 pb
->num_vars
= pb
->safe_vars
;
3699 if (desired_res
== omega_simplify
)
3701 omega_problem_reduced (pb
);
3708 if (desired_res
!= omega_simplify
)
3713 if (pb
->num_geqs
== 0)
3715 if (desired_res
== omega_simplify
)
3717 pb
->num_vars
= pb
->safe_vars
;
3718 omega_problem_reduced (pb
);
3724 if (desired_res
== omega_simplify
&& n_vars
== pb
->safe_vars
)
3726 omega_problem_reduced (pb
);
3730 if (pb
->num_geqs
> OMEGA_MAX_GEQS
- 30
3731 || pb
->num_geqs
> 2 * n_vars
* n_vars
+ 4 * n_vars
+ 10)
3733 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3735 "TOO MANY EQUATIONS; "
3736 "%d equations, %d variables, "
3737 "ELIMINATING REDUNDANT ONES\n",
3738 pb
->num_geqs
, n_vars
);
3740 if (!omega_eliminate_redundant (pb
, false))
3743 n_vars
= pb
->num_vars
;
3745 if (pb
->num_eqs
> 0)
3746 return omega_solve_problem (pb
, desired_res
);
3748 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3749 fprintf (dump_file
, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3752 if (desired_res
!= omega_simplify
)
3757 for (i
= n_vars
; i
!= fv
; i
--)
3763 int upper_bound_count
= 0;
3765 lower_bound_count
= 0;
3768 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3769 if (pb
->geqs
[e
].coef
[i
] < 0)
3771 minC
= MIN (minC
, pb
->geqs
[e
].coef
[i
]);
3772 upper_bound_count
++;
3773 if (pb
->geqs
[e
].coef
[i
] < -1)
3781 else if (pb
->geqs
[e
].coef
[i
] > 0)
3783 maxC
= MAX (maxC
, pb
->geqs
[e
].coef
[i
]);
3784 lower_bound_count
++;
3786 if (pb
->geqs
[e
].coef
[i
] > 1)
3795 if (lower_bound_count
== 0
3796 || upper_bound_count
== 0)
3798 lower_bound_count
= 0;
3802 if (ub
>= 0 && lb
>= 0
3803 && pb
->geqs
[lb
].key
== -pb
->geqs
[ub
].key
)
3805 int Lc
= pb
->geqs
[lb
].coef
[i
];
3806 int Uc
= -pb
->geqs
[ub
].coef
[i
];
3808 Lc
* pb
->geqs
[ub
].coef
[0] + Uc
* pb
->geqs
[lb
].coef
[0];
3809 lucky
= (diff
>= (Uc
- 1) * (Lc
- 1));
3815 || in_approximate_mode
)
3817 score
= upper_bound_count
* lower_bound_count
;
3819 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3821 "For %s, exact, score = %d*%d, range = %d ... %d,"
3822 "\nlucky = %d, in_approximate_mode=%d \n",
3823 omega_variable_to_str (pb
, i
),
3825 lower_bound_count
, minC
, maxC
, lucky
,
3826 in_approximate_mode
);
3836 jLowerBoundCount
= lower_bound_count
;
3838 lucky_exact
= lucky
;
3845 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3847 "For %s, non-exact, score = %d*%d,"
3848 "range = %d ... %d \n",
3849 omega_variable_to_str (pb
, i
),
3851 lower_bound_count
, minC
, maxC
);
3853 score
= maxC
- minC
;
3861 jLowerBoundCount
= lower_bound_count
;
3866 if (lower_bound_count
== 0)
3868 omega_free_eliminations (pb
, pb
->safe_vars
);
3869 n_vars
= pb
->num_vars
;
3870 eliminate_again
= true;
3877 lower_bound_count
= jLowerBoundCount
;
3879 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3880 if (pb
->geqs
[e
].coef
[i
] > 0)
3882 if (pb
->geqs
[e
].coef
[i
] == -minC
)
3883 max_splinters
+= -minC
- 1;
3886 pos_mul_hwi ((pb
->geqs
[e
].coef
[i
] - 1),
3887 (-minC
- 1)) / (-minC
) + 1;
3891 /* Trying to produce exact elimination by finding redundant
3893 if (!exact
&& !tried_eliminating_redundant
)
3895 omega_eliminate_redundant (pb
, false);
3896 tried_eliminating_redundant
= true;
3897 eliminate_again
= true;
3900 tried_eliminating_redundant
= false;
3903 if (return_single_result
&& desired_res
== omega_simplify
&& !exact
)
3905 omega_problem_reduced (pb
);
3909 /* #ifndef Omega3 */
3910 /* Trying to produce exact elimination by finding redundant
3912 if (!exact
&& !tried_eliminating_redundant
)
3914 omega_eliminate_redundant (pb
, false);
3915 tried_eliminating_redundant
= true;
3918 tried_eliminating_redundant
= false;
3925 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
3926 if (pb
->geqs
[e1
].color
== omega_black
)
3927 for (e2
= e1
- 1; e2
>= 0; e2
--)
3928 if (pb
->geqs
[e2
].color
== omega_black
3929 && pb
->geqs
[e1
].key
== -pb
->geqs
[e2
].key
3930 && ((pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3931 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3932 / 2 < parallel_difference
))
3934 parallel_difference
=
3935 (pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3936 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3938 best_parallel_eqn
= e1
;
3941 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
3942 && best_parallel_eqn
>= 0)
3945 "Possible parallel projection, diff = %d, in ",
3946 parallel_difference
);
3947 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[best_parallel_eqn
]));
3948 fprintf (dump_file
, "\n");
3949 omega_print_problem (dump_file
, pb
);
3953 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3955 fprintf (dump_file
, "going to eliminate %s, (%d,%d,%d)\n",
3956 omega_variable_to_str (pb
, i
), i
, minC
,
3958 omega_print_problem (dump_file
, pb
);
3961 fprintf (dump_file
, "(a lucky exact elimination)\n");
3964 fprintf (dump_file
, "(an exact elimination)\n");
3966 fprintf (dump_file
, "Max # of splinters = %d\n", max_splinters
);
3969 gcc_assert (max_splinters
>= 1);
3971 if (!exact
&& desired_res
== omega_simplify
&& best_parallel_eqn
>= 0
3972 && parallel_difference
<= max_splinters
)
3973 return parallel_splinter (pb
, best_parallel_eqn
, parallel_difference
,
3980 int j
= pb
->num_vars
;
3982 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3984 fprintf (dump_file
, "Swapping %d and %d\n", i
, j
);
3985 omega_print_problem (dump_file
, pb
);
3988 std::swap (pb
->var
[i
], pb
->var
[j
]);
3990 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3991 if (pb
->geqs
[e
].coef
[i
] != pb
->geqs
[e
].coef
[j
])
3993 pb
->geqs
[e
].touched
= 1;
3994 std::swap (pb
->geqs
[e
].coef
[i
], pb
->geqs
[e
].coef
[j
]);
3997 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3998 if (pb
->subs
[e
].coef
[i
] != pb
->subs
[e
].coef
[j
])
3999 std::swap (pb
->subs
[e
].coef
[i
], pb
->subs
[e
].coef
[j
]);
4001 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4003 fprintf (dump_file
, "Swapping complete \n");
4004 omega_print_problem (dump_file
, pb
);
4005 fprintf (dump_file
, "\n");
4011 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4013 fprintf (dump_file
, "No swap needed\n");
4014 omega_print_problem (dump_file
, pb
);
4018 n_vars
= pb
->num_vars
;
4024 int upper_bound
= pos_infinity
;
4025 int lower_bound
= neg_infinity
;
4026 enum omega_eqn_color ub_color
= omega_black
;
4027 enum omega_eqn_color lb_color
= omega_black
;
4028 int topeqn
= pb
->num_geqs
- 1;
4029 int Lc
= pb
->geqs
[Le
].coef
[i
];
4031 for (Le
= topeqn
; Le
>= 0; Le
--)
4032 if ((Lc
= pb
->geqs
[Le
].coef
[i
]) == 0)
4034 if (pb
->geqs
[Le
].coef
[1] == 1)
4036 int constantTerm
= -pb
->geqs
[Le
].coef
[0];
4038 if (constantTerm
> lower_bound
||
4039 (constantTerm
== lower_bound
&&
4040 !omega_eqn_is_red (&pb
->geqs
[Le
], desired_res
)))
4042 lower_bound
= constantTerm
;
4043 lb_color
= pb
->geqs
[Le
].color
;
4046 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4048 if (pb
->geqs
[Le
].color
== omega_black
)
4049 fprintf (dump_file
, " :::=> %s >= %d\n",
4050 omega_variable_to_str (pb
, 1),
4054 " :::=> [%s >= %d]\n",
4055 omega_variable_to_str (pb
, 1),
4061 int constantTerm
= pb
->geqs
[Le
].coef
[0];
4062 if (constantTerm
< upper_bound
||
4063 (constantTerm
== upper_bound
4064 && !omega_eqn_is_red (&pb
->geqs
[Le
],
4067 upper_bound
= constantTerm
;
4068 ub_color
= pb
->geqs
[Le
].color
;
4071 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4073 if (pb
->geqs
[Le
].color
== omega_black
)
4074 fprintf (dump_file
, " :::=> %s <= %d\n",
4075 omega_variable_to_str (pb
, 1),
4079 " :::=> [%s <= %d]\n",
4080 omega_variable_to_str (pb
, 1),
4086 for (Ue
= topeqn
; Ue
>= 0; Ue
--)
4087 if (pb
->geqs
[Ue
].coef
[i
] < 0
4088 && pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4090 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4091 int coefficient
= pb
->geqs
[Ue
].coef
[1] * Lc
4092 + pb
->geqs
[Le
].coef
[1] * Uc
;
4093 int constantTerm
= pb
->geqs
[Ue
].coef
[0] * Lc
4094 + pb
->geqs
[Le
].coef
[0] * Uc
;
4096 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4098 omega_print_geq_extra (dump_file
, pb
,
4100 fprintf (dump_file
, "\n");
4101 omega_print_geq_extra (dump_file
, pb
,
4103 fprintf (dump_file
, "\n");
4106 if (coefficient
> 0)
4108 constantTerm
= -int_div (constantTerm
, coefficient
);
4110 if (constantTerm
> lower_bound
4111 || (constantTerm
== lower_bound
4112 && (desired_res
!= omega_simplify
4113 || (pb
->geqs
[Ue
].color
== omega_black
4114 && pb
->geqs
[Le
].color
== omega_black
))))
4116 lower_bound
= constantTerm
;
4117 lb_color
= (pb
->geqs
[Ue
].color
== omega_red
4118 || pb
->geqs
[Le
].color
== omega_red
)
4119 ? omega_red
: omega_black
;
4122 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4124 if (pb
->geqs
[Ue
].color
== omega_red
4125 || pb
->geqs
[Le
].color
== omega_red
)
4127 " ::=> [%s >= %d]\n",
4128 omega_variable_to_str (pb
, 1),
4133 omega_variable_to_str (pb
, 1),
4139 constantTerm
= int_div (constantTerm
, -coefficient
);
4140 if (constantTerm
< upper_bound
4141 || (constantTerm
== upper_bound
4142 && pb
->geqs
[Ue
].color
== omega_black
4143 && pb
->geqs
[Le
].color
== omega_black
))
4145 upper_bound
= constantTerm
;
4146 ub_color
= (pb
->geqs
[Ue
].color
== omega_red
4147 || pb
->geqs
[Le
].color
== omega_red
)
4148 ? omega_red
: omega_black
;
4152 && (dump_flags
& TDF_DETAILS
))
4154 if (pb
->geqs
[Ue
].color
== omega_red
4155 || pb
->geqs
[Le
].color
== omega_red
)
4157 " ::=> [%s <= %d]\n",
4158 omega_variable_to_str (pb
, 1),
4163 omega_variable_to_str (pb
, 1),
4171 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4173 " therefore, %c%d <= %c%s%c <= %d%c\n",
4174 lb_color
== omega_red
? '[' : ' ', lower_bound
,
4175 (lb_color
== omega_red
&& ub_color
== omega_black
)
4177 omega_variable_to_str (pb
, 1),
4178 (lb_color
== omega_black
&& ub_color
== omega_red
)
4180 upper_bound
, ub_color
== omega_red
? ']' : ' ');
4182 if (lower_bound
> upper_bound
)
4185 if (pb
->safe_vars
== 1)
4187 if (upper_bound
== lower_bound
4188 && !(ub_color
== omega_red
|| lb_color
== omega_red
)
4189 && !please_no_equalities_in_simplified_problems
)
4192 pb
->eqs
[0].coef
[1] = -1;
4193 pb
->eqs
[0].coef
[0] = upper_bound
;
4195 if (ub_color
== omega_red
4196 || lb_color
== omega_red
)
4197 pb
->eqs
[0].color
= omega_red
;
4199 if (desired_res
== omega_simplify
4200 && pb
->eqs
[0].color
== omega_black
)
4201 return omega_solve_problem (pb
, desired_res
);
4204 if (upper_bound
!= pos_infinity
)
4206 pb
->geqs
[0].coef
[1] = -1;
4207 pb
->geqs
[0].coef
[0] = upper_bound
;
4208 pb
->geqs
[0].color
= ub_color
;
4209 pb
->geqs
[0].key
= -1;
4210 pb
->geqs
[0].touched
= 0;
4214 if (lower_bound
!= neg_infinity
)
4216 pb
->geqs
[pb
->num_geqs
].coef
[1] = 1;
4217 pb
->geqs
[pb
->num_geqs
].coef
[0] = -lower_bound
;
4218 pb
->geqs
[pb
->num_geqs
].color
= lb_color
;
4219 pb
->geqs
[pb
->num_geqs
].key
= 1;
4220 pb
->geqs
[pb
->num_geqs
].touched
= 0;
4225 if (desired_res
== omega_simplify
)
4227 omega_problem_reduced (pb
);
4233 && (desired_res
!= omega_simplify
4234 || (lb_color
== omega_black
4235 && ub_color
== omega_black
))
4236 && original_problem
!= no_problem
4237 && lower_bound
== upper_bound
)
4239 for (i
= original_problem
->num_vars
; i
>= 0; i
--)
4240 if (original_problem
->var
[i
] == pb
->var
[1])
4246 e
= original_problem
->num_eqs
++;
4247 omega_init_eqn_zero (&original_problem
->eqs
[e
],
4248 original_problem
->num_vars
);
4249 original_problem
->eqs
[e
].coef
[i
] = -1;
4250 original_problem
->eqs
[e
].coef
[0] = upper_bound
;
4252 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4255 "adding equality %d to outer problem\n", e
);
4256 omega_print_problem (dump_file
, original_problem
);
4263 eliminate_again
= true;
4265 if (lower_bound_count
== 1)
4267 eqn lbeqn
= omega_alloc_eqns (0, 1);
4268 int Lc
= pb
->geqs
[Le
].coef
[i
];
4270 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4271 fprintf (dump_file
, "an inplace elimination\n");
4273 omega_copy_eqn (lbeqn
, &pb
->geqs
[Le
], (n_vars
+ 1));
4274 omega_delete_geq_extra (pb
, Le
, n_vars
+ 1);
4276 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4277 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4279 if (lbeqn
->key
== -pb
->geqs
[Ue
].key
)
4280 omega_delete_geq_extra (pb
, Ue
, n_vars
+ 1);
4284 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4285 pb
->geqs
[Ue
].touched
= 1;
4286 eliminate_again
= false;
4288 if (lbeqn
->color
== omega_red
)
4289 pb
->geqs
[Ue
].color
= omega_red
;
4291 for (k
= 0; k
<= n_vars
; k
++)
4292 pb
->geqs
[Ue
].coef
[k
] =
4293 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4294 mul_hwi (lbeqn
->coef
[k
], Uc
);
4296 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4298 omega_print_geq (dump_file
, pb
,
4300 fprintf (dump_file
, "\n");
4305 omega_free_eqns (lbeqn
, 1);
4310 int *dead_eqns
= XNEWVEC (int, OMEGA_MAX_GEQS
);
4311 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
4313 int top_eqn
= pb
->num_geqs
- 1;
4314 lower_bound_count
--;
4316 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4317 fprintf (dump_file
, "lower bound count = %d\n",
4320 for (Le
= top_eqn
; Le
>= 0; Le
--)
4321 if (pb
->geqs
[Le
].coef
[i
] > 0)
4323 int Lc
= pb
->geqs
[Le
].coef
[i
];
4324 for (Ue
= top_eqn
; Ue
>= 0; Ue
--)
4325 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4327 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4330 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4333 e2
= pb
->num_geqs
++;
4335 e2
= dead_eqns
[--num_dead
];
4337 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4339 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4342 "Le = %d, Ue = %d, gen = %d\n",
4344 omega_print_geq_extra (dump_file
, pb
,
4346 fprintf (dump_file
, "\n");
4347 omega_print_geq_extra (dump_file
, pb
,
4349 fprintf (dump_file
, "\n");
4352 eliminate_again
= false;
4354 for (k
= n_vars
; k
>= 0; k
--)
4355 pb
->geqs
[e2
].coef
[k
] =
4356 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4357 mul_hwi (pb
->geqs
[Le
].coef
[k
], Uc
);
4359 pb
->geqs
[e2
].coef
[n_vars
+ 1] = 0;
4360 pb
->geqs
[e2
].touched
= 1;
4362 if (pb
->geqs
[Ue
].color
== omega_red
4363 || pb
->geqs
[Le
].color
== omega_red
)
4364 pb
->geqs
[e2
].color
= omega_red
;
4366 pb
->geqs
[e2
].color
= omega_black
;
4368 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4370 omega_print_geq (dump_file
, pb
,
4372 fprintf (dump_file
, "\n");
4376 if (lower_bound_count
== 0)
4378 dead_eqns
[num_dead
++] = Ue
;
4380 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4381 fprintf (dump_file
, "Killed %d\n", Ue
);
4385 lower_bound_count
--;
4386 dead_eqns
[num_dead
++] = Le
;
4388 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4389 fprintf (dump_file
, "Killed %d\n", Le
);
4392 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4395 while (num_dead
> 0)
4396 is_dead
[dead_eqns
[--num_dead
]] = true;
4398 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4400 omega_delete_geq_extra (pb
, e
, n_vars
+ 1);
4411 rS
= omega_alloc_problem (0, 0);
4412 iS
= omega_alloc_problem (0, 0);
4414 possible_easy_int_solution
= true;
4416 for (e
= 0; e
< pb
->num_geqs
; e
++)
4417 if (pb
->geqs
[e
].coef
[i
] == 0)
4419 omega_copy_eqn (&(rS
->geqs
[e2
]), &pb
->geqs
[e
],
4421 omega_copy_eqn (&(iS
->geqs
[e2
]), &pb
->geqs
[e
],
4424 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4427 fprintf (dump_file
, "Copying (%d, %d): ", i
,
4428 pb
->geqs
[e
].coef
[i
]);
4429 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
4430 fprintf (dump_file
, "\n");
4431 for (t
= 0; t
<= n_vars
+ 1; t
++)
4432 fprintf (dump_file
, "%d ", pb
->geqs
[e
].coef
[t
]);
4433 fprintf (dump_file
, "\n");
4437 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4440 for (Le
= pb
->num_geqs
- 1; Le
>= 0; Le
--)
4441 if (pb
->geqs
[Le
].coef
[i
] > 0)
4442 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4443 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4446 int Lc
= pb
->geqs
[Le
].coef
[i
];
4447 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4449 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4452 rS
->geqs
[e2
].touched
= iS
->geqs
[e2
].touched
= 1;
4454 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4456 fprintf (dump_file
, "---\n");
4458 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4459 Le
, Lc
, Ue
, Uc
, e2
);
4460 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Le
]);
4461 fprintf (dump_file
, "\n");
4462 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Ue
]);
4463 fprintf (dump_file
, "\n");
4468 for (k
= n_vars
; k
>= 0; k
--)
4469 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4470 pb
->geqs
[Ue
].coef
[k
] + pb
->geqs
[Le
].coef
[k
];
4472 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1);
4476 for (k
= n_vars
; k
>= 0; k
--)
4477 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4478 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4479 mul_hwi (pb
->geqs
[Le
].coef
[k
], Uc
);
4481 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1) * (Lc
- 1);
4484 if (pb
->geqs
[Ue
].color
== omega_red
4485 || pb
->geqs
[Le
].color
== omega_red
)
4486 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_red
;
4488 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_black
;
4490 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4492 omega_print_geq (dump_file
, pb
, &(rS
->geqs
[e2
]));
4493 fprintf (dump_file
, "\n");
4497 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4499 else if (pb
->geqs
[Ue
].coef
[0] * Lc
+
4500 pb
->geqs
[Le
].coef
[0] * Uc
-
4501 (Uc
- 1) * (Lc
- 1) < 0)
4502 possible_easy_int_solution
= false;
4505 iS
->variables_initialized
= rS
->variables_initialized
= true;
4506 iS
->num_vars
= rS
->num_vars
= pb
->num_vars
;
4507 iS
->num_geqs
= rS
->num_geqs
= e2
;
4508 iS
->num_eqs
= rS
->num_eqs
= 0;
4509 iS
->num_subs
= rS
->num_subs
= pb
->num_subs
;
4510 iS
->safe_vars
= rS
->safe_vars
= pb
->safe_vars
;
4512 for (e
= n_vars
; e
>= 0; e
--)
4513 rS
->var
[e
] = pb
->var
[e
];
4515 for (e
= n_vars
; e
>= 0; e
--)
4516 iS
->var
[e
] = pb
->var
[e
];
4518 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
4520 omega_copy_eqn (&(rS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4521 omega_copy_eqn (&(iS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4525 n_vars
= pb
->num_vars
;
4527 if (desired_res
!= omega_true
)
4529 if (original_problem
== no_problem
)
4531 original_problem
= pb
;
4532 result
= omega_solve_geq (rS
, omega_false
);
4533 original_problem
= no_problem
;
4536 result
= omega_solve_geq (rS
, omega_false
);
4538 if (result
== omega_false
)
4545 if (pb
->num_eqs
> 0)
4547 /* An equality constraint must have been found */
4550 return omega_solve_problem (pb
, desired_res
);
4554 if (desired_res
!= omega_false
)
4557 int lower_bounds
= 0;
4558 int *lower_bound
= XNEWVEC (int, OMEGA_MAX_GEQS
);
4560 if (possible_easy_int_solution
)
4563 result
= omega_solve_geq (iS
, desired_res
);
4566 if (result
!= omega_false
)
4575 if (!exact
&& best_parallel_eqn
>= 0
4576 && parallel_difference
<= max_splinters
)
4581 return parallel_splinter (pb
, best_parallel_eqn
,
4582 parallel_difference
,
4586 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4587 fprintf (dump_file
, "have to do exact analysis\n");
4591 for (e
= 0; e
< pb
->num_geqs
; e
++)
4592 if (pb
->geqs
[e
].coef
[i
] > 1)
4593 lower_bound
[lower_bounds
++] = e
;
4595 /* Sort array LOWER_BOUND. */
4596 for (j
= 0; j
< lower_bounds
; j
++)
4600 for (int k
= j
+ 1; k
< lower_bounds
; k
++)
4601 if (pb
->geqs
[lower_bound
[smallest
]].coef
[i
] >
4602 pb
->geqs
[lower_bound
[k
]].coef
[i
])
4605 std::swap (lower_bound
[smallest
], lower_bound
[j
]);
4608 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4610 fprintf (dump_file
, "lower bound coefficients = ");
4612 for (j
= 0; j
< lower_bounds
; j
++)
4613 fprintf (dump_file
, " %d",
4614 pb
->geqs
[lower_bound
[j
]].coef
[i
]);
4616 fprintf (dump_file
, "\n");
4619 for (j
= 0; j
< lower_bounds
; j
++)
4623 int worst_lower_bound_constant
= -minC
;
4626 max_incr
= (((pb
->geqs
[e
].coef
[i
] - 1) *
4627 (worst_lower_bound_constant
- 1) - 1)
4628 / worst_lower_bound_constant
);
4629 /* max_incr += 2; */
4631 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4633 fprintf (dump_file
, "for equation ");
4634 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
4636 "\ntry decrements from 0 to %d\n",
4638 omega_print_problem (dump_file
, pb
);
4641 if (max_incr
> 50 && !smoothed
4642 && smooth_weird_equations (pb
))
4648 goto solve_geq_start
;
4651 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
],
4653 pb
->eqs
[0].color
= omega_black
;
4654 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
4655 pb
->geqs
[e
].touched
= 1;
4658 for (c
= max_incr
; c
>= 0; c
--)
4660 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4663 "trying next decrement of %d\n",
4665 omega_print_problem (dump_file
, pb
);
4668 omega_copy_problem (rS
, pb
);
4670 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4671 omega_print_problem (dump_file
, rS
);
4673 result
= omega_solve_problem (rS
, desired_res
);
4675 if (result
== omega_true
)
4684 pb
->eqs
[0].coef
[0]--;
4687 if (j
+ 1 < lower_bounds
)
4690 omega_copy_eqn (&pb
->geqs
[e
], &pb
->eqs
[0],
4692 pb
->geqs
[e
].touched
= 1;
4693 pb
->geqs
[e
].color
= omega_black
;
4694 omega_copy_problem (rS
, pb
);
4696 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4698 "exhausted lower bound, "
4699 "checking if still feasible ");
4701 result
= omega_solve_problem (rS
, omega_false
);
4703 if (result
== omega_false
)
4708 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4709 fprintf (dump_file
, "fall-off the end\n");
4721 return omega_unknown
;
4722 } while (eliminate_again
);
4726 /* Because the omega solver is recursive, this counter limits the
4728 static int omega_solve_depth
= 0;
4730 /* Return omega_true when the problem PB has a solution following the
4734 omega_solve_problem (omega_pb pb
, enum omega_result desired_res
)
4736 enum omega_result result
;
4738 gcc_assert (pb
->num_vars
>= pb
->safe_vars
);
4739 omega_solve_depth
++;
4741 if (desired_res
!= omega_simplify
)
4744 if (omega_solve_depth
> 50)
4746 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4749 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4750 omega_solve_depth
, in_approximate_mode
);
4751 omega_print_problem (dump_file
, pb
);
4756 if (omega_solve_eq (pb
, desired_res
) == omega_false
)
4758 omega_solve_depth
--;
4762 if (in_approximate_mode
&& !pb
->num_geqs
)
4764 result
= omega_true
;
4765 pb
->num_vars
= pb
->safe_vars
;
4766 omega_problem_reduced (pb
);
4769 result
= omega_solve_geq (pb
, desired_res
);
4771 omega_solve_depth
--;
4773 if (!omega_reduce_with_subs
)
4775 resurrect_subs (pb
);
4776 gcc_assert (please_no_equalities_in_simplified_problems
4777 || !result
|| pb
->num_subs
== 0);
4783 /* Return true if red equations constrain the set of possible solutions.
4784 We assume that there are solutions to the black equations by
4785 themselves, so if there is no solution to the combined problem, we
4789 omega_problem_has_red_equations (omega_pb pb
)
4795 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4797 fprintf (dump_file
, "Checking for red equations:\n");
4798 omega_print_problem (dump_file
, pb
);
4801 please_no_equalities_in_simplified_problems
++;
4804 if (omega_single_result
)
4805 return_single_result
++;
4807 create_color
= true;
4808 result
= (omega_simplify_problem (pb
) == omega_false
);
4810 if (omega_single_result
)
4811 return_single_result
--;
4814 please_no_equalities_in_simplified_problems
--;
4818 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4819 fprintf (dump_file
, "Gist is FALSE\n");
4824 pb
->eqs
[0].color
= omega_red
;
4826 for (i
= pb
->num_vars
; i
> 0; i
--)
4827 pb
->eqs
[0].coef
[i
] = 0;
4829 pb
->eqs
[0].coef
[0] = 1;
4833 free_red_eliminations (pb
);
4834 gcc_assert (pb
->num_eqs
== 0);
4836 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4837 if (pb
->geqs
[e
].color
== omega_red
)
4846 for (i
= pb
->safe_vars
; i
>= 1; i
--)
4851 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4853 if (pb
->geqs
[e
].coef
[i
])
4855 if (pb
->geqs
[e
].coef
[i
] > 0)
4856 lb
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4859 ub
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4863 if (ub
== 2 || lb
== 2)
4866 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4867 fprintf (dump_file
, "checks for upper/lower bounds worked!\n");
4869 if (!omega_reduce_with_subs
)
4871 resurrect_subs (pb
);
4872 gcc_assert (pb
->num_subs
== 0);
4880 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4882 "*** Doing potentially expensive elimination tests "
4883 "for red equations\n");
4885 please_no_equalities_in_simplified_problems
++;
4886 omega_eliminate_red (pb
, true);
4887 please_no_equalities_in_simplified_problems
--;
4890 gcc_assert (pb
->num_eqs
== 0);
4892 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4893 if (pb
->geqs
[e
].color
== omega_red
)
4899 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4903 "******************** Redundant Red Equations eliminated!!\n");
4906 "******************** Red Equations remain\n");
4908 omega_print_problem (dump_file
, pb
);
4911 if (!omega_reduce_with_subs
)
4913 normalize_return_type r
;
4915 resurrect_subs (pb
);
4916 r
= normalize_omega_problem (pb
);
4917 gcc_assert (r
!= normalize_false
);
4920 cleanout_wildcards (pb
);
4921 gcc_assert (pb
->num_subs
== 0);
4927 /* Calls omega_simplify_problem in approximate mode. */
4930 omega_simplify_approximate (omega_pb pb
)
4932 enum omega_result result
;
4934 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4935 fprintf (dump_file
, "(Entering approximate mode\n");
4937 in_approximate_mode
= true;
4938 result
= omega_simplify_problem (pb
);
4939 in_approximate_mode
= false;
4941 gcc_assert (pb
->num_vars
== pb
->safe_vars
);
4942 if (!omega_reduce_with_subs
)
4943 gcc_assert (pb
->num_subs
== 0);
4945 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4946 fprintf (dump_file
, "Leaving approximate mode)\n");
4952 /* Simplifies problem PB by eliminating redundant constraints and
4953 reducing the constraints system to a minimal form. Returns
4954 omega_true when the problem was successfully reduced, omega_unknown
4955 when the solver is unable to determine an answer. */
4958 omega_simplify_problem (omega_pb pb
)
4962 omega_found_reduction
= omega_false
;
4964 if (!pb
->variables_initialized
)
4965 omega_initialize_variables (pb
);
4967 if (next_key
* 3 > MAX_KEYS
)
4972 next_key
= OMEGA_MAX_VARS
+ 1;
4974 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4975 pb
->geqs
[e
].touched
= 1;
4977 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
4978 hash_master
[i
].touched
= -1;
4980 pb
->hash_version
= hash_version
;
4983 else if (pb
->hash_version
!= hash_version
)
4987 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4988 pb
->geqs
[e
].touched
= 1;
4990 pb
->hash_version
= hash_version
;
4993 if (pb
->num_vars
> pb
->num_eqs
+ 3 * pb
->safe_vars
)
4994 omega_free_eliminations (pb
, pb
->safe_vars
);
4996 if (!may_be_red
&& pb
->num_subs
== 0 && pb
->safe_vars
== 0)
4998 omega_found_reduction
= omega_solve_problem (pb
, omega_unknown
);
5000 if (omega_found_reduction
!= omega_false
5001 && !return_single_result
)
5005 (*omega_when_reduced
) (pb
);
5008 return omega_found_reduction
;
5011 omega_solve_problem (pb
, omega_simplify
);
5013 if (omega_found_reduction
!= omega_false
)
5015 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
5016 pb
->forwarding_address
[pb
->var
[i
]] = i
;
5018 for (i
= 0; i
< pb
->num_subs
; i
++)
5019 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
5022 if (!omega_reduce_with_subs
)
5023 gcc_assert (please_no_equalities_in_simplified_problems
5024 || omega_found_reduction
== omega_false
5025 || pb
->num_subs
== 0);
5027 return omega_found_reduction
;
5030 /* Make variable VAR unprotected: it then can be eliminated. */
5033 omega_unprotect_variable (omega_pb pb
, int var
)
5036 idx
= pb
->forwarding_address
[var
];
5043 if (idx
< pb
->num_subs
)
5045 omega_copy_eqn (&pb
->subs
[idx
], &pb
->subs
[pb
->num_subs
],
5047 pb
->forwarding_address
[pb
->subs
[idx
].key
] = -idx
- 1;
5052 int *bring_to_life
= XNEWVEC (int, OMEGA_MAX_VARS
);
5055 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5056 bring_to_life
[e
] = (pb
->subs
[e
].coef
[idx
] != 0);
5058 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
5059 if (bring_to_life
[e2
])
5064 if (pb
->safe_vars
< pb
->num_vars
)
5066 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5068 pb
->geqs
[e
].coef
[pb
->num_vars
] =
5069 pb
->geqs
[e
].coef
[pb
->safe_vars
];
5071 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5074 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5076 pb
->eqs
[e
].coef
[pb
->num_vars
] =
5077 pb
->eqs
[e
].coef
[pb
->safe_vars
];
5079 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5082 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5084 pb
->subs
[e
].coef
[pb
->num_vars
] =
5085 pb
->subs
[e
].coef
[pb
->safe_vars
];
5087 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5090 pb
->var
[pb
->num_vars
] = pb
->var
[pb
->safe_vars
];
5091 pb
->forwarding_address
[pb
->var
[pb
->num_vars
]] =
5096 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5097 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5099 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5100 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5102 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5103 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5106 pb
->var
[pb
->safe_vars
] = pb
->subs
[e2
].key
;
5107 pb
->forwarding_address
[pb
->subs
[e2
].key
] = pb
->safe_vars
;
5109 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e2
]),
5111 pb
->eqs
[pb
->num_eqs
++].coef
[pb
->safe_vars
] = -1;
5112 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5114 if (e2
< pb
->num_subs
- 1)
5115 omega_copy_eqn (&(pb
->subs
[e2
]), &(pb
->subs
[pb
->num_subs
- 1]),
5121 omega_unprotect_1 (pb
, &idx
, NULL
);
5122 free (bring_to_life
);
5125 chain_unprotect (pb
);
5128 /* Unprotects VAR and simplifies PB. */
5131 omega_constrain_variable_sign (omega_pb pb
, enum omega_eqn_color color
,
5134 int n_vars
= pb
->num_vars
;
5136 int k
= pb
->forwarding_address
[var
];
5145 omega_copy_eqn (&pb
->geqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5147 for (j
= 0; j
<= n_vars
; j
++)
5148 pb
->geqs
[e
].coef
[j
] *= sign
;
5150 pb
->geqs
[e
].coef
[0]--;
5151 pb
->geqs
[e
].touched
= 1;
5152 pb
->geqs
[e
].color
= color
;
5157 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5158 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5159 pb
->eqs
[e
].color
= color
;
5165 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
5166 pb
->geqs
[e
].coef
[k
] = sign
;
5167 pb
->geqs
[e
].coef
[0] = -1;
5168 pb
->geqs
[e
].touched
= 1;
5169 pb
->geqs
[e
].color
= color
;
5174 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5175 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5176 pb
->eqs
[e
].coef
[k
] = 1;
5177 pb
->eqs
[e
].color
= color
;
5180 omega_unprotect_variable (pb
, var
);
5181 return omega_simplify_problem (pb
);
5184 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5187 omega_constrain_variable_value (omega_pb pb
, enum omega_eqn_color color
,
5191 int k
= pb
->forwarding_address
[var
];
5197 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5198 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5199 pb
->eqs
[e
].coef
[0] -= value
;
5204 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5205 pb
->eqs
[e
].coef
[k
] = 1;
5206 pb
->eqs
[e
].coef
[0] = -value
;
5209 pb
->eqs
[e
].color
= color
;
5212 /* Return false when the upper and lower bounds are not coupled.
5213 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5217 omega_query_variable (omega_pb pb
, int i
, int *lower_bound
, int *upper_bound
)
5219 int n_vars
= pb
->num_vars
;
5222 bool coupled
= false;
5224 *lower_bound
= neg_infinity
;
5225 *upper_bound
= pos_infinity
;
5226 i
= pb
->forwarding_address
[i
];
5232 for (j
= 1; j
<= n_vars
; j
++)
5233 if (pb
->subs
[i
].coef
[j
] != 0)
5236 *upper_bound
= *lower_bound
= pb
->subs
[i
].coef
[0];
5240 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5241 if (pb
->subs
[e
].coef
[i
] != 0)
5247 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5248 if (pb
->eqs
[e
].coef
[i
] != 0)
5252 for (j
= 1; j
<= n_vars
; j
++)
5253 if (i
!= j
&& pb
->eqs
[e
].coef
[j
] != 0)
5264 *lower_bound
= *upper_bound
=
5265 -pb
->eqs
[e
].coef
[i
] * pb
->eqs
[e
].coef
[0];
5270 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5271 if (pb
->geqs
[e
].coef
[i
] != 0)
5273 if (pb
->geqs
[e
].key
== i
)
5274 *lower_bound
= MAX (*lower_bound
, -pb
->geqs
[e
].coef
[0]);
5276 else if (pb
->geqs
[e
].key
== -i
)
5277 *upper_bound
= MIN (*upper_bound
, pb
->geqs
[e
].coef
[0]);
5286 /* Sets the lower bound L and upper bound U for the values of variable
5287 I, and sets COULD_BE_ZERO to true if variable I might take value
5288 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5292 query_coupled_variable (omega_pb pb
, int i
, int *l
, int *u
,
5293 bool *could_be_zero
, int lower_bound
, int upper_bound
)
5300 /* Preconditions. */
5301 gcc_assert (abs (pb
->forwarding_address
[i
]) == 1
5302 && pb
->num_vars
+ pb
->num_subs
== 2
5303 && pb
->num_eqs
+ pb
->num_subs
== 1);
5305 /* Define variable I in terms of variable V. */
5306 if (pb
->forwarding_address
[i
] == -1)
5315 sign
= -eqn
->coef
[1];
5319 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5320 if (pb
->geqs
[e
].coef
[v
] != 0)
5322 if (pb
->geqs
[e
].coef
[v
] == 1)
5323 lower_bound
= MAX (lower_bound
, -pb
->geqs
[e
].coef
[0]);
5326 upper_bound
= MIN (upper_bound
, pb
->geqs
[e
].coef
[0]);
5329 if (lower_bound
> upper_bound
)
5337 if (lower_bound
== neg_infinity
)
5339 if (eqn
->coef
[v
] > 0)
5340 b1
= sign
* neg_infinity
;
5343 b1
= -sign
* neg_infinity
;
5346 b1
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * lower_bound
);
5348 if (upper_bound
== pos_infinity
)
5350 if (eqn
->coef
[v
] > 0)
5351 b2
= sign
* pos_infinity
;
5354 b2
= -sign
* pos_infinity
;
5357 b2
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * upper_bound
);
5359 *l
= MAX (*l
, b1
<= b2
? b1
: b2
);
5360 *u
= MIN (*u
, b1
<= b2
? b2
: b1
);
5362 *could_be_zero
= (*l
<= 0 && 0 <= *u
5363 && int_mod (eqn
->coef
[0], abs (eqn
->coef
[v
])) == 0);
5366 /* Return false when a lower bound L and an upper bound U for variable
5367 I in problem PB have been initialized. */
5370 omega_query_variable_bounds (omega_pb pb
, int i
, int *l
, int *u
)
5375 if (!omega_query_variable (pb
, i
, l
, u
)
5376 || (pb
->num_vars
== 1 && pb
->forwarding_address
[i
] == 1))
5379 if (abs (pb
->forwarding_address
[i
]) == 1
5380 && pb
->num_vars
+ pb
->num_subs
== 2
5381 && pb
->num_eqs
+ pb
->num_subs
== 1)
5384 query_coupled_variable (pb
, i
, l
, u
, &could_be_zero
, neg_infinity
,
5392 /* For problem PB, return an integer that represents the classic data
5393 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5394 masks that are added to the result. When DIST_KNOWN is true, DIST
5395 is set to the classic data dependence distance. LOWER_BOUND and
5396 UPPER_BOUND are bounds on the value of variable I, for example, it
5397 is possible to narrow the iteration domain with safe approximations
5398 of loop counts, and thus discard some data dependences that cannot
5402 omega_query_variable_signs (omega_pb pb
, int i
, int dd_lt
,
5403 int dd_eq
, int dd_gt
, int lower_bound
,
5404 int upper_bound
, bool *dist_known
, int *dist
)
5413 omega_query_variable (pb
, i
, &l
, &u
);
5414 query_coupled_variable (pb
, i
, &l
, &u
, &could_be_zero
, lower_bound
,
5433 *dist_known
= false;
5438 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5439 safe variables. Safe variables are not eliminated during the
5440 Fourier-Motzkin elimination. Safe variables are all those
5441 variables that are placed at the beginning of the array of
5442 variables: P->var[0, ..., NPROT - 1]. */
5445 omega_alloc_problem (int nvars
, int nprot
)
5449 gcc_assert (nvars
<= OMEGA_MAX_VARS
);
5450 omega_initialize ();
5452 /* Allocate and initialize PB. */
5453 pb
= XCNEW (struct omega_pb_d
);
5454 pb
->var
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5455 pb
->forwarding_address
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5456 pb
->geqs
= omega_alloc_eqns (0, OMEGA_MAX_GEQS
);
5457 pb
->eqs
= omega_alloc_eqns (0, OMEGA_MAX_EQS
);
5458 pb
->subs
= omega_alloc_eqns (0, OMEGA_MAX_VARS
+ 1);
5460 pb
->hash_version
= hash_version
;
5461 pb
->num_vars
= nvars
;
5462 pb
->safe_vars
= nprot
;
5463 pb
->variables_initialized
= false;
5464 pb
->variables_freed
= false;
5471 /* Keeps the state of the initialization. */
5472 static bool omega_initialized
= false;
5474 /* Initialization of the Omega solver. */
5477 omega_initialize (void)
5481 if (omega_initialized
)
5485 next_key
= OMEGA_MAX_VARS
+ 1;
5486 packing
= XCNEWVEC (int, OMEGA_MAX_VARS
);
5487 fast_lookup
= XCNEWVEC (int, MAX_KEYS
* 2);
5488 fast_lookup_red
= XCNEWVEC (int, MAX_KEYS
* 2);
5489 hash_master
= omega_alloc_eqns (0, HASH_TABLE_SIZE
);
5491 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
5492 hash_master
[i
].touched
= -1;
5494 sprintf (wild_name
[0], "1");
5495 sprintf (wild_name
[1], "a");
5496 sprintf (wild_name
[2], "b");
5497 sprintf (wild_name
[3], "c");
5498 sprintf (wild_name
[4], "d");
5499 sprintf (wild_name
[5], "e");
5500 sprintf (wild_name
[6], "f");
5501 sprintf (wild_name
[7], "g");
5502 sprintf (wild_name
[8], "h");
5503 sprintf (wild_name
[9], "i");
5504 sprintf (wild_name
[10], "j");
5505 sprintf (wild_name
[11], "k");
5506 sprintf (wild_name
[12], "l");
5507 sprintf (wild_name
[13], "m");
5508 sprintf (wild_name
[14], "n");
5509 sprintf (wild_name
[15], "o");
5510 sprintf (wild_name
[16], "p");
5511 sprintf (wild_name
[17], "q");
5512 sprintf (wild_name
[18], "r");
5513 sprintf (wild_name
[19], "s");
5514 sprintf (wild_name
[20], "t");
5515 sprintf (wild_name
[40 - 1], "alpha");
5516 sprintf (wild_name
[40 - 2], "beta");
5517 sprintf (wild_name
[40 - 3], "gamma");
5518 sprintf (wild_name
[40 - 4], "delta");
5519 sprintf (wild_name
[40 - 5], "tau");
5520 sprintf (wild_name
[40 - 6], "sigma");
5521 sprintf (wild_name
[40 - 7], "chi");
5522 sprintf (wild_name
[40 - 8], "omega");
5523 sprintf (wild_name
[40 - 9], "pi");
5524 sprintf (wild_name
[40 - 10], "ni");
5525 sprintf (wild_name
[40 - 11], "Alpha");
5526 sprintf (wild_name
[40 - 12], "Beta");
5527 sprintf (wild_name
[40 - 13], "Gamma");
5528 sprintf (wild_name
[40 - 14], "Delta");
5529 sprintf (wild_name
[40 - 15], "Tau");
5530 sprintf (wild_name
[40 - 16], "Sigma");
5531 sprintf (wild_name
[40 - 17], "Chi");
5532 sprintf (wild_name
[40 - 18], "Omega");
5533 sprintf (wild_name
[40 - 19], "xxx");
5535 omega_initialized
= true;