1 /* Source code for an implementation of the Omega test, an integer
2 programming algorithm for dependence analysis, by William Pugh,
3 appeared in Supercomputing '91 and CACM Aug 92.
5 This code has no license restrictions, and is considered public
8 Changes copyright (C) 2005, 2006, 2007, 2008, 2009,
9 2010 Free Software Foundation, Inc.
10 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
12 This file is part of GCC.
14 GCC is free software; you can redistribute it and/or modify it under
15 the terms of the GNU General Public License as published by the Free
16 Software Foundation; either version 3, or (at your option) any later
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING3. If not see
26 <http://www.gnu.org/licenses/>. */
28 /* For a detailed description, see "Constraint-Based Array Dependence
29 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
31 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
36 #include "coretypes.h"
38 #include "diagnostic-core.h"
39 #include "tree-pass.h"
42 /* When set to true, keep substitution variables. When set to false,
43 resurrect substitution variables (convert substitutions back to EQs). */
44 static bool omega_reduce_with_subs
= true;
46 /* When set to true, omega_simplify_problem checks for problem with no
47 solutions, calling verify_omega_pb. */
48 static bool omega_verify_simplification
= false;
50 /* When set to true, only produce a single simplified result. */
51 static bool omega_single_result
= false;
53 /* Set return_single_result to 1 when omega_single_result is true. */
54 static int return_single_result
= 0;
56 /* Hash table for equations generated by the solver. */
57 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
58 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
59 static eqn hash_master
;
61 static int hash_version
= 0;
63 /* Set to true for making the solver enter in approximation mode. */
64 static bool in_approximate_mode
= false;
66 /* When set to zero, the solver is allowed to add new equalities to
67 the problem to be solved. */
68 static int conservative
= 0;
70 /* Set to omega_true when the problem was successfully reduced, set to
71 omega_unknown when the solver is unable to determine an answer. */
72 static enum omega_result omega_found_reduction
;
74 /* Set to true when the solver is allowed to add omega_red equations. */
75 static bool create_color
= false;
77 /* Set to nonzero when the problem to be solved can be reduced. */
78 static int may_be_red
= 0;
80 /* When false, there should be no substitution equations in the
81 simplified problem. */
82 static int please_no_equalities_in_simplified_problems
= 0;
84 /* Variables names for pretty printing. */
85 static char wild_name
[200][40];
87 /* Pointer to the void problem. */
88 static omega_pb no_problem
= (omega_pb
) 0;
90 /* Pointer to the problem to be solved. */
91 static omega_pb original_problem
= (omega_pb
) 0;
94 /* Return the integer A divided by B. */
97 int_div (int a
, int b
)
102 return -((-a
+ b
- 1)/b
);
105 /* Return the integer A modulo B. */
108 int_mod (int a
, int b
)
110 return a
- b
* int_div (a
, b
);
113 /* Test whether equation E is red. */
116 omega_eqn_is_red (eqn e
, int desired_res
)
118 return (desired_res
== omega_simplify
&& e
->color
== omega_red
);
121 /* Return a string for VARIABLE. */
124 omega_var_to_str (int variable
)
126 if (0 <= variable
&& variable
<= 20)
127 return wild_name
[variable
];
129 if (-20 < variable
&& variable
< 0)
130 return wild_name
[40 + variable
];
132 /* Collapse all the entries that would have overflowed. */
133 return wild_name
[21];
136 /* Return a string for variable I in problem PB. */
139 omega_variable_to_str (omega_pb pb
, int i
)
141 return omega_var_to_str (pb
->var
[i
]);
144 /* Do nothing function: used for default initializations. */
147 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED
)
151 void (*omega_when_reduced
) (omega_pb
) = omega_no_procedure
;
153 /* Print to FILE from PB equation E with all its coefficients
157 omega_print_term (FILE *file
, omega_pb pb
, eqn e
, int c
)
161 int n
= pb
->num_vars
;
164 for (i
= 1; i
<= n
; i
++)
165 if (c
* e
->coef
[i
] > 0)
170 if (c
* e
->coef
[i
] == 1)
171 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
173 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
174 omega_variable_to_str (pb
, i
));
178 for (i
= 1; i
<= n
; i
++)
179 if (i
!= went_first
&& c
* e
->coef
[i
] != 0)
181 if (!first
&& c
* e
->coef
[i
] > 0)
182 fprintf (file
, " + ");
186 if (c
* e
->coef
[i
] == 1)
187 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
188 else if (c
* e
->coef
[i
] == -1)
189 fprintf (file
, " - %s", omega_variable_to_str (pb
, i
));
191 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
192 omega_variable_to_str (pb
, i
));
195 if (!first
&& c
* e
->coef
[0] > 0)
196 fprintf (file
, " + ");
198 if (first
|| c
* e
->coef
[0] != 0)
199 fprintf (file
, "%d", c
* e
->coef
[0]);
202 /* Print to FILE the equation E of problem PB. */
205 omega_print_eqn (FILE *file
, omega_pb pb
, eqn e
, bool test
, int extra
)
208 int n
= pb
->num_vars
+ extra
;
209 bool is_lt
= test
&& e
->coef
[0] == -1;
217 else if (e
->key
!= 0)
218 fprintf (file
, "%d: ", e
->key
);
221 if (e
->color
== omega_red
)
226 for (i
= is_lt
? 1 : 0; i
<= n
; i
++)
230 fprintf (file
, " + ");
235 fprintf (file
, "%d", -e
->coef
[i
]);
236 else if (e
->coef
[i
] == -1)
237 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
239 fprintf (file
, "%d * %s", -e
->coef
[i
],
240 omega_variable_to_str (pb
, i
));
255 fprintf (file
, " = ");
257 fprintf (file
, " < ");
259 fprintf (file
, " <= ");
263 for (i
= 0; i
<= n
; i
++)
267 fprintf (file
, " + ");
272 fprintf (file
, "%d", e
->coef
[i
]);
273 else if (e
->coef
[i
] == 1)
274 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
276 fprintf (file
, "%d * %s", e
->coef
[i
],
277 omega_variable_to_str (pb
, i
));
283 if (e
->color
== omega_red
)
287 /* Print to FILE all the variables of problem PB. */
290 omega_print_vars (FILE *file
, omega_pb pb
)
294 fprintf (file
, "variables = ");
296 if (pb
->safe_vars
> 0)
297 fprintf (file
, "protected (");
299 for (i
= 1; i
<= pb
->num_vars
; i
++)
301 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
303 if (i
== pb
->safe_vars
)
306 if (i
< pb
->num_vars
)
307 fprintf (file
, ", ");
310 fprintf (file
, "\n");
313 /* Debug problem PB. */
316 debug_omega_problem (omega_pb pb
)
318 omega_print_problem (stderr
, pb
);
321 /* Print to FILE problem PB. */
324 omega_print_problem (FILE *file
, omega_pb pb
)
328 if (!pb
->variables_initialized
)
329 omega_initialize_variables (pb
);
331 omega_print_vars (file
, pb
);
333 for (e
= 0; e
< pb
->num_eqs
; e
++)
335 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
336 fprintf (file
, "\n");
339 fprintf (file
, "Done with EQ\n");
341 for (e
= 0; e
< pb
->num_geqs
; e
++)
343 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
344 fprintf (file
, "\n");
347 fprintf (file
, "Done with GEQ\n");
349 for (e
= 0; e
< pb
->num_subs
; e
++)
351 eqn eq
= &pb
->subs
[e
];
353 if (eq
->color
== omega_red
)
357 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
359 fprintf (file
, "#%d := ", eq
->key
);
361 omega_print_term (file
, pb
, eq
, 1);
363 if (eq
->color
== omega_red
)
366 fprintf (file
, "\n");
370 /* Return the number of equations in PB tagged omega_red. */
373 omega_count_red_equations (omega_pb pb
)
378 for (e
= 0; e
< pb
->num_eqs
; e
++)
379 if (pb
->eqs
[e
].color
== omega_red
)
381 for (i
= pb
->num_vars
; i
> 0; i
--)
382 if (pb
->geqs
[e
].coef
[i
])
385 if (i
== 0 && pb
->geqs
[e
].coef
[0] == 1)
391 for (e
= 0; e
< pb
->num_geqs
; e
++)
392 if (pb
->geqs
[e
].color
== omega_red
)
395 for (e
= 0; e
< pb
->num_subs
; e
++)
396 if (pb
->subs
[e
].color
== omega_red
)
402 /* Print to FILE all the equations in PB that are tagged omega_red. */
405 omega_print_red_equations (FILE *file
, omega_pb pb
)
409 if (!pb
->variables_initialized
)
410 omega_initialize_variables (pb
);
412 omega_print_vars (file
, pb
);
414 for (e
= 0; e
< pb
->num_eqs
; e
++)
415 if (pb
->eqs
[e
].color
== omega_red
)
417 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
418 fprintf (file
, "\n");
421 for (e
= 0; e
< pb
->num_geqs
; e
++)
422 if (pb
->geqs
[e
].color
== omega_red
)
424 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
425 fprintf (file
, "\n");
428 for (e
= 0; e
< pb
->num_subs
; e
++)
429 if (pb
->subs
[e
].color
== omega_red
)
431 eqn eq
= &pb
->subs
[e
];
435 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
437 fprintf (file
, "#%d := ", eq
->key
);
439 omega_print_term (file
, pb
, eq
, 1);
440 fprintf (file
, "]\n");
444 /* Pretty print PB to FILE. */
447 omega_pretty_print_problem (FILE *file
, omega_pb pb
)
449 int e
, v
, v1
, v2
, v3
, t
;
450 bool *live
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
451 int stuffPrinted
= 0;
456 } partial_order_type
;
458 partial_order_type
**po
= XNEWVEC (partial_order_type
*,
459 OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
460 int **po_eq
= XNEWVEC (int *, OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
461 int *last_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
462 int *first_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
463 int *chain_length
= XNEWVEC (int, OMEGA_MAX_VARS
);
464 int *chain
= XNEWVEC (int, OMEGA_MAX_VARS
);
468 if (!pb
->variables_initialized
)
469 omega_initialize_variables (pb
);
471 if (pb
->num_vars
> 0)
473 omega_eliminate_redundant (pb
, false);
475 for (e
= 0; e
< pb
->num_eqs
; e
++)
478 fprintf (file
, "; ");
481 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
484 for (e
= 0; e
< pb
->num_geqs
; e
++)
489 for (v
= 1; v
<= pb
->num_vars
; v
++)
491 last_links
[v
] = first_links
[v
] = 0;
494 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
498 for (e
= 0; e
< pb
->num_geqs
; e
++)
501 for (v
= 1; v
<= pb
->num_vars
; v
++)
502 if (pb
->geqs
[e
].coef
[v
] == 1)
504 else if (pb
->geqs
[e
].coef
[v
] == -1)
509 while (v1
> 0 && pb
->geqs
[e
].coef
[v1
] == 0)
514 while (v2
> 0 && pb
->geqs
[e
].coef
[v2
] == 0)
519 while (v3
> 0 && pb
->geqs
[e
].coef
[v3
] == 0)
522 if (pb
->geqs
[e
].coef
[0] > 0 || pb
->geqs
[e
].coef
[0] < -1
524 || pb
->geqs
[e
].coef
[v1
] * pb
->geqs
[e
].coef
[v2
] != -1)
526 /* Not a partial order relation. */
530 if (pb
->geqs
[e
].coef
[v1
] == 1)
537 /* Relation is v1 <= v2 or v1 < v2. */
538 po
[v1
][v2
] = ((pb
->geqs
[e
].coef
[0] == 0) ? le
: lt
);
542 for (v
= 1; v
<= pb
->num_vars
; v
++)
543 chain_length
[v
] = last_links
[v
];
545 /* Just in case pb->num_vars <= 0. */
547 for (t
= 0; t
< pb
->num_vars
; t
++)
551 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
552 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
553 if (po
[v1
][v2
] != none
&&
554 chain_length
[v1
] <= chain_length
[v2
])
556 chain_length
[v1
] = chain_length
[v2
] + 1;
561 /* Caught in cycle. */
562 gcc_assert (!change
);
564 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
565 if (chain_length
[v1
] == 0)
570 for (v1
= 2; v1
<= pb
->num_vars
; v1
++)
571 if (chain_length
[v1
] + first_links
[v1
] >
572 chain_length
[v
] + first_links
[v
])
575 if (chain_length
[v
] + first_links
[v
] == 0)
579 fprintf (file
, "; ");
583 /* Chain starts at v. */
588 for (e
= 0; e
< pb
->num_geqs
; e
++)
589 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == 1)
592 fprintf (file
, ", ");
594 tmp
= pb
->geqs
[e
].coef
[v
];
595 pb
->geqs
[e
].coef
[v
] = 0;
596 omega_print_term (file
, pb
, &pb
->geqs
[e
], -1);
597 pb
->geqs
[e
].coef
[v
] = tmp
;
603 fprintf (file
, " <= ");
612 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
613 if (po
[v
][v2
] && chain_length
[v
] == 1 + chain_length
[v2
])
616 if (v2
> pb
->num_vars
)
623 fprintf (file
, "%s", omega_variable_to_str (pb
, chain
[0]));
625 for (multiprint
= false, i
= 1; i
< m
; i
++)
631 fprintf (file
, " <= ");
633 fprintf (file
, " < ");
635 fprintf (file
, "%s", omega_variable_to_str (pb
, v2
));
636 live
[po_eq
[v
][v2
]] = false;
638 if (!multiprint
&& i
< m
- 1)
639 for (v3
= 1; v3
<= pb
->num_vars
; v3
++)
641 if (v
== v3
|| v2
== v3
642 || po
[v
][v2
] != po
[v
][v3
]
643 || po
[v2
][chain
[i
+ 1]] != po
[v3
][chain
[i
+ 1]])
646 fprintf (file
, ",%s", omega_variable_to_str (pb
, v3
));
647 live
[po_eq
[v
][v3
]] = false;
648 live
[po_eq
[v3
][chain
[i
+ 1]]] = false;
656 /* Print last_links. */
661 for (e
= 0; e
< pb
->num_geqs
; e
++)
662 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == -1)
665 fprintf (file
, ", ");
667 fprintf (file
, " <= ");
669 tmp
= pb
->geqs
[e
].coef
[v
];
670 pb
->geqs
[e
].coef
[v
] = 0;
671 omega_print_term (file
, pb
, &pb
->geqs
[e
], 1);
672 pb
->geqs
[e
].coef
[v
] = tmp
;
679 for (e
= 0; e
< pb
->num_geqs
; e
++)
683 fprintf (file
, "; ");
685 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
688 for (e
= 0; e
< pb
->num_subs
; e
++)
690 eqn eq
= &pb
->subs
[e
];
693 fprintf (file
, "; ");
698 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
700 fprintf (file
, "#%d := ", eq
->key
);
702 omega_print_term (file
, pb
, eq
, 1);
715 /* Assign to variable I in PB the next wildcard name. The name of a
716 wildcard is a negative number. */
717 static int next_wild_card
= 0;
720 omega_name_wild_card (omega_pb pb
, int i
)
723 if (next_wild_card
< -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS
))
725 pb
->var
[i
] = next_wild_card
;
728 /* Return the index of the last protected (or safe) variable in PB,
729 after having added a new wildcard variable. */
732 omega_add_new_wild_card (omega_pb pb
)
735 int i
= ++pb
->safe_vars
;
738 /* Make a free place in the protected (safe) variables, by moving
739 the non protected variable pointed by "I" at the end, ie. at
740 offset pb->num_vars. */
741 if (pb
->num_vars
!= i
)
743 /* Move "I" for all the inequalities. */
744 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
746 if (pb
->geqs
[e
].coef
[i
])
747 pb
->geqs
[e
].touched
= 1;
749 pb
->geqs
[e
].coef
[pb
->num_vars
] = pb
->geqs
[e
].coef
[i
];
752 /* Move "I" for all the equalities. */
753 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
754 pb
->eqs
[e
].coef
[pb
->num_vars
] = pb
->eqs
[e
].coef
[i
];
756 /* Move "I" for all the substitutions. */
757 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
758 pb
->subs
[e
].coef
[pb
->num_vars
] = pb
->subs
[e
].coef
[i
];
760 /* Move the identifier. */
761 pb
->var
[pb
->num_vars
] = pb
->var
[i
];
764 /* Initialize at zero all the coefficients */
765 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
766 pb
->geqs
[e
].coef
[i
] = 0;
768 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
769 pb
->eqs
[e
].coef
[i
] = 0;
771 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
772 pb
->subs
[e
].coef
[i
] = 0;
774 /* And give it a name. */
775 omega_name_wild_card (pb
, i
);
779 /* Delete inequality E from problem PB that has N_VARS variables. */
782 omega_delete_geq (omega_pb pb
, int e
, int n_vars
)
784 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
786 fprintf (dump_file
, "Deleting %d (last:%d): ", e
, pb
->num_geqs
- 1);
787 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
788 fprintf (dump_file
, "\n");
791 if (e
< pb
->num_geqs
- 1)
792 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
797 /* Delete extra inequality E from problem PB that has N_VARS
801 omega_delete_geq_extra (omega_pb pb
, int e
, int n_vars
)
803 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
805 fprintf (dump_file
, "Deleting %d: ",e
);
806 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
807 fprintf (dump_file
, "\n");
810 if (e
< pb
->num_geqs
- 1)
811 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
817 /* Remove variable I from problem PB. */
820 omega_delete_variable (omega_pb pb
, int i
)
822 int n_vars
= pb
->num_vars
;
825 if (omega_safe_var_p (pb
, i
))
827 int j
= pb
->safe_vars
;
829 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
831 pb
->geqs
[e
].touched
= 1;
832 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[j
];
833 pb
->geqs
[e
].coef
[j
] = pb
->geqs
[e
].coef
[n_vars
];
836 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
838 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[j
];
839 pb
->eqs
[e
].coef
[j
] = pb
->eqs
[e
].coef
[n_vars
];
842 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
844 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[j
];
845 pb
->subs
[e
].coef
[j
] = pb
->subs
[e
].coef
[n_vars
];
848 pb
->var
[i
] = pb
->var
[j
];
849 pb
->var
[j
] = pb
->var
[n_vars
];
853 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
854 if (pb
->geqs
[e
].coef
[n_vars
])
856 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[n_vars
];
857 pb
->geqs
[e
].touched
= 1;
860 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
861 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[n_vars
];
863 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
864 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[n_vars
];
866 pb
->var
[i
] = pb
->var
[n_vars
];
869 if (omega_safe_var_p (pb
, i
))
875 /* Because the coefficients of an equation are sparse, PACKING records
876 indices for non null coefficients. */
879 /* Set up the coefficients of PACKING, following the coefficients of
880 equation EQN that has NUM_VARS variables. */
883 setup_packing (eqn eqn
, int num_vars
)
888 for (k
= num_vars
; k
>= 0; k
--)
895 /* Computes a linear combination of EQ and SUB at VAR with coefficient
896 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
897 non null indices of SUB stored in PACKING. */
900 omega_substitute_red_1 (eqn eq
, eqn sub
, int var
, int c
, bool *found_black
,
903 if (eq
->coef
[var
] != 0)
905 if (eq
->color
== omega_black
)
909 int j
, k
= eq
->coef
[var
];
913 for (j
= top_var
; j
>= 0; j
--)
914 eq
->coef
[packing
[j
]] -= sub
->coef
[packing
[j
]] * k
* c
;
919 /* Substitute in PB variable VAR with "C * SUB". */
922 omega_substitute_red (omega_pb pb
, eqn sub
, int var
, int c
, bool *found_black
)
924 int e
, top_var
= setup_packing (sub
, pb
->num_vars
);
926 *found_black
= false;
928 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
930 if (sub
->color
== omega_red
)
931 fprintf (dump_file
, "[");
933 fprintf (dump_file
, "substituting using %s := ",
934 omega_variable_to_str (pb
, var
));
935 omega_print_term (dump_file
, pb
, sub
, -c
);
937 if (sub
->color
== omega_red
)
938 fprintf (dump_file
, "]");
940 fprintf (dump_file
, "\n");
941 omega_print_vars (dump_file
, pb
);
944 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
946 eqn eqn
= &(pb
->eqs
[e
]);
948 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
950 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
952 omega_print_eq (dump_file
, pb
, eqn
);
953 fprintf (dump_file
, "\n");
957 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
959 eqn eqn
= &(pb
->geqs
[e
]);
961 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
963 if (eqn
->coef
[var
] && eqn
->color
== omega_red
)
966 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
968 omega_print_geq (dump_file
, pb
, eqn
);
969 fprintf (dump_file
, "\n");
973 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
975 eqn eqn
= &(pb
->subs
[e
]);
977 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
979 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
981 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
982 omega_print_term (dump_file
, pb
, eqn
, 1);
983 fprintf (dump_file
, "\n");
987 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
988 fprintf (dump_file
, "---\n\n");
990 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
994 /* Substitute in PB variable VAR with "C * SUB". */
997 omega_substitute (omega_pb pb
, eqn sub
, int var
, int c
)
1000 int top_var
= setup_packing (sub
, pb
->num_vars
);
1002 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1004 fprintf (dump_file
, "substituting using %s := ",
1005 omega_variable_to_str (pb
, var
));
1006 omega_print_term (dump_file
, pb
, sub
, -c
);
1007 fprintf (dump_file
, "\n");
1008 omega_print_vars (dump_file
, pb
);
1013 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1014 pb
->eqs
[e
].coef
[var
] = 0;
1016 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1017 if (pb
->geqs
[e
].coef
[var
] != 0)
1019 pb
->geqs
[e
].touched
= 1;
1020 pb
->geqs
[e
].coef
[var
] = 0;
1023 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1024 pb
->subs
[e
].coef
[var
] = 0;
1026 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1029 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1031 for (k
= pb
->num_vars
; k
>= 0; k
--)
1034 eqn
->key
= pb
->var
[var
];
1035 eqn
->color
= omega_black
;
1038 else if (top_var
== 0 && packing
[0] == 0)
1040 c
= -sub
->coef
[0] * c
;
1042 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1044 pb
->eqs
[e
].coef
[0] += pb
->eqs
[e
].coef
[var
] * c
;
1045 pb
->eqs
[e
].coef
[var
] = 0;
1048 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1049 if (pb
->geqs
[e
].coef
[var
] != 0)
1051 pb
->geqs
[e
].coef
[0] += pb
->geqs
[e
].coef
[var
] * c
;
1052 pb
->geqs
[e
].coef
[var
] = 0;
1053 pb
->geqs
[e
].touched
= 1;
1056 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1058 pb
->subs
[e
].coef
[0] += pb
->subs
[e
].coef
[var
] * c
;
1059 pb
->subs
[e
].coef
[var
] = 0;
1062 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1065 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1067 for (k
= pb
->num_vars
; k
>= 1; k
--)
1071 eqn
->key
= pb
->var
[var
];
1072 eqn
->color
= omega_black
;
1075 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1077 fprintf (dump_file
, "---\n\n");
1078 omega_print_problem (dump_file
, pb
);
1079 fprintf (dump_file
, "===\n\n");
1084 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1086 eqn eqn
= &(pb
->eqs
[e
]);
1087 int k
= eqn
->coef
[var
];
1094 for (j
= top_var
; j
>= 0; j
--)
1097 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1101 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1103 omega_print_eq (dump_file
, pb
, eqn
);
1104 fprintf (dump_file
, "\n");
1108 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1110 eqn eqn
= &(pb
->geqs
[e
]);
1111 int k
= eqn
->coef
[var
];
1119 for (j
= top_var
; j
>= 0; j
--)
1122 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1126 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1128 omega_print_geq (dump_file
, pb
, eqn
);
1129 fprintf (dump_file
, "\n");
1133 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1135 eqn eqn
= &(pb
->subs
[e
]);
1136 int k
= eqn
->coef
[var
];
1143 for (j
= top_var
; j
>= 0; j
--)
1146 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1150 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1152 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1153 omega_print_term (dump_file
, pb
, eqn
, 1);
1154 fprintf (dump_file
, "\n");
1158 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1160 fprintf (dump_file
, "---\n\n");
1161 omega_print_problem (dump_file
, pb
);
1162 fprintf (dump_file
, "===\n\n");
1165 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1168 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1171 for (k
= pb
->num_vars
; k
>= 0; k
--)
1172 eqn
->coef
[k
] = c
* (sub
->coef
[k
]);
1174 eqn
->key
= pb
->var
[var
];
1175 eqn
->color
= sub
->color
;
1180 /* Solve e = factor alpha for x_j and substitute. */
1183 omega_do_mod (omega_pb pb
, int factor
, int e
, int j
)
1186 eqn eq
= omega_alloc_eqns (0, 1);
1188 bool kill_j
= false;
1190 omega_copy_eqn (eq
, &pb
->eqs
[e
], pb
->num_vars
);
1192 for (k
= pb
->num_vars
; k
>= 0; k
--)
1194 eq
->coef
[k
] = int_mod (eq
->coef
[k
], factor
);
1196 if (2 * eq
->coef
[k
] >= factor
)
1197 eq
->coef
[k
] -= factor
;
1200 nfactor
= eq
->coef
[j
];
1202 if (omega_safe_var_p (pb
, j
) && !omega_wildcard_p (pb
, j
))
1204 i
= omega_add_new_wild_card (pb
);
1205 eq
->coef
[pb
->num_vars
] = eq
->coef
[i
];
1207 eq
->coef
[i
] = -factor
;
1212 eq
->coef
[j
] = -factor
;
1213 if (!omega_wildcard_p (pb
, j
))
1214 omega_name_wild_card (pb
, j
);
1217 omega_substitute (pb
, eq
, j
, nfactor
);
1219 for (k
= pb
->num_vars
; k
>= 0; k
--)
1220 pb
->eqs
[e
].coef
[k
] = pb
->eqs
[e
].coef
[k
] / factor
;
1223 omega_delete_variable (pb
, j
);
1225 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1227 fprintf (dump_file
, "Mod-ing and normalizing produces:\n");
1228 omega_print_problem (dump_file
, pb
);
1231 omega_free_eqns (eq
, 1);
1234 /* Multiplies by -1 inequality E. */
1237 omega_negate_geq (omega_pb pb
, int e
)
1241 for (i
= pb
->num_vars
; i
>= 0; i
--)
1242 pb
->geqs
[e
].coef
[i
] *= -1;
1244 pb
->geqs
[e
].coef
[0]--;
1245 pb
->geqs
[e
].touched
= 1;
1248 /* Returns OMEGA_TRUE when problem PB has a solution. */
1250 static enum omega_result
1251 verify_omega_pb (omega_pb pb
)
1253 enum omega_result result
;
1255 bool any_color
= false;
1256 omega_pb tmp_problem
= XNEW (struct omega_pb_d
);
1258 omega_copy_problem (tmp_problem
, pb
);
1259 tmp_problem
->safe_vars
= 0;
1260 tmp_problem
->num_subs
= 0;
1262 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1263 if (pb
->geqs
[e
].color
== omega_red
)
1269 if (please_no_equalities_in_simplified_problems
)
1273 original_problem
= no_problem
;
1275 original_problem
= pb
;
1277 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1279 fprintf (dump_file
, "verifying problem");
1282 fprintf (dump_file
, " (color mode)");
1284 fprintf (dump_file
, " :\n");
1285 omega_print_problem (dump_file
, pb
);
1288 result
= omega_solve_problem (tmp_problem
, omega_unknown
);
1289 original_problem
= no_problem
;
1292 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1294 if (result
!= omega_false
)
1295 fprintf (dump_file
, "verified problem\n");
1297 fprintf (dump_file
, "disproved problem\n");
1298 omega_print_problem (dump_file
, pb
);
1304 /* Add a new equality to problem PB at last position E. */
1307 adding_equality_constraint (omega_pb pb
, int e
)
1309 if (original_problem
!= no_problem
1310 && original_problem
!= pb
1314 int e2
= original_problem
->num_eqs
++;
1316 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1318 "adding equality constraint %d to outer problem\n", e2
);
1319 omega_init_eqn_zero (&original_problem
->eqs
[e2
],
1320 original_problem
->num_vars
);
1322 for (i
= pb
->num_vars
; i
>= 1; i
--)
1324 for (j
= original_problem
->num_vars
; j
>= 1; j
--)
1325 if (original_problem
->var
[j
] == pb
->var
[i
])
1330 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1331 fprintf (dump_file
, "retracting\n");
1332 original_problem
->num_eqs
--;
1335 original_problem
->eqs
[e2
].coef
[j
] = pb
->eqs
[e
].coef
[i
];
1338 original_problem
->eqs
[e2
].coef
[0] = pb
->eqs
[e
].coef
[0];
1340 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1341 omega_print_problem (dump_file
, original_problem
);
1345 static int *fast_lookup
;
1346 static int *fast_lookup_red
;
1350 normalize_uncoupled
,
1352 } normalize_return_type
;
1354 /* Normalizes PB by removing redundant constraints. Returns
1355 normalize_false when the constraints system has no solution,
1356 otherwise returns normalize_coupled or normalize_uncoupled. */
1358 static normalize_return_type
1359 normalize_omega_problem (omega_pb pb
)
1361 int e
, i
, j
, k
, n_vars
;
1362 int coupled_subscripts
= 0;
1364 n_vars
= pb
->num_vars
;
1366 for (e
= 0; e
< pb
->num_geqs
; e
++)
1368 if (!pb
->geqs
[e
].touched
)
1370 if (!single_var_geq (&pb
->geqs
[e
], n_vars
))
1371 coupled_subscripts
= 1;
1375 int g
, top_var
, i0
, hashCode
;
1376 int *p
= &packing
[0];
1378 for (k
= 1; k
<= n_vars
; k
++)
1379 if (pb
->geqs
[e
].coef
[k
])
1382 top_var
= (p
- &packing
[0]) - 1;
1386 if (pb
->geqs
[e
].coef
[0] < 0)
1388 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1390 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1391 fprintf (dump_file
, "\nequations have no solution \n");
1393 return normalize_false
;
1396 omega_delete_geq (pb
, e
, n_vars
);
1400 else if (top_var
== 0)
1402 int singlevar
= packing
[0];
1404 g
= pb
->geqs
[e
].coef
[singlevar
];
1408 pb
->geqs
[e
].coef
[singlevar
] = 1;
1409 pb
->geqs
[e
].key
= singlevar
;
1414 pb
->geqs
[e
].coef
[singlevar
] = -1;
1415 pb
->geqs
[e
].key
= -singlevar
;
1419 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1424 int hash_key_multiplier
= 31;
1426 coupled_subscripts
= 1;
1429 g
= pb
->geqs
[e
].coef
[i
];
1430 hashCode
= g
* (i
+ 3);
1435 for (; i0
>= 0; i0
--)
1440 x
= pb
->geqs
[e
].coef
[i
];
1441 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1456 for (; i0
>= 0; i0
--)
1460 x
= pb
->geqs
[e
].coef
[i
];
1461 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1466 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1469 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1470 hashCode
= pb
->geqs
[e
].coef
[i
] * (i
+ 3);
1472 for (; i0
>= 0; i0
--)
1475 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1476 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3)
1477 + pb
->geqs
[e
].coef
[i
];
1481 g2
= abs (hashCode
);
1483 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1485 fprintf (dump_file
, "Hash code = %d, eqn = ", hashCode
);
1486 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1487 fprintf (dump_file
, "\n");
1490 j
= g2
% HASH_TABLE_SIZE
;
1493 eqn proto
= &(hash_master
[j
]);
1495 if (proto
->touched
== g2
)
1497 if (proto
->coef
[0] == top_var
)
1500 for (i0
= top_var
; i0
>= 0; i0
--)
1504 if (pb
->geqs
[e
].coef
[i
] != proto
->coef
[i
])
1508 for (i0
= top_var
; i0
>= 0; i0
--)
1512 if (pb
->geqs
[e
].coef
[i
] != -proto
->coef
[i
])
1519 pb
->geqs
[e
].key
= proto
->key
;
1521 pb
->geqs
[e
].key
= -proto
->key
;
1526 else if (proto
->touched
< 0)
1528 omega_init_eqn_zero (proto
, pb
->num_vars
);
1530 for (i0
= top_var
; i0
>= 0; i0
--)
1533 proto
->coef
[i
] = pb
->geqs
[e
].coef
[i
];
1536 for (i0
= top_var
; i0
>= 0; i0
--)
1539 proto
->coef
[i
] = -pb
->geqs
[e
].coef
[i
];
1542 proto
->coef
[0] = top_var
;
1543 proto
->touched
= g2
;
1545 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1546 fprintf (dump_file
, " constraint key = %d\n",
1549 proto
->key
= next_key
++;
1551 /* Too many hash keys generated. */
1552 gcc_assert (proto
->key
<= MAX_KEYS
);
1555 pb
->geqs
[e
].key
= proto
->key
;
1557 pb
->geqs
[e
].key
= -proto
->key
;
1562 j
= (j
+ 1) % HASH_TABLE_SIZE
;
1566 pb
->geqs
[e
].touched
= 0;
1570 int eKey
= pb
->geqs
[e
].key
;
1574 int cTerm
= pb
->geqs
[e
].coef
[0];
1575 e2
= fast_lookup
[MAX_KEYS
- eKey
];
1577 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1578 && pb
->geqs
[e2
].color
== omega_black
)
1580 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1582 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1584 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1585 fprintf (dump_file
, "\n");
1586 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1588 "\nequations have no solution \n");
1590 return normalize_false
;
1593 if (pb
->geqs
[e2
].coef
[0] == -cTerm
1595 || pb
->geqs
[e
].color
== omega_black
))
1597 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1599 if (pb
->geqs
[e
].color
== omega_black
)
1600 adding_equality_constraint (pb
, pb
->num_eqs
);
1602 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1606 e2
= fast_lookup_red
[MAX_KEYS
- eKey
];
1608 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1609 && pb
->geqs
[e2
].color
== omega_red
)
1611 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1613 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1615 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1616 fprintf (dump_file
, "\n");
1617 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1619 "\nequations have no solution \n");
1621 return normalize_false
;
1624 if (pb
->geqs
[e2
].coef
[0] == -cTerm
&& create_color
)
1626 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1628 pb
->eqs
[pb
->num_eqs
].color
= omega_red
;
1630 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1634 e2
= fast_lookup
[MAX_KEYS
+ eKey
];
1636 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1637 && pb
->geqs
[e2
].color
== omega_black
)
1639 if (pb
->geqs
[e2
].coef
[0] > cTerm
)
1641 if (pb
->geqs
[e
].color
== omega_black
)
1643 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1646 "Removing Redundant Equation: ");
1647 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1648 fprintf (dump_file
, "\n");
1650 "[a] Made Redundant by: ");
1651 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1652 fprintf (dump_file
, "\n");
1654 pb
->geqs
[e2
].coef
[0] = cTerm
;
1655 omega_delete_geq (pb
, e
, n_vars
);
1662 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1664 fprintf (dump_file
, "Removing Redundant Equation: ");
1665 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1666 fprintf (dump_file
, "\n");
1667 fprintf (dump_file
, "[b] Made Redundant by: ");
1668 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1669 fprintf (dump_file
, "\n");
1671 omega_delete_geq (pb
, e
, n_vars
);
1677 e2
= fast_lookup_red
[MAX_KEYS
+ eKey
];
1679 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1680 && pb
->geqs
[e2
].color
== omega_red
)
1682 if (pb
->geqs
[e2
].coef
[0] >= cTerm
)
1684 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1686 fprintf (dump_file
, "Removing Redundant Equation: ");
1687 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1688 fprintf (dump_file
, "\n");
1689 fprintf (dump_file
, "[c] Made Redundant by: ");
1690 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1691 fprintf (dump_file
, "\n");
1693 pb
->geqs
[e2
].coef
[0] = cTerm
;
1694 pb
->geqs
[e2
].color
= pb
->geqs
[e
].color
;
1696 else if (pb
->geqs
[e
].color
== omega_red
)
1698 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1700 fprintf (dump_file
, "Removing Redundant Equation: ");
1701 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1702 fprintf (dump_file
, "\n");
1703 fprintf (dump_file
, "[d] Made Redundant by: ");
1704 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1705 fprintf (dump_file
, "\n");
1708 omega_delete_geq (pb
, e
, n_vars
);
1715 if (pb
->geqs
[e
].color
== omega_red
)
1716 fast_lookup_red
[MAX_KEYS
+ eKey
] = e
;
1718 fast_lookup
[MAX_KEYS
+ eKey
] = e
;
1722 create_color
= false;
1723 return coupled_subscripts
? normalize_coupled
: normalize_uncoupled
;
1726 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1727 of variables in EQN. */
1730 divide_eqn_by_gcd (eqn eqn
, int n_vars
)
1734 for (var
= n_vars
; var
>= 0; var
--)
1735 g
= gcd (abs (eqn
->coef
[var
]), g
);
1738 for (var
= n_vars
; var
>= 0; var
--)
1739 eqn
->coef
[var
] = eqn
->coef
[var
] / g
;
1742 /* Rewrite some non-safe variables in function of protected
1743 wildcard variables. */
1746 cleanout_wildcards (omega_pb pb
)
1749 int n_vars
= pb
->num_vars
;
1750 bool renormalize
= false;
1752 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1753 for (i
= n_vars
; !omega_safe_var_p (pb
, i
); i
--)
1754 if (pb
->eqs
[e
].coef
[i
] != 0)
1756 /* i is the last nonzero non-safe variable. */
1758 for (j
= i
- 1; !omega_safe_var_p (pb
, j
); j
--)
1759 if (pb
->eqs
[e
].coef
[j
] != 0)
1762 /* j is the next nonzero non-safe variable, or points
1763 to a safe variable: it is then a wildcard variable. */
1766 if (omega_safe_var_p (pb
, j
))
1768 eqn sub
= &(pb
->eqs
[e
]);
1769 int c
= pb
->eqs
[e
].coef
[i
];
1773 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1776 "Found a single wild card equality: ");
1777 omega_print_eq (dump_file
, pb
, &pb
->eqs
[e
]);
1778 fprintf (dump_file
, "\n");
1779 omega_print_problem (dump_file
, pb
);
1782 for (e2
= pb
->num_eqs
- 1; e2
>= 0; e2
--)
1783 if (e
!= e2
&& pb
->eqs
[e2
].coef
[i
]
1784 && (pb
->eqs
[e2
].color
== omega_red
1785 || (pb
->eqs
[e2
].color
== omega_black
1786 && pb
->eqs
[e
].color
== omega_black
)))
1788 eqn eqn
= &(pb
->eqs
[e2
]);
1791 for (var
= n_vars
; var
>= 0; var
--)
1792 eqn
->coef
[var
] *= a
;
1796 for (var
= n_vars
; var
>= 0; var
--)
1797 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1800 divide_eqn_by_gcd (eqn
, n_vars
);
1803 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
1804 if (pb
->geqs
[e2
].coef
[i
]
1805 && (pb
->geqs
[e2
].color
== omega_red
1806 || (pb
->eqs
[e
].color
== omega_black
1807 && pb
->geqs
[e2
].color
== omega_black
)))
1809 eqn eqn
= &(pb
->geqs
[e2
]);
1812 for (var
= n_vars
; var
>= 0; var
--)
1813 eqn
->coef
[var
] *= a
;
1817 for (var
= n_vars
; var
>= 0; var
--)
1818 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1825 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
1826 if (pb
->subs
[e2
].coef
[i
]
1827 && (pb
->subs
[e2
].color
== omega_red
1828 || (pb
->subs
[e2
].color
== omega_black
1829 && pb
->eqs
[e
].color
== omega_black
)))
1831 eqn eqn
= &(pb
->subs
[e2
]);
1834 for (var
= n_vars
; var
>= 0; var
--)
1835 eqn
->coef
[var
] *= a
;
1839 for (var
= n_vars
; var
>= 0; var
--)
1840 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1843 divide_eqn_by_gcd (eqn
, n_vars
);
1846 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1848 fprintf (dump_file
, "cleaned-out wildcard: ");
1849 omega_print_problem (dump_file
, pb
);
1856 normalize_omega_problem (pb
);
1859 /* Swap values contained in I and J. */
1862 swap (int *i
, int *j
)
1870 /* Swap values contained in I and J. */
1873 bswap (bool *i
, bool *j
)
1881 /* Make variable IDX unprotected in PB, by swapping its index at the
1882 PB->safe_vars rank. */
1885 omega_unprotect_1 (omega_pb pb
, int *idx
, bool *unprotect
)
1887 /* If IDX is protected... */
1888 if (*idx
< pb
->safe_vars
)
1890 /* ... swap its index with the last non protected index. */
1891 int j
= pb
->safe_vars
;
1894 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1896 pb
->geqs
[e
].touched
= 1;
1897 swap (&pb
->geqs
[e
].coef
[*idx
], &pb
->geqs
[e
].coef
[j
]);
1900 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1901 swap (&pb
->eqs
[e
].coef
[*idx
], &pb
->eqs
[e
].coef
[j
]);
1903 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1904 swap (&pb
->subs
[e
].coef
[*idx
], &pb
->subs
[e
].coef
[j
]);
1907 bswap (&unprotect
[*idx
], &unprotect
[j
]);
1909 swap (&pb
->var
[*idx
], &pb
->var
[j
]);
1910 pb
->forwarding_address
[pb
->var
[*idx
]] = *idx
;
1911 pb
->forwarding_address
[pb
->var
[j
]] = j
;
1915 /* The variable at pb->safe_vars is also unprotected now. */
1919 /* During the Fourier-Motzkin elimination some variables are
1920 substituted with other variables. This function resurrects the
1921 substituted variables in PB. */
1924 resurrect_subs (omega_pb pb
)
1926 if (pb
->num_subs
> 0
1927 && please_no_equalities_in_simplified_problems
== 0)
1931 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1934 "problem reduced, bringing variables back to life\n");
1935 omega_print_problem (dump_file
, pb
);
1938 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
1939 if (omega_wildcard_p (pb
, i
))
1940 omega_unprotect_1 (pb
, &i
, NULL
);
1944 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1945 if (single_var_geq (&pb
->geqs
[e
], pb
->num_vars
))
1947 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
1948 pb
->geqs
[e
].key
+= (pb
->geqs
[e
].key
> 0 ? m
: -m
);
1952 pb
->geqs
[e
].touched
= 1;
1953 pb
->geqs
[e
].key
= 0;
1956 for (i
= pb
->num_vars
; !omega_safe_var_p (pb
, i
); i
--)
1958 pb
->var
[i
+ m
] = pb
->var
[i
];
1960 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1961 pb
->geqs
[e
].coef
[i
+ m
] = pb
->geqs
[e
].coef
[i
];
1963 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1964 pb
->eqs
[e
].coef
[i
+ m
] = pb
->eqs
[e
].coef
[i
];
1966 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1967 pb
->subs
[e
].coef
[i
+ m
] = pb
->subs
[e
].coef
[i
];
1970 for (i
= pb
->safe_vars
+ m
; !omega_safe_var_p (pb
, i
); i
--)
1972 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1973 pb
->geqs
[e
].coef
[i
] = 0;
1975 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1976 pb
->eqs
[e
].coef
[i
] = 0;
1978 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1979 pb
->subs
[e
].coef
[i
] = 0;
1984 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1986 pb
->var
[pb
->safe_vars
+ 1 + e
] = pb
->subs
[e
].key
;
1987 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e
]),
1989 pb
->eqs
[pb
->num_eqs
].coef
[pb
->safe_vars
+ 1 + e
] = -1;
1990 pb
->eqs
[pb
->num_eqs
].color
= omega_black
;
1992 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1994 fprintf (dump_file
, "brought back: ");
1995 omega_print_eq (dump_file
, pb
, &pb
->eqs
[pb
->num_eqs
]);
1996 fprintf (dump_file
, "\n");
2000 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2006 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2008 fprintf (dump_file
, "variables brought back to life\n");
2009 omega_print_problem (dump_file
, pb
);
2012 cleanout_wildcards (pb
);
2017 implies (unsigned int a
, unsigned int b
)
2019 return (a
== (a
& b
));
2022 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2023 extra step is performed. Returns omega_false when there exist no
2024 solution, omega_true otherwise. */
2027 omega_eliminate_redundant (omega_pb pb
, bool expensive
)
2029 int c
, e
, e1
, e2
, e3
, p
, q
, i
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2030 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2031 omega_pb tmp_problem
;
2033 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2034 unsigned int *peqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2035 unsigned int *zeqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2036 unsigned int *neqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2038 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2039 unsigned int pp
, pz
, pn
;
2041 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2043 fprintf (dump_file
, "in eliminate Redundant:\n");
2044 omega_print_problem (dump_file
, pb
);
2047 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2052 peqs
[e
] = zeqs
[e
] = neqs
[e
] = 0;
2054 for (i
= pb
->num_vars
; i
>= 1; i
--)
2056 if (pb
->geqs
[e
].coef
[i
] > 0)
2058 else if (pb
->geqs
[e
].coef
[i
] < 0)
2068 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2070 for (e2
= e1
- 1; e2
>= 0; e2
--)
2073 for (p
= pb
->num_vars
; p
> 1; p
--)
2074 for (q
= p
- 1; q
> 0; q
--)
2075 if ((alpha
= pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
]
2076 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]) != 0)
2082 pz
= ((zeqs
[e1
] & zeqs
[e2
]) | (peqs
[e1
] & neqs
[e2
])
2083 | (neqs
[e1
] & peqs
[e2
]));
2084 pp
= peqs
[e1
] | peqs
[e2
];
2085 pn
= neqs
[e1
] | neqs
[e2
];
2087 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2088 if (e3
!= e1
&& e3
!= e2
)
2090 if (!implies (zeqs
[e3
], pz
))
2093 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2094 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2095 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2096 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2099 if (alpha1
* alpha2
<= 0)
2111 /* Trying to prove e3 is redundant. */
2112 if (!implies (peqs
[e3
], pp
)
2113 || !implies (neqs
[e3
], pn
))
2116 if (pb
->geqs
[e3
].color
== omega_black
2117 && (pb
->geqs
[e1
].color
== omega_red
2118 || pb
->geqs
[e2
].color
== omega_red
))
2121 for (k
= pb
->num_vars
; k
>= 1; k
--)
2122 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2123 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2124 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2127 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2128 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2130 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2132 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2135 "found redundant inequality\n");
2137 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2138 alpha1
, alpha2
, alpha3
);
2140 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2141 fprintf (dump_file
, "\n");
2142 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2143 fprintf (dump_file
, "\n=> ");
2144 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2145 fprintf (dump_file
, "\n\n");
2153 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2154 or trying to prove e3 < 0, and therefore the
2155 problem has no solutions. */
2156 if (!implies (peqs
[e3
], pn
)
2157 || !implies (neqs
[e3
], pp
))
2160 if (pb
->geqs
[e1
].color
== omega_red
2161 || pb
->geqs
[e2
].color
== omega_red
2162 || pb
->geqs
[e3
].color
== omega_red
)
2165 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2166 for (k
= pb
->num_vars
; k
>= 1; k
--)
2167 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2168 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2169 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2172 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2173 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2175 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0]))
2177 /* We just proved e3 < 0, so no solutions exist. */
2178 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2181 "found implied over tight inequality\n");
2183 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2184 alpha1
, alpha2
, -alpha3
);
2185 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2186 fprintf (dump_file
, "\n");
2187 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2188 fprintf (dump_file
, "\n=> not ");
2189 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2190 fprintf (dump_file
, "\n\n");
2198 else if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] - 1))
2200 /* We just proved that e3 <=0, so e3 = 0. */
2201 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2204 "found implied tight inequality\n");
2206 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2207 alpha1
, alpha2
, -alpha3
);
2208 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2209 fprintf (dump_file
, "\n");
2210 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2211 fprintf (dump_file
, "\n=> inverse ");
2212 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2213 fprintf (dump_file
, "\n\n");
2216 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++],
2217 &pb
->geqs
[e3
], pb
->num_vars
);
2218 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2219 adding_equality_constraint (pb
, pb
->num_eqs
- 1);
2227 /* Delete the inequalities that were marked as dead. */
2228 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2230 omega_delete_geq (pb
, e
, pb
->num_vars
);
2233 goto eliminate_redundant_done
;
2235 tmp_problem
= XNEW (struct omega_pb_d
);
2238 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2240 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2243 "checking equation %d to see if it is redundant: ", e
);
2244 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2245 fprintf (dump_file
, "\n");
2248 omega_copy_problem (tmp_problem
, pb
);
2249 omega_negate_geq (tmp_problem
, e
);
2250 tmp_problem
->safe_vars
= 0;
2251 tmp_problem
->variables_freed
= false;
2253 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2254 omega_delete_geq (pb
, e
, pb
->num_vars
);
2260 if (!omega_reduce_with_subs
)
2262 resurrect_subs (pb
);
2263 gcc_assert (please_no_equalities_in_simplified_problems
2264 || pb
->num_subs
== 0);
2267 eliminate_redundant_done
:
2275 /* For each inequality that has coefficients bigger than 20, try to
2276 create a new constraint that cannot be derived from the original
2277 constraint and that has smaller coefficients. Add the new
2278 constraint at the end of geqs. Return the number of inequalities
2279 that have been added to PB. */
2282 smooth_weird_equations (omega_pb pb
)
2284 int e1
, e2
, e3
, p
, q
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2289 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2290 if (pb
->geqs
[e1
].color
== omega_black
)
2294 for (v
= pb
->num_vars
; v
>= 1; v
--)
2295 if (pb
->geqs
[e1
].coef
[v
] != 0 && abs (pb
->geqs
[e1
].coef
[v
]) < g
)
2296 g
= abs (pb
->geqs
[e1
].coef
[v
]);
2303 for (v
= pb
->num_vars
; v
>= 1; v
--)
2304 pb
->geqs
[e3
].coef
[v
] = int_div (6 * pb
->geqs
[e1
].coef
[v
] + g
/ 2,
2307 pb
->geqs
[e3
].color
= omega_black
;
2308 pb
->geqs
[e3
].touched
= 1;
2310 pb
->geqs
[e3
].coef
[0] = 9997;
2312 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2314 fprintf (dump_file
, "Checking to see if we can derive: ");
2315 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2316 fprintf (dump_file
, "\n from: ");
2317 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e1
]);
2318 fprintf (dump_file
, "\n");
2321 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
2322 if (e1
!= e2
&& pb
->geqs
[e2
].color
== omega_black
)
2324 for (p
= pb
->num_vars
; p
> 1; p
--)
2326 for (q
= p
- 1; q
> 0; q
--)
2329 (pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
] -
2330 pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]);
2339 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2340 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2341 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2342 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2345 if (alpha1
* alpha2
<= 0)
2357 /* Try to prove e3 is redundant: verify
2358 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2359 for (k
= pb
->num_vars
; k
>= 1; k
--)
2360 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2361 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2362 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2365 c
= alpha1
* pb
->geqs
[e1
].coef
[0]
2366 + alpha2
* pb
->geqs
[e2
].coef
[0];
2368 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2369 pb
->geqs
[e3
].coef
[0] = int_div (c
, alpha3
);
2374 if (pb
->geqs
[e3
].coef
[0] < 9997)
2379 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2382 "Smoothing weird equations; adding:\n");
2383 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2384 fprintf (dump_file
, "\nto:\n");
2385 omega_print_problem (dump_file
, pb
);
2386 fprintf (dump_file
, "\n\n");
2394 /* Replace tuples of inequalities, that define upper and lower half
2395 spaces, with an equation. */
2398 coalesce (omega_pb pb
)
2403 int found_something
= 0;
2405 for (e
= 0; e
< pb
->num_geqs
; e
++)
2406 if (pb
->geqs
[e
].color
== omega_red
)
2412 is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2414 for (e
= 0; e
< pb
->num_geqs
; e
++)
2417 for (e
= 0; e
< pb
->num_geqs
; e
++)
2418 if (pb
->geqs
[e
].color
== omega_red
2419 && !pb
->geqs
[e
].touched
)
2420 for (e2
= e
+ 1; e2
< pb
->num_geqs
; e2
++)
2421 if (!pb
->geqs
[e2
].touched
2422 && pb
->geqs
[e
].key
== -pb
->geqs
[e2
].key
2423 && pb
->geqs
[e
].coef
[0] == -pb
->geqs
[e2
].coef
[0]
2424 && pb
->geqs
[e2
].color
== omega_red
)
2426 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++], &pb
->geqs
[e
],
2428 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2434 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2436 omega_delete_geq (pb
, e
, pb
->num_vars
);
2438 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && found_something
)
2440 fprintf (dump_file
, "Coalesced pb->geqs into %d EQ's:\n",
2442 omega_print_problem (dump_file
, pb
);
2448 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2449 true, continue to eliminate all the red inequalities. */
2452 omega_eliminate_red (omega_pb pb
, bool eliminate_all
)
2454 int e
, e2
, e3
, i
, j
, k
, a
, alpha1
, alpha2
;
2456 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2459 omega_pb tmp_problem
;
2461 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2463 fprintf (dump_file
, "in eliminate RED:\n");
2464 omega_print_problem (dump_file
, pb
);
2467 if (pb
->num_eqs
> 0)
2468 omega_simplify_problem (pb
);
2470 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2473 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2474 if (pb
->geqs
[e
].color
== omega_black
&& !is_dead
[e
])
2475 for (e2
= e
- 1; e2
>= 0; e2
--)
2476 if (pb
->geqs
[e2
].color
== omega_black
2481 for (i
= pb
->num_vars
; i
> 1; i
--)
2482 for (j
= i
- 1; j
> 0; j
--)
2483 if ((a
= (pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e2
].coef
[j
]
2484 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e
].coef
[j
])) != 0)
2490 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2493 "found two equations to combine, i = %s, ",
2494 omega_variable_to_str (pb
, i
));
2495 fprintf (dump_file
, "j = %s, alpha = %d\n",
2496 omega_variable_to_str (pb
, j
), a
);
2497 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2498 fprintf (dump_file
, "\n");
2499 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2500 fprintf (dump_file
, "\n");
2503 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2504 if (pb
->geqs
[e3
].color
== omega_red
)
2506 alpha1
= (pb
->geqs
[e2
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2507 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2508 alpha2
= -(pb
->geqs
[e
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2509 - pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2511 if ((a
> 0 && alpha1
> 0 && alpha2
> 0)
2512 || (a
< 0 && alpha1
< 0 && alpha2
< 0))
2514 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2517 "alpha1 = %d, alpha2 = %d;"
2518 "comparing against: ",
2520 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2521 fprintf (dump_file
, "\n");
2524 for (k
= pb
->num_vars
; k
>= 0; k
--)
2526 c
= (alpha1
* pb
->geqs
[e
].coef
[k
]
2527 + alpha2
* pb
->geqs
[e2
].coef
[k
]);
2529 if (c
!= a
* pb
->geqs
[e3
].coef
[k
])
2532 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && k
> 0)
2533 fprintf (dump_file
, " %s: %d, %d\n",
2534 omega_variable_to_str (pb
, k
), c
,
2535 a
* pb
->geqs
[e3
].coef
[k
]);
2540 ((a
> 0 && c
< a
* pb
->geqs
[e3
].coef
[k
])
2541 || (a
< 0 && c
> a
* pb
->geqs
[e3
].coef
[k
]))))
2543 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2547 "red equation#%d is dead "
2548 "(%d dead so far, %d remain)\n",
2550 pb
->num_geqs
- dead_count
);
2551 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2552 fprintf (dump_file
, "\n");
2553 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2554 fprintf (dump_file
, "\n");
2555 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2556 fprintf (dump_file
, "\n");
2564 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2566 omega_delete_geq (pb
, e
, pb
->num_vars
);
2570 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2572 fprintf (dump_file
, "in eliminate RED, easy tests done:\n");
2573 omega_print_problem (dump_file
, pb
);
2576 for (red_found
= 0, e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2577 if (pb
->geqs
[e
].color
== omega_red
)
2582 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2583 fprintf (dump_file
, "fast checks worked\n");
2585 if (!omega_reduce_with_subs
)
2586 gcc_assert (please_no_equalities_in_simplified_problems
2587 || pb
->num_subs
== 0);
2592 if (!omega_verify_simplification
2593 && verify_omega_pb (pb
) == omega_false
)
2597 tmp_problem
= XNEW (struct omega_pb_d
);
2599 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2600 if (pb
->geqs
[e
].color
== omega_red
)
2602 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2605 "checking equation %d to see if it is redundant: ", e
);
2606 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2607 fprintf (dump_file
, "\n");
2610 omega_copy_problem (tmp_problem
, pb
);
2611 omega_negate_geq (tmp_problem
, e
);
2612 tmp_problem
->safe_vars
= 0;
2613 tmp_problem
->variables_freed
= false;
2614 tmp_problem
->num_subs
= 0;
2616 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2618 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2619 fprintf (dump_file
, "it is redundant\n");
2620 omega_delete_geq (pb
, e
, pb
->num_vars
);
2624 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2625 fprintf (dump_file
, "it is not redundant\n");
2629 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2630 fprintf (dump_file
, "no need to check other red equations\n");
2638 /* omega_simplify_problem (pb); */
2640 if (!omega_reduce_with_subs
)
2641 gcc_assert (please_no_equalities_in_simplified_problems
2642 || pb
->num_subs
== 0);
2645 /* Transform some wildcard variables to non-safe variables. */
2648 chain_unprotect (omega_pb pb
)
2651 bool *unprotect
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2653 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2655 unprotect
[i
] = omega_wildcard_p (pb
, i
);
2657 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2658 if (pb
->subs
[e
].coef
[i
])
2659 unprotect
[i
] = false;
2662 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2664 fprintf (dump_file
, "Doing chain reaction unprotection\n");
2665 omega_print_problem (dump_file
, pb
);
2667 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2669 fprintf (dump_file
, "unprotecting %s\n",
2670 omega_variable_to_str (pb
, i
));
2673 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2675 omega_unprotect_1 (pb
, &i
, unprotect
);
2677 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2679 fprintf (dump_file
, "After chain reactions\n");
2680 omega_print_problem (dump_file
, pb
);
2686 /* Reduce problem PB. */
2689 omega_problem_reduced (omega_pb pb
)
2691 if (omega_verify_simplification
2692 && !in_approximate_mode
2693 && verify_omega_pb (pb
) == omega_false
)
2696 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS
)
2697 && !omega_eliminate_redundant (pb
, true))
2700 omega_found_reduction
= omega_true
;
2702 if (!please_no_equalities_in_simplified_problems
)
2705 if (omega_reduce_with_subs
2706 || please_no_equalities_in_simplified_problems
)
2707 chain_unprotect (pb
);
2709 resurrect_subs (pb
);
2711 if (!return_single_result
)
2715 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2716 pb
->forwarding_address
[pb
->var
[i
]] = i
;
2718 for (i
= 0; i
< pb
->num_subs
; i
++)
2719 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
2721 (*omega_when_reduced
) (pb
);
2724 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2726 fprintf (dump_file
, "-------------------------------------------\n");
2727 fprintf (dump_file
, "problem reduced:\n");
2728 omega_print_problem (dump_file
, pb
);
2729 fprintf (dump_file
, "-------------------------------------------\n");
2733 /* Eliminates all the free variables for problem PB, that is all the
2734 variables from FV to PB->NUM_VARS. */
2737 omega_free_eliminations (omega_pb pb
, int fv
)
2739 bool try_again
= true;
2741 int n_vars
= pb
->num_vars
;
2747 for (i
= n_vars
; i
> fv
; i
--)
2749 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2750 if (pb
->geqs
[e
].coef
[i
])
2755 else if (pb
->geqs
[e
].coef
[i
] > 0)
2757 for (e2
= e
- 1; e2
>= 0; e2
--)
2758 if (pb
->geqs
[e2
].coef
[i
] < 0)
2763 for (e2
= e
- 1; e2
>= 0; e2
--)
2764 if (pb
->geqs
[e2
].coef
[i
] > 0)
2771 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2772 if (pb
->subs
[e3
].coef
[i
])
2778 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2779 if (pb
->eqs
[e3
].coef
[i
])
2785 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2786 fprintf (dump_file
, "a free elimination of %s\n",
2787 omega_variable_to_str (pb
, i
));
2791 omega_delete_geq (pb
, e
, n_vars
);
2793 for (e
--; e
>= 0; e
--)
2794 if (pb
->geqs
[e
].coef
[i
])
2795 omega_delete_geq (pb
, e
, n_vars
);
2797 try_again
= (i
< n_vars
);
2800 omega_delete_variable (pb
, i
);
2801 n_vars
= pb
->num_vars
;
2806 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2808 fprintf (dump_file
, "\nafter free eliminations:\n");
2809 omega_print_problem (dump_file
, pb
);
2810 fprintf (dump_file
, "\n");
2814 /* Do free red eliminations. */
2817 free_red_eliminations (omega_pb pb
)
2819 bool try_again
= true;
2821 int n_vars
= pb
->num_vars
;
2822 bool *is_red_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2823 bool *is_dead_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2824 bool *is_dead_geq
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2826 for (i
= n_vars
; i
> 0; i
--)
2828 is_red_var
[i
] = false;
2829 is_dead_var
[i
] = false;
2832 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2834 is_dead_geq
[e
] = false;
2836 if (pb
->geqs
[e
].color
== omega_red
)
2837 for (i
= n_vars
; i
> 0; i
--)
2838 if (pb
->geqs
[e
].coef
[i
] != 0)
2839 is_red_var
[i
] = true;
2845 for (i
= n_vars
; i
> 0; i
--)
2846 if (!is_red_var
[i
] && !is_dead_var
[i
])
2848 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2849 if (!is_dead_geq
[e
] && pb
->geqs
[e
].coef
[i
])
2854 else if (pb
->geqs
[e
].coef
[i
] > 0)
2856 for (e2
= e
- 1; e2
>= 0; e2
--)
2857 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] < 0)
2862 for (e2
= e
- 1; e2
>= 0; e2
--)
2863 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] > 0)
2870 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2871 if (pb
->subs
[e3
].coef
[i
])
2877 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2878 if (pb
->eqs
[e3
].coef
[i
])
2884 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2885 fprintf (dump_file
, "a free red elimination of %s\n",
2886 omega_variable_to_str (pb
, i
));
2889 if (pb
->geqs
[e
].coef
[i
])
2890 is_dead_geq
[e
] = true;
2893 is_dead_var
[i
] = true;
2898 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2900 omega_delete_geq (pb
, e
, n_vars
);
2902 for (i
= n_vars
; i
> 0; i
--)
2904 omega_delete_variable (pb
, i
);
2906 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2908 fprintf (dump_file
, "\nafter free red eliminations:\n");
2909 omega_print_problem (dump_file
, pb
);
2910 fprintf (dump_file
, "\n");
2918 /* For equation EQ of the form "0 = EQN", insert in PB two
2919 inequalities "0 <= EQN" and "0 <= -EQN". */
2922 omega_convert_eq_to_geqs (omega_pb pb
, int eq
)
2926 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2927 fprintf (dump_file
, "Converting Eq to Geqs\n");
2929 /* Insert "0 <= EQN". */
2930 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2931 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2934 /* Insert "0 <= -EQN". */
2935 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2936 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2938 for (i
= 0; i
<= pb
->num_vars
; i
++)
2939 pb
->geqs
[pb
->num_geqs
].coef
[i
] *= -1;
2943 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2944 omega_print_problem (dump_file
, pb
);
2947 /* Eliminates variable I from PB. */
2950 omega_do_elimination (omega_pb pb
, int e
, int i
)
2952 eqn sub
= omega_alloc_eqns (0, 1);
2954 int n_vars
= pb
->num_vars
;
2956 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2957 fprintf (dump_file
, "eliminating variable %s\n",
2958 omega_variable_to_str (pb
, i
));
2960 omega_copy_eqn (sub
, &pb
->eqs
[e
], pb
->num_vars
);
2963 if (c
== 1 || c
== -1)
2965 if (pb
->eqs
[e
].color
== omega_red
)
2968 omega_substitute_red (pb
, sub
, i
, c
, &fB
);
2970 omega_convert_eq_to_geqs (pb
, e
);
2972 omega_delete_variable (pb
, i
);
2976 omega_substitute (pb
, sub
, i
, c
);
2977 omega_delete_variable (pb
, i
);
2985 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2986 fprintf (dump_file
, "performing non-exact elimination, c = %d\n", c
);
2988 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
2989 if (pb
->eqs
[e
].coef
[i
])
2991 eqn eqn
= &(pb
->eqs
[e
]);
2993 for (j
= n_vars
; j
>= 0; j
--)
2997 if (sub
->color
== omega_red
)
2998 eqn
->color
= omega_red
;
2999 for (j
= n_vars
; j
>= 0; j
--)
3000 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3003 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3004 if (pb
->geqs
[e
].coef
[i
])
3006 eqn eqn
= &(pb
->geqs
[e
]);
3009 if (sub
->color
== omega_red
)
3010 eqn
->color
= omega_red
;
3012 for (j
= n_vars
; j
>= 0; j
--)
3019 for (j
= n_vars
; j
>= 0; j
--)
3020 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3024 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3025 if (pb
->subs
[e
].coef
[i
])
3027 eqn eqn
= &(pb
->subs
[e
]);
3030 gcc_assert (sub
->color
== omega_black
);
3031 for (j
= n_vars
; j
>= 0; j
--)
3035 for (j
= n_vars
; j
>= 0; j
--)
3036 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3039 if (in_approximate_mode
)
3040 omega_delete_variable (pb
, i
);
3042 omega_convert_eq_to_geqs (pb
, e2
);
3045 omega_free_eqns (sub
, 1);
3048 /* Helper function for printing "sorry, no solution". */
3050 static inline enum omega_result
3051 omega_problem_has_no_solution (void)
3053 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3054 fprintf (dump_file
, "\nequations have no solution \n");
3059 /* Helper function: solve equations in PB one at a time, following the
3060 DESIRED_RES result. */
3062 static enum omega_result
3063 omega_solve_eq (omega_pb pb
, enum omega_result desired_res
)
3070 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && pb
->num_eqs
> 0)
3072 fprintf (dump_file
, "\nomega_solve_eq (%d, %d)\n",
3073 desired_res
, may_be_red
);
3074 omega_print_problem (dump_file
, pb
);
3075 fprintf (dump_file
, "\n");
3081 j
= pb
->num_eqs
- 1;
3087 while (i
<= j
&& pb
->eqs
[i
].color
== omega_red
)
3090 while (i
<= j
&& pb
->eqs
[j
].color
== omega_black
)
3096 eq
= omega_alloc_eqns (0, 1);
3097 omega_copy_eqn (eq
, &pb
->eqs
[i
], pb
->num_vars
);
3098 omega_copy_eqn (&pb
->eqs
[i
], &pb
->eqs
[j
], pb
->num_vars
);
3099 omega_copy_eqn (&pb
->eqs
[j
], eq
, pb
->num_vars
);
3100 omega_free_eqns (eq
, 1);
3106 /* Eliminate all EQ equations */
3107 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
3109 eqn eqn
= &(pb
->eqs
[e
]);
3112 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3113 fprintf (dump_file
, "----\n");
3115 for (i
= pb
->num_vars
; i
> 0; i
--)
3121 for (j
= i
- 1; j
> 0; j
--)
3125 /* i is the position of last nonzero coefficient,
3126 g is the coefficient of i,
3127 j is the position of next nonzero coefficient. */
3131 if (eqn
->coef
[0] % g
!= 0)
3132 return omega_problem_has_no_solution ();
3134 eqn
->coef
[0] = eqn
->coef
[0] / g
;
3137 omega_do_elimination (pb
, e
, i
);
3143 if (eqn
->coef
[0] != 0)
3144 return omega_problem_has_no_solution ();
3156 omega_do_elimination (pb
, e
, i
);
3162 bool promotion_possible
=
3163 (omega_safe_var_p (pb
, j
)
3164 && pb
->safe_vars
+ 1 == i
3165 && !omega_eqn_is_red (eqn
, desired_res
)
3166 && !in_approximate_mode
);
3168 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && promotion_possible
)
3169 fprintf (dump_file
, " Promotion possible\n");
3172 if (!omega_safe_var_p (pb
, j
))
3174 for (; g
!= 1 && !omega_safe_var_p (pb
, j
); j
--)
3175 g
= gcd (abs (eqn
->coef
[j
]), g
);
3178 else if (!omega_safe_var_p (pb
, i
))
3183 for (; g
!= 1 && j
> 0; j
--)
3184 g
= gcd (abs (eqn
->coef
[j
]), g
);
3188 if (eqn
->coef
[0] % g
!= 0)
3189 return omega_problem_has_no_solution ();
3191 for (j
= 0; j
<= pb
->num_vars
; j
++)
3201 for (e2
= e
- 1; e2
>= 0; e2
--)
3202 if (pb
->eqs
[e2
].coef
[i
])
3206 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
3207 if (pb
->geqs
[e2
].coef
[i
])
3211 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
3212 if (pb
->subs
[e2
].coef
[i
])
3217 bool change
= false;
3219 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3221 fprintf (dump_file
, "Ha! We own it! \n");
3222 omega_print_eq (dump_file
, pb
, eqn
);
3223 fprintf (dump_file
, " \n");
3229 for (j
= i
- 1; j
>= 0; j
--)
3231 int t
= int_mod (eqn
->coef
[j
], g
);
3236 if (t
!= eqn
->coef
[j
])
3245 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3246 fprintf (dump_file
, "So what?\n");
3251 omega_name_wild_card (pb
, i
);
3253 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3255 omega_print_eq (dump_file
, pb
, eqn
);
3256 fprintf (dump_file
, " \n");
3265 if (promotion_possible
)
3267 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3269 fprintf (dump_file
, "promoting %s to safety\n",
3270 omega_variable_to_str (pb
, i
));
3271 omega_print_vars (dump_file
, pb
);
3276 if (!omega_wildcard_p (pb
, i
))
3277 omega_name_wild_card (pb
, i
);
3279 promotion_possible
= false;
3284 if (g2
> 1 && !in_approximate_mode
)
3286 if (pb
->eqs
[e
].color
== omega_red
)
3288 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3289 fprintf (dump_file
, "handling red equality\n");
3292 omega_do_elimination (pb
, e
, i
);
3296 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3299 "adding equation to handle safe variable \n");
3300 omega_print_eq (dump_file
, pb
, eqn
);
3301 fprintf (dump_file
, "\n----\n");
3302 omega_print_problem (dump_file
, pb
);
3303 fprintf (dump_file
, "\n----\n");
3304 fprintf (dump_file
, "\n----\n");
3307 i
= omega_add_new_wild_card (pb
);
3309 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
3310 omega_init_eqn_zero (&pb
->eqs
[e
+ 1], pb
->num_vars
);
3311 omega_copy_eqn (&pb
->eqs
[e
+ 1], eqn
, pb
->safe_vars
);
3313 for (j
= pb
->num_vars
; j
>= 0; j
--)
3315 pb
->eqs
[e
+ 1].coef
[j
] = int_mod (pb
->eqs
[e
+ 1].coef
[j
], g2
);
3317 if (2 * pb
->eqs
[e
+ 1].coef
[j
] >= g2
)
3318 pb
->eqs
[e
+ 1].coef
[j
] -= g2
;
3321 pb
->eqs
[e
+ 1].coef
[i
] = g2
;
3324 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3325 omega_print_problem (dump_file
, pb
);
3334 /* Find variable to eliminate. */
3337 gcc_assert (in_approximate_mode
);
3339 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3341 fprintf (dump_file
, "non-exact elimination: ");
3342 omega_print_eq (dump_file
, pb
, eqn
);
3343 fprintf (dump_file
, "\n");
3344 omega_print_problem (dump_file
, pb
);
3347 for (i
= pb
->num_vars
; i
> sv
; i
--)
3348 if (pb
->eqs
[e
].coef
[i
] != 0)
3352 for (i
= pb
->num_vars
; i
> sv
; i
--)
3353 if (pb
->eqs
[e
].coef
[i
] == 1 || pb
->eqs
[e
].coef
[i
] == -1)
3359 omega_do_elimination (pb
, e
, i
);
3361 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && g2
> 1)
3363 fprintf (dump_file
, "result of non-exact elimination:\n");
3364 omega_print_problem (dump_file
, pb
);
3369 int factor
= (INT_MAX
);
3372 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3373 fprintf (dump_file
, "doing moding\n");
3375 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3376 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3381 for (; i
!= sv
; i
--)
3382 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3388 if (j
!= 0 && i
== sv
)
3390 omega_do_mod (pb
, 2, e
, j
);
3396 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3397 if (pb
->eqs
[e
].coef
[i
] != 0
3398 && factor
> abs (pb
->eqs
[e
].coef
[i
]) + 1)
3400 factor
= abs (pb
->eqs
[e
].coef
[i
]) + 1;
3406 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3407 fprintf (dump_file
, "should not have happened\n");
3411 omega_do_mod (pb
, factor
, e
, j
);
3412 /* Go back and try this equation again. */
3419 return omega_unknown
;
3422 /* Transform an inequation E to an equality, then solve DIFF problems
3423 based on PB, and only differing by the constant part that is
3424 diminished by one, trying to figure out which of the constants
3427 static enum omega_result
3428 parallel_splinter (omega_pb pb
, int e
, int diff
,
3429 enum omega_result desired_res
)
3431 omega_pb tmp_problem
;
3434 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3436 fprintf (dump_file
, "Using parallel splintering\n");
3437 omega_print_problem (dump_file
, pb
);
3440 tmp_problem
= XNEW (struct omega_pb_d
);
3441 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
], pb
->num_vars
);
3444 for (i
= 0; i
<= diff
; i
++)
3446 omega_copy_problem (tmp_problem
, pb
);
3448 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3450 fprintf (dump_file
, "Splinter # %i\n", i
);
3451 omega_print_problem (dump_file
, pb
);
3454 if (omega_solve_problem (tmp_problem
, desired_res
) == omega_true
)
3460 pb
->eqs
[0].coef
[0]--;
3467 /* Helper function: solve equations one at a time. */
3469 static enum omega_result
3470 omega_solve_geq (omega_pb pb
, enum omega_result desired_res
)
3474 enum omega_result result
;
3475 bool coupled_subscripts
= false;
3476 bool smoothed
= false;
3477 bool eliminate_again
;
3478 bool tried_eliminating_redundant
= false;
3480 if (desired_res
!= omega_simplify
)
3488 gcc_assert (desired_res
== omega_simplify
|| pb
->num_subs
== 0);
3490 /* Verify that there are not too many inequalities. */
3491 gcc_assert (pb
->num_geqs
<= OMEGA_MAX_GEQS
);
3493 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3495 fprintf (dump_file
, "\nomega_solve_geq (%d,%d):\n",
3496 desired_res
, please_no_equalities_in_simplified_problems
);
3497 omega_print_problem (dump_file
, pb
);
3498 fprintf (dump_file
, "\n");
3501 n_vars
= pb
->num_vars
;
3505 enum omega_eqn_color u_color
= omega_black
;
3506 enum omega_eqn_color l_color
= omega_black
;
3507 int upper_bound
= pos_infinity
;
3508 int lower_bound
= neg_infinity
;
3510 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3512 int a
= pb
->geqs
[e
].coef
[1];
3513 int c
= pb
->geqs
[e
].coef
[0];
3515 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3519 return omega_problem_has_no_solution ();
3526 if (lower_bound
< -c
3527 || (lower_bound
== -c
3528 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3531 l_color
= pb
->geqs
[e
].color
;
3537 c
= int_div (c
, -a
);
3540 || (upper_bound
== c
3541 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3544 u_color
= pb
->geqs
[e
].color
;
3549 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3551 fprintf (dump_file
, "upper bound = %d\n", upper_bound
);
3552 fprintf (dump_file
, "lower bound = %d\n", lower_bound
);
3555 if (lower_bound
> upper_bound
)
3556 return omega_problem_has_no_solution ();
3558 if (desired_res
== omega_simplify
)
3561 if (pb
->safe_vars
== 1)
3564 if (lower_bound
== upper_bound
3565 && u_color
== omega_black
3566 && l_color
== omega_black
)
3568 pb
->eqs
[0].coef
[0] = -lower_bound
;
3569 pb
->eqs
[0].coef
[1] = 1;
3570 pb
->eqs
[0].color
= omega_black
;
3572 return omega_solve_problem (pb
, desired_res
);
3576 if (lower_bound
> neg_infinity
)
3578 pb
->geqs
[0].coef
[0] = -lower_bound
;
3579 pb
->geqs
[0].coef
[1] = 1;
3580 pb
->geqs
[0].key
= 1;
3581 pb
->geqs
[0].color
= l_color
;
3582 pb
->geqs
[0].touched
= 0;
3586 if (upper_bound
< pos_infinity
)
3588 pb
->geqs
[pb
->num_geqs
].coef
[0] = upper_bound
;
3589 pb
->geqs
[pb
->num_geqs
].coef
[1] = -1;
3590 pb
->geqs
[pb
->num_geqs
].key
= -1;
3591 pb
->geqs
[pb
->num_geqs
].color
= u_color
;
3592 pb
->geqs
[pb
->num_geqs
].touched
= 0;
3600 omega_problem_reduced (pb
);
3604 if (original_problem
!= no_problem
3605 && l_color
== omega_black
3606 && u_color
== omega_black
3608 && lower_bound
== upper_bound
)
3610 pb
->eqs
[0].coef
[0] = -lower_bound
;
3611 pb
->eqs
[0].coef
[1] = 1;
3613 adding_equality_constraint (pb
, 0);
3619 if (!pb
->variables_freed
)
3621 pb
->variables_freed
= true;
3623 if (desired_res
!= omega_simplify
)
3624 omega_free_eliminations (pb
, 0);
3626 omega_free_eliminations (pb
, pb
->safe_vars
);
3628 n_vars
= pb
->num_vars
;
3634 switch (normalize_omega_problem (pb
))
3636 case normalize_false
:
3640 case normalize_coupled
:
3641 coupled_subscripts
= true;
3644 case normalize_uncoupled
:
3645 coupled_subscripts
= false;
3652 n_vars
= pb
->num_vars
;
3654 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3656 fprintf (dump_file
, "\nafter normalization:\n");
3657 omega_print_problem (dump_file
, pb
);
3658 fprintf (dump_file
, "\n");
3659 fprintf (dump_file
, "eliminating variable using Fourier-Motzkin.\n");
3663 int parallel_difference
= INT_MAX
;
3664 int best_parallel_eqn
= -1;
3665 int minC
, maxC
, minCj
= 0;
3666 int lower_bound_count
= 0;
3668 bool possible_easy_int_solution
;
3669 int max_splinters
= 1;
3671 bool lucky_exact
= false;
3672 int best
= (INT_MAX
);
3673 int j
= 0, jLe
= 0, jLowerBoundCount
= 0;
3676 eliminate_again
= false;
3678 if (pb
->num_eqs
> 0)
3679 return omega_solve_problem (pb
, desired_res
);
3681 if (!coupled_subscripts
)
3683 if (pb
->safe_vars
== 0)
3686 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3687 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
3688 omega_delete_geq (pb
, e
, n_vars
);
3690 pb
->num_vars
= pb
->safe_vars
;
3692 if (desired_res
== omega_simplify
)
3694 omega_problem_reduced (pb
);
3701 if (desired_res
!= omega_simplify
)
3706 if (pb
->num_geqs
== 0)
3708 if (desired_res
== omega_simplify
)
3710 pb
->num_vars
= pb
->safe_vars
;
3711 omega_problem_reduced (pb
);
3717 if (desired_res
== omega_simplify
&& n_vars
== pb
->safe_vars
)
3719 omega_problem_reduced (pb
);
3723 if (pb
->num_geqs
> OMEGA_MAX_GEQS
- 30
3724 || pb
->num_geqs
> 2 * n_vars
* n_vars
+ 4 * n_vars
+ 10)
3726 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3728 "TOO MANY EQUATIONS; "
3729 "%d equations, %d variables, "
3730 "ELIMINATING REDUNDANT ONES\n",
3731 pb
->num_geqs
, n_vars
);
3733 if (!omega_eliminate_redundant (pb
, false))
3736 n_vars
= pb
->num_vars
;
3738 if (pb
->num_eqs
> 0)
3739 return omega_solve_problem (pb
, desired_res
);
3741 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3742 fprintf (dump_file
, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3745 if (desired_res
!= omega_simplify
)
3750 for (i
= n_vars
; i
!= fv
; i
--)
3756 int upper_bound_count
= 0;
3758 lower_bound_count
= 0;
3761 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3762 if (pb
->geqs
[e
].coef
[i
] < 0)
3764 minC
= MIN (minC
, pb
->geqs
[e
].coef
[i
]);
3765 upper_bound_count
++;
3766 if (pb
->geqs
[e
].coef
[i
] < -1)
3774 else if (pb
->geqs
[e
].coef
[i
] > 0)
3776 maxC
= MAX (maxC
, pb
->geqs
[e
].coef
[i
]);
3777 lower_bound_count
++;
3779 if (pb
->geqs
[e
].coef
[i
] > 1)
3788 if (lower_bound_count
== 0
3789 || upper_bound_count
== 0)
3791 lower_bound_count
= 0;
3795 if (ub
>= 0 && lb
>= 0
3796 && pb
->geqs
[lb
].key
== -pb
->geqs
[ub
].key
)
3798 int Lc
= pb
->geqs
[lb
].coef
[i
];
3799 int Uc
= -pb
->geqs
[ub
].coef
[i
];
3801 Lc
* pb
->geqs
[ub
].coef
[0] + Uc
* pb
->geqs
[lb
].coef
[0];
3802 lucky
= (diff
>= (Uc
- 1) * (Lc
- 1));
3808 || in_approximate_mode
)
3810 score
= upper_bound_count
* lower_bound_count
;
3812 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3814 "For %s, exact, score = %d*%d, range = %d ... %d,"
3815 "\nlucky = %d, in_approximate_mode=%d \n",
3816 omega_variable_to_str (pb
, i
),
3818 lower_bound_count
, minC
, maxC
, lucky
,
3819 in_approximate_mode
);
3829 jLowerBoundCount
= lower_bound_count
;
3831 lucky_exact
= lucky
;
3838 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3840 "For %s, non-exact, score = %d*%d,"
3841 "range = %d ... %d \n",
3842 omega_variable_to_str (pb
, i
),
3844 lower_bound_count
, minC
, maxC
);
3846 score
= maxC
- minC
;
3854 jLowerBoundCount
= lower_bound_count
;
3859 if (lower_bound_count
== 0)
3861 omega_free_eliminations (pb
, pb
->safe_vars
);
3862 n_vars
= pb
->num_vars
;
3863 eliminate_again
= true;
3870 lower_bound_count
= jLowerBoundCount
;
3872 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3873 if (pb
->geqs
[e
].coef
[i
] > 0)
3875 if (pb
->geqs
[e
].coef
[i
] == -minC
)
3876 max_splinters
+= -minC
- 1;
3879 pos_mul_hwi ((pb
->geqs
[e
].coef
[i
] - 1),
3880 (-minC
- 1)) / (-minC
) + 1;
3884 /* Trying to produce exact elimination by finding redundant
3886 if (!exact
&& !tried_eliminating_redundant
)
3888 omega_eliminate_redundant (pb
, false);
3889 tried_eliminating_redundant
= true;
3890 eliminate_again
= true;
3893 tried_eliminating_redundant
= false;
3896 if (return_single_result
&& desired_res
== omega_simplify
&& !exact
)
3898 omega_problem_reduced (pb
);
3902 /* #ifndef Omega3 */
3903 /* Trying to produce exact elimination by finding redundant
3905 if (!exact
&& !tried_eliminating_redundant
)
3907 omega_eliminate_redundant (pb
, false);
3908 tried_eliminating_redundant
= true;
3911 tried_eliminating_redundant
= false;
3918 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
3919 if (pb
->geqs
[e1
].color
== omega_black
)
3920 for (e2
= e1
- 1; e2
>= 0; e2
--)
3921 if (pb
->geqs
[e2
].color
== omega_black
3922 && pb
->geqs
[e1
].key
== -pb
->geqs
[e2
].key
3923 && ((pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3924 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3925 / 2 < parallel_difference
))
3927 parallel_difference
=
3928 (pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3929 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3931 best_parallel_eqn
= e1
;
3934 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
3935 && best_parallel_eqn
>= 0)
3938 "Possible parallel projection, diff = %d, in ",
3939 parallel_difference
);
3940 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[best_parallel_eqn
]));
3941 fprintf (dump_file
, "\n");
3942 omega_print_problem (dump_file
, pb
);
3946 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3948 fprintf (dump_file
, "going to eliminate %s, (%d,%d,%d)\n",
3949 omega_variable_to_str (pb
, i
), i
, minC
,
3951 omega_print_problem (dump_file
, pb
);
3954 fprintf (dump_file
, "(a lucky exact elimination)\n");
3957 fprintf (dump_file
, "(an exact elimination)\n");
3959 fprintf (dump_file
, "Max # of splinters = %d\n", max_splinters
);
3962 gcc_assert (max_splinters
>= 1);
3964 if (!exact
&& desired_res
== omega_simplify
&& best_parallel_eqn
>= 0
3965 && parallel_difference
<= max_splinters
)
3966 return parallel_splinter (pb
, best_parallel_eqn
, parallel_difference
,
3974 int j
= pb
->num_vars
;
3976 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3978 fprintf (dump_file
, "Swapping %d and %d\n", i
, j
);
3979 omega_print_problem (dump_file
, pb
);
3982 swap (&pb
->var
[i
], &pb
->var
[j
]);
3984 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3985 if (pb
->geqs
[e
].coef
[i
] != pb
->geqs
[e
].coef
[j
])
3987 pb
->geqs
[e
].touched
= 1;
3988 t
= pb
->geqs
[e
].coef
[i
];
3989 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[j
];
3990 pb
->geqs
[e
].coef
[j
] = t
;
3993 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3994 if (pb
->subs
[e
].coef
[i
] != pb
->subs
[e
].coef
[j
])
3996 t
= pb
->subs
[e
].coef
[i
];
3997 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[j
];
3998 pb
->subs
[e
].coef
[j
] = t
;
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
++)
4598 int k
, smallest
= j
;
4600 for (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 k
= lower_bound
[smallest
];
4606 lower_bound
[smallest
] = lower_bound
[j
];
4610 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4612 fprintf (dump_file
, "lower bound coefficients = ");
4614 for (j
= 0; j
< lower_bounds
; j
++)
4615 fprintf (dump_file
, " %d",
4616 pb
->geqs
[lower_bound
[j
]].coef
[i
]);
4618 fprintf (dump_file
, "\n");
4621 for (j
= 0; j
< lower_bounds
; j
++)
4625 int worst_lower_bound_constant
= -minC
;
4628 max_incr
= (((pb
->geqs
[e
].coef
[i
] - 1) *
4629 (worst_lower_bound_constant
- 1) - 1)
4630 / worst_lower_bound_constant
);
4631 /* max_incr += 2; */
4633 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4635 fprintf (dump_file
, "for equation ");
4636 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
4638 "\ntry decrements from 0 to %d\n",
4640 omega_print_problem (dump_file
, pb
);
4643 if (max_incr
> 50 && !smoothed
4644 && smooth_weird_equations (pb
))
4650 goto solve_geq_start
;
4653 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
],
4655 pb
->eqs
[0].color
= omega_black
;
4656 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
4657 pb
->geqs
[e
].touched
= 1;
4660 for (c
= max_incr
; c
>= 0; c
--)
4662 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4665 "trying next decrement of %d\n",
4667 omega_print_problem (dump_file
, pb
);
4670 omega_copy_problem (rS
, pb
);
4672 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4673 omega_print_problem (dump_file
, rS
);
4675 result
= omega_solve_problem (rS
, desired_res
);
4677 if (result
== omega_true
)
4686 pb
->eqs
[0].coef
[0]--;
4689 if (j
+ 1 < lower_bounds
)
4692 omega_copy_eqn (&pb
->geqs
[e
], &pb
->eqs
[0],
4694 pb
->geqs
[e
].touched
= 1;
4695 pb
->geqs
[e
].color
= omega_black
;
4696 omega_copy_problem (rS
, pb
);
4698 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4700 "exhausted lower bound, "
4701 "checking if still feasible ");
4703 result
= omega_solve_problem (rS
, omega_false
);
4705 if (result
== omega_false
)
4710 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4711 fprintf (dump_file
, "fall-off the end\n");
4723 return omega_unknown
;
4724 } while (eliminate_again
);
4728 /* Because the omega solver is recursive, this counter limits the
4730 static int omega_solve_depth
= 0;
4732 /* Return omega_true when the problem PB has a solution following the
4736 omega_solve_problem (omega_pb pb
, enum omega_result desired_res
)
4738 enum omega_result result
;
4740 gcc_assert (pb
->num_vars
>= pb
->safe_vars
);
4741 omega_solve_depth
++;
4743 if (desired_res
!= omega_simplify
)
4746 if (omega_solve_depth
> 50)
4748 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4751 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4752 omega_solve_depth
, in_approximate_mode
);
4753 omega_print_problem (dump_file
, pb
);
4758 if (omega_solve_eq (pb
, desired_res
) == omega_false
)
4760 omega_solve_depth
--;
4764 if (in_approximate_mode
&& !pb
->num_geqs
)
4766 result
= omega_true
;
4767 pb
->num_vars
= pb
->safe_vars
;
4768 omega_problem_reduced (pb
);
4771 result
= omega_solve_geq (pb
, desired_res
);
4773 omega_solve_depth
--;
4775 if (!omega_reduce_with_subs
)
4777 resurrect_subs (pb
);
4778 gcc_assert (please_no_equalities_in_simplified_problems
4779 || !result
|| pb
->num_subs
== 0);
4785 /* Return true if red equations constrain the set of possible solutions.
4786 We assume that there are solutions to the black equations by
4787 themselves, so if there is no solution to the combined problem, we
4791 omega_problem_has_red_equations (omega_pb pb
)
4797 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4799 fprintf (dump_file
, "Checking for red equations:\n");
4800 omega_print_problem (dump_file
, pb
);
4803 please_no_equalities_in_simplified_problems
++;
4806 if (omega_single_result
)
4807 return_single_result
++;
4809 create_color
= true;
4810 result
= (omega_simplify_problem (pb
) == omega_false
);
4812 if (omega_single_result
)
4813 return_single_result
--;
4816 please_no_equalities_in_simplified_problems
--;
4820 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4821 fprintf (dump_file
, "Gist is FALSE\n");
4826 pb
->eqs
[0].color
= omega_red
;
4828 for (i
= pb
->num_vars
; i
> 0; i
--)
4829 pb
->eqs
[0].coef
[i
] = 0;
4831 pb
->eqs
[0].coef
[0] = 1;
4835 free_red_eliminations (pb
);
4836 gcc_assert (pb
->num_eqs
== 0);
4838 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4839 if (pb
->geqs
[e
].color
== omega_red
)
4845 for (i
= pb
->safe_vars
; i
>= 1; i
--)
4850 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4852 if (pb
->geqs
[e
].coef
[i
])
4854 if (pb
->geqs
[e
].coef
[i
] > 0)
4855 lb
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4858 ub
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4862 if (ub
== 2 || lb
== 2)
4865 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4866 fprintf (dump_file
, "checks for upper/lower bounds worked!\n");
4868 if (!omega_reduce_with_subs
)
4870 resurrect_subs (pb
);
4871 gcc_assert (pb
->num_subs
== 0);
4879 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4881 "*** Doing potentially expensive elimination tests "
4882 "for red equations\n");
4884 please_no_equalities_in_simplified_problems
++;
4885 omega_eliminate_red (pb
, true);
4886 please_no_equalities_in_simplified_problems
--;
4889 gcc_assert (pb
->num_eqs
== 0);
4891 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4892 if (pb
->geqs
[e
].color
== omega_red
)
4895 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4899 "******************** Redundant Red Equations eliminated!!\n");
4902 "******************** Red Equations remain\n");
4904 omega_print_problem (dump_file
, pb
);
4907 if (!omega_reduce_with_subs
)
4909 normalize_return_type r
;
4911 resurrect_subs (pb
);
4912 r
= normalize_omega_problem (pb
);
4913 gcc_assert (r
!= normalize_false
);
4916 cleanout_wildcards (pb
);
4917 gcc_assert (pb
->num_subs
== 0);
4923 /* Calls omega_simplify_problem in approximate mode. */
4926 omega_simplify_approximate (omega_pb pb
)
4928 enum omega_result result
;
4930 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4931 fprintf (dump_file
, "(Entering approximate mode\n");
4933 in_approximate_mode
= true;
4934 result
= omega_simplify_problem (pb
);
4935 in_approximate_mode
= false;
4937 gcc_assert (pb
->num_vars
== pb
->safe_vars
);
4938 if (!omega_reduce_with_subs
)
4939 gcc_assert (pb
->num_subs
== 0);
4941 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4942 fprintf (dump_file
, "Leaving approximate mode)\n");
4948 /* Simplifies problem PB by eliminating redundant constraints and
4949 reducing the constraints system to a minimal form. Returns
4950 omega_true when the problem was successfully reduced, omega_unknown
4951 when the solver is unable to determine an answer. */
4954 omega_simplify_problem (omega_pb pb
)
4958 omega_found_reduction
= omega_false
;
4960 if (!pb
->variables_initialized
)
4961 omega_initialize_variables (pb
);
4963 if (next_key
* 3 > MAX_KEYS
)
4968 next_key
= OMEGA_MAX_VARS
+ 1;
4970 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4971 pb
->geqs
[e
].touched
= 1;
4973 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
4974 hash_master
[i
].touched
= -1;
4976 pb
->hash_version
= hash_version
;
4979 else if (pb
->hash_version
!= hash_version
)
4983 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4984 pb
->geqs
[e
].touched
= 1;
4986 pb
->hash_version
= hash_version
;
4989 if (pb
->num_vars
> pb
->num_eqs
+ 3 * pb
->safe_vars
)
4990 omega_free_eliminations (pb
, pb
->safe_vars
);
4992 if (!may_be_red
&& pb
->num_subs
== 0 && pb
->safe_vars
== 0)
4994 omega_found_reduction
= omega_solve_problem (pb
, omega_unknown
);
4996 if (omega_found_reduction
!= omega_false
4997 && !return_single_result
)
5001 (*omega_when_reduced
) (pb
);
5004 return omega_found_reduction
;
5007 omega_solve_problem (pb
, omega_simplify
);
5009 if (omega_found_reduction
!= omega_false
)
5011 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
5012 pb
->forwarding_address
[pb
->var
[i
]] = i
;
5014 for (i
= 0; i
< pb
->num_subs
; i
++)
5015 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
5018 if (!omega_reduce_with_subs
)
5019 gcc_assert (please_no_equalities_in_simplified_problems
5020 || omega_found_reduction
== omega_false
5021 || pb
->num_subs
== 0);
5023 return omega_found_reduction
;
5026 /* Make variable VAR unprotected: it then can be eliminated. */
5029 omega_unprotect_variable (omega_pb pb
, int var
)
5032 idx
= pb
->forwarding_address
[var
];
5039 if (idx
< pb
->num_subs
)
5041 omega_copy_eqn (&pb
->subs
[idx
], &pb
->subs
[pb
->num_subs
],
5043 pb
->forwarding_address
[pb
->subs
[idx
].key
] = -idx
- 1;
5048 int *bring_to_life
= XNEWVEC (int, OMEGA_MAX_VARS
);
5051 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5052 bring_to_life
[e
] = (pb
->subs
[e
].coef
[idx
] != 0);
5054 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
5055 if (bring_to_life
[e2
])
5060 if (pb
->safe_vars
< pb
->num_vars
)
5062 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5064 pb
->geqs
[e
].coef
[pb
->num_vars
] =
5065 pb
->geqs
[e
].coef
[pb
->safe_vars
];
5067 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5070 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5072 pb
->eqs
[e
].coef
[pb
->num_vars
] =
5073 pb
->eqs
[e
].coef
[pb
->safe_vars
];
5075 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5078 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5080 pb
->subs
[e
].coef
[pb
->num_vars
] =
5081 pb
->subs
[e
].coef
[pb
->safe_vars
];
5083 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5086 pb
->var
[pb
->num_vars
] = pb
->var
[pb
->safe_vars
];
5087 pb
->forwarding_address
[pb
->var
[pb
->num_vars
]] =
5092 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5093 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5095 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5096 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5098 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5099 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5102 pb
->var
[pb
->safe_vars
] = pb
->subs
[e2
].key
;
5103 pb
->forwarding_address
[pb
->subs
[e2
].key
] = pb
->safe_vars
;
5105 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e2
]),
5107 pb
->eqs
[pb
->num_eqs
++].coef
[pb
->safe_vars
] = -1;
5108 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5110 if (e2
< pb
->num_subs
- 1)
5111 omega_copy_eqn (&(pb
->subs
[e2
]), &(pb
->subs
[pb
->num_subs
- 1]),
5117 omega_unprotect_1 (pb
, &idx
, NULL
);
5118 free (bring_to_life
);
5121 chain_unprotect (pb
);
5124 /* Unprotects VAR and simplifies PB. */
5127 omega_constrain_variable_sign (omega_pb pb
, enum omega_eqn_color color
,
5130 int n_vars
= pb
->num_vars
;
5132 int k
= pb
->forwarding_address
[var
];
5141 omega_copy_eqn (&pb
->geqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5143 for (j
= 0; j
<= n_vars
; j
++)
5144 pb
->geqs
[e
].coef
[j
] *= sign
;
5146 pb
->geqs
[e
].coef
[0]--;
5147 pb
->geqs
[e
].touched
= 1;
5148 pb
->geqs
[e
].color
= color
;
5153 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5154 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5155 pb
->eqs
[e
].color
= color
;
5161 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
5162 pb
->geqs
[e
].coef
[k
] = sign
;
5163 pb
->geqs
[e
].coef
[0] = -1;
5164 pb
->geqs
[e
].touched
= 1;
5165 pb
->geqs
[e
].color
= color
;
5170 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5171 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5172 pb
->eqs
[e
].coef
[k
] = 1;
5173 pb
->eqs
[e
].color
= color
;
5176 omega_unprotect_variable (pb
, var
);
5177 return omega_simplify_problem (pb
);
5180 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5183 omega_constrain_variable_value (omega_pb pb
, enum omega_eqn_color color
,
5187 int k
= pb
->forwarding_address
[var
];
5193 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5194 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5195 pb
->eqs
[e
].coef
[0] -= value
;
5200 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5201 pb
->eqs
[e
].coef
[k
] = 1;
5202 pb
->eqs
[e
].coef
[0] = -value
;
5205 pb
->eqs
[e
].color
= color
;
5208 /* Return false when the upper and lower bounds are not coupled.
5209 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5213 omega_query_variable (omega_pb pb
, int i
, int *lower_bound
, int *upper_bound
)
5215 int n_vars
= pb
->num_vars
;
5218 bool coupled
= false;
5220 *lower_bound
= neg_infinity
;
5221 *upper_bound
= pos_infinity
;
5222 i
= pb
->forwarding_address
[i
];
5228 for (j
= 1; j
<= n_vars
; j
++)
5229 if (pb
->subs
[i
].coef
[j
] != 0)
5232 *upper_bound
= *lower_bound
= pb
->subs
[i
].coef
[0];
5236 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5237 if (pb
->subs
[e
].coef
[i
] != 0)
5240 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5241 if (pb
->eqs
[e
].coef
[i
] != 0)
5245 for (j
= 1; j
<= n_vars
; j
++)
5246 if (i
!= j
&& pb
->eqs
[e
].coef
[j
] != 0)
5257 *lower_bound
= *upper_bound
=
5258 -pb
->eqs
[e
].coef
[i
] * pb
->eqs
[e
].coef
[0];
5263 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5264 if (pb
->geqs
[e
].coef
[i
] != 0)
5266 if (pb
->geqs
[e
].key
== i
)
5267 *lower_bound
= MAX (*lower_bound
, -pb
->geqs
[e
].coef
[0]);
5269 else if (pb
->geqs
[e
].key
== -i
)
5270 *upper_bound
= MIN (*upper_bound
, pb
->geqs
[e
].coef
[0]);
5279 /* Sets the lower bound L and upper bound U for the values of variable
5280 I, and sets COULD_BE_ZERO to true if variable I might take value
5281 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5285 query_coupled_variable (omega_pb pb
, int i
, int *l
, int *u
,
5286 bool *could_be_zero
, int lower_bound
, int upper_bound
)
5293 /* Preconditions. */
5294 gcc_assert (abs (pb
->forwarding_address
[i
]) == 1
5295 && pb
->num_vars
+ pb
->num_subs
== 2
5296 && pb
->num_eqs
+ pb
->num_subs
== 1);
5298 /* Define variable I in terms of variable V. */
5299 if (pb
->forwarding_address
[i
] == -1)
5308 sign
= -eqn
->coef
[1];
5312 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5313 if (pb
->geqs
[e
].coef
[v
] != 0)
5315 if (pb
->geqs
[e
].coef
[v
] == 1)
5316 lower_bound
= MAX (lower_bound
, -pb
->geqs
[e
].coef
[0]);
5319 upper_bound
= MIN (upper_bound
, pb
->geqs
[e
].coef
[0]);
5322 if (lower_bound
> upper_bound
)
5330 if (lower_bound
== neg_infinity
)
5332 if (eqn
->coef
[v
] > 0)
5333 b1
= sign
* neg_infinity
;
5336 b1
= -sign
* neg_infinity
;
5339 b1
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * lower_bound
);
5341 if (upper_bound
== pos_infinity
)
5343 if (eqn
->coef
[v
] > 0)
5344 b2
= sign
* pos_infinity
;
5347 b2
= -sign
* pos_infinity
;
5350 b2
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * upper_bound
);
5352 *l
= MAX (*l
, b1
<= b2
? b1
: b2
);
5353 *u
= MIN (*u
, b1
<= b2
? b2
: b1
);
5355 *could_be_zero
= (*l
<= 0 && 0 <= *u
5356 && int_mod (eqn
->coef
[0], abs (eqn
->coef
[v
])) == 0);
5359 /* Return false when a lower bound L and an upper bound U for variable
5360 I in problem PB have been initialized. */
5363 omega_query_variable_bounds (omega_pb pb
, int i
, int *l
, int *u
)
5368 if (!omega_query_variable (pb
, i
, l
, u
)
5369 || (pb
->num_vars
== 1 && pb
->forwarding_address
[i
] == 1))
5372 if (abs (pb
->forwarding_address
[i
]) == 1
5373 && pb
->num_vars
+ pb
->num_subs
== 2
5374 && pb
->num_eqs
+ pb
->num_subs
== 1)
5377 query_coupled_variable (pb
, i
, l
, u
, &could_be_zero
, neg_infinity
,
5385 /* For problem PB, return an integer that represents the classic data
5386 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5387 masks that are added to the result. When DIST_KNOWN is true, DIST
5388 is set to the classic data dependence distance. LOWER_BOUND and
5389 UPPER_BOUND are bounds on the value of variable I, for example, it
5390 is possible to narrow the iteration domain with safe approximations
5391 of loop counts, and thus discard some data dependences that cannot
5395 omega_query_variable_signs (omega_pb pb
, int i
, int dd_lt
,
5396 int dd_eq
, int dd_gt
, int lower_bound
,
5397 int upper_bound
, bool *dist_known
, int *dist
)
5406 omega_query_variable (pb
, i
, &l
, &u
);
5407 query_coupled_variable (pb
, i
, &l
, &u
, &could_be_zero
, lower_bound
,
5426 *dist_known
= false;
5431 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5432 safe variables. Safe variables are not eliminated during the
5433 Fourier-Motzkin elimination. Safe variables are all those
5434 variables that are placed at the beginning of the array of
5435 variables: P->var[0, ..., NPROT - 1]. */
5438 omega_alloc_problem (int nvars
, int nprot
)
5442 gcc_assert (nvars
<= OMEGA_MAX_VARS
);
5443 omega_initialize ();
5445 /* Allocate and initialize PB. */
5446 pb
= XCNEW (struct omega_pb_d
);
5447 pb
->var
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5448 pb
->forwarding_address
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5449 pb
->geqs
= omega_alloc_eqns (0, OMEGA_MAX_GEQS
);
5450 pb
->eqs
= omega_alloc_eqns (0, OMEGA_MAX_EQS
);
5451 pb
->subs
= omega_alloc_eqns (0, OMEGA_MAX_VARS
+ 1);
5453 pb
->hash_version
= hash_version
;
5454 pb
->num_vars
= nvars
;
5455 pb
->safe_vars
= nprot
;
5456 pb
->variables_initialized
= false;
5457 pb
->variables_freed
= false;
5464 /* Keeps the state of the initialization. */
5465 static bool omega_initialized
= false;
5467 /* Initialization of the Omega solver. */
5470 omega_initialize (void)
5474 if (omega_initialized
)
5478 next_key
= OMEGA_MAX_VARS
+ 1;
5479 packing
= XCNEWVEC (int, OMEGA_MAX_VARS
);
5480 fast_lookup
= XCNEWVEC (int, MAX_KEYS
* 2);
5481 fast_lookup_red
= XCNEWVEC (int, MAX_KEYS
* 2);
5482 hash_master
= omega_alloc_eqns (0, HASH_TABLE_SIZE
);
5484 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
5485 hash_master
[i
].touched
= -1;
5487 sprintf (wild_name
[0], "1");
5488 sprintf (wild_name
[1], "a");
5489 sprintf (wild_name
[2], "b");
5490 sprintf (wild_name
[3], "c");
5491 sprintf (wild_name
[4], "d");
5492 sprintf (wild_name
[5], "e");
5493 sprintf (wild_name
[6], "f");
5494 sprintf (wild_name
[7], "g");
5495 sprintf (wild_name
[8], "h");
5496 sprintf (wild_name
[9], "i");
5497 sprintf (wild_name
[10], "j");
5498 sprintf (wild_name
[11], "k");
5499 sprintf (wild_name
[12], "l");
5500 sprintf (wild_name
[13], "m");
5501 sprintf (wild_name
[14], "n");
5502 sprintf (wild_name
[15], "o");
5503 sprintf (wild_name
[16], "p");
5504 sprintf (wild_name
[17], "q");
5505 sprintf (wild_name
[18], "r");
5506 sprintf (wild_name
[19], "s");
5507 sprintf (wild_name
[20], "t");
5508 sprintf (wild_name
[40 - 1], "alpha");
5509 sprintf (wild_name
[40 - 2], "beta");
5510 sprintf (wild_name
[40 - 3], "gamma");
5511 sprintf (wild_name
[40 - 4], "delta");
5512 sprintf (wild_name
[40 - 5], "tau");
5513 sprintf (wild_name
[40 - 6], "sigma");
5514 sprintf (wild_name
[40 - 7], "chi");
5515 sprintf (wild_name
[40 - 8], "omega");
5516 sprintf (wild_name
[40 - 9], "pi");
5517 sprintf (wild_name
[40 - 10], "ni");
5518 sprintf (wild_name
[40 - 11], "Alpha");
5519 sprintf (wild_name
[40 - 12], "Beta");
5520 sprintf (wild_name
[40 - 13], "Gamma");
5521 sprintf (wild_name
[40 - 14], "Delta");
5522 sprintf (wild_name
[40 - 15], "Tau");
5523 sprintf (wild_name
[40 - 16], "Sigma");
5524 sprintf (wild_name
[40 - 17], "Chi");
5525 sprintf (wild_name
[40 - 18], "Omega");
5526 sprintf (wild_name
[40 - 19], "xxx");
5528 omega_initialized
= true;