1 /* Source code for an implementation of the Omega test, an integer
2 programming algorithm for dependence analysis, by William Pugh,
3 appeared in Supercomputing '91 and CACM Aug 92.
5 This code has no license restrictions, and is considered public
8 Changes copyright (C) 2005-2015 Free Software Foundation, Inc.
9 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
11 This file is part of GCC.
13 GCC is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free
15 Software Foundation; either version 3, or (at your option) any later
18 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
19 WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 You should have received a copy of the GNU General Public License
24 along with GCC; see the file COPYING3. If not see
25 <http://www.gnu.org/licenses/>. */
27 /* For a detailed description, see "Constraint-Based Array Dependence
28 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
30 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
35 #include "coretypes.h"
41 #include "diagnostic-core.h"
45 /* When set to true, keep substitution variables. When set to false,
46 resurrect substitution variables (convert substitutions back to EQs). */
47 static bool omega_reduce_with_subs
= true;
49 /* When set to true, omega_simplify_problem checks for problem with no
50 solutions, calling verify_omega_pb. */
51 static bool omega_verify_simplification
= false;
53 /* When set to true, only produce a single simplified result. */
54 static bool omega_single_result
= false;
56 /* Set return_single_result to 1 when omega_single_result is true. */
57 static int return_single_result
= 0;
59 /* Hash table for equations generated by the solver. */
60 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
61 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
62 static eqn hash_master
;
64 static int hash_version
= 0;
66 /* Set to true for making the solver enter in approximation mode. */
67 static bool in_approximate_mode
= false;
69 /* When set to zero, the solver is allowed to add new equalities to
70 the problem to be solved. */
71 static int conservative
= 0;
73 /* Set to omega_true when the problem was successfully reduced, set to
74 omega_unknown when the solver is unable to determine an answer. */
75 static enum omega_result omega_found_reduction
;
77 /* Set to true when the solver is allowed to add omega_red equations. */
78 static bool create_color
= false;
80 /* Set to nonzero when the problem to be solved can be reduced. */
81 static int may_be_red
= 0;
83 /* When false, there should be no substitution equations in the
84 simplified problem. */
85 static int please_no_equalities_in_simplified_problems
= 0;
87 /* Variables names for pretty printing. */
88 static char wild_name
[200][40];
90 /* Pointer to the void problem. */
91 static omega_pb no_problem
= (omega_pb
) 0;
93 /* Pointer to the problem to be solved. */
94 static omega_pb original_problem
= (omega_pb
) 0;
97 /* Return the integer A divided by B. */
100 int_div (int a
, int b
)
105 return -((-a
+ b
- 1)/b
);
108 /* Return the integer A modulo B. */
111 int_mod (int a
, int b
)
113 return a
- b
* int_div (a
, b
);
116 /* Test whether equation E is red. */
119 omega_eqn_is_red (eqn e
, int desired_res
)
121 return (desired_res
== omega_simplify
&& e
->color
== omega_red
);
124 /* Return a string for VARIABLE. */
127 omega_var_to_str (int variable
)
129 if (0 <= variable
&& variable
<= 20)
130 return wild_name
[variable
];
132 if (-20 < variable
&& variable
< 0)
133 return wild_name
[40 + variable
];
135 /* Collapse all the entries that would have overflowed. */
136 return wild_name
[21];
139 /* Return a string for variable I in problem PB. */
142 omega_variable_to_str (omega_pb pb
, int i
)
144 return omega_var_to_str (pb
->var
[i
]);
147 /* Do nothing function: used for default initializations. */
150 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED
)
154 void (*omega_when_reduced
) (omega_pb
) = omega_no_procedure
;
156 /* Print to FILE from PB equation E with all its coefficients
160 omega_print_term (FILE *file
, omega_pb pb
, eqn e
, int c
)
164 int n
= pb
->num_vars
;
167 for (i
= 1; i
<= n
; i
++)
168 if (c
* e
->coef
[i
] > 0)
173 if (c
* e
->coef
[i
] == 1)
174 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
176 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
177 omega_variable_to_str (pb
, i
));
181 for (i
= 1; i
<= n
; i
++)
182 if (i
!= went_first
&& c
* e
->coef
[i
] != 0)
184 if (!first
&& c
* e
->coef
[i
] > 0)
185 fprintf (file
, " + ");
189 if (c
* e
->coef
[i
] == 1)
190 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
191 else if (c
* e
->coef
[i
] == -1)
192 fprintf (file
, " - %s", omega_variable_to_str (pb
, i
));
194 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
195 omega_variable_to_str (pb
, i
));
198 if (!first
&& c
* e
->coef
[0] > 0)
199 fprintf (file
, " + ");
201 if (first
|| c
* e
->coef
[0] != 0)
202 fprintf (file
, "%d", c
* e
->coef
[0]);
205 /* Print to FILE the equation E of problem PB. */
208 omega_print_eqn (FILE *file
, omega_pb pb
, eqn e
, bool test
, int extra
)
211 int n
= pb
->num_vars
+ extra
;
212 bool is_lt
= test
&& e
->coef
[0] == -1;
220 else if (e
->key
!= 0)
221 fprintf (file
, "%d: ", e
->key
);
224 if (e
->color
== omega_red
)
229 for (i
= is_lt
? 1 : 0; i
<= n
; i
++)
233 fprintf (file
, " + ");
238 fprintf (file
, "%d", -e
->coef
[i
]);
239 else if (e
->coef
[i
] == -1)
240 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
242 fprintf (file
, "%d * %s", -e
->coef
[i
],
243 omega_variable_to_str (pb
, i
));
258 fprintf (file
, " = ");
260 fprintf (file
, " < ");
262 fprintf (file
, " <= ");
266 for (i
= 0; i
<= n
; i
++)
270 fprintf (file
, " + ");
275 fprintf (file
, "%d", e
->coef
[i
]);
276 else if (e
->coef
[i
] == 1)
277 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
279 fprintf (file
, "%d * %s", e
->coef
[i
],
280 omega_variable_to_str (pb
, i
));
286 if (e
->color
== omega_red
)
290 /* Print to FILE all the variables of problem PB. */
293 omega_print_vars (FILE *file
, omega_pb pb
)
297 fprintf (file
, "variables = ");
299 if (pb
->safe_vars
> 0)
300 fprintf (file
, "protected (");
302 for (i
= 1; i
<= pb
->num_vars
; i
++)
304 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
306 if (i
== pb
->safe_vars
)
309 if (i
< pb
->num_vars
)
310 fprintf (file
, ", ");
313 fprintf (file
, "\n");
316 /* Dump problem PB. */
319 debug (omega_pb_d
&ref
)
321 omega_print_problem (stderr
, &ref
);
325 debug (omega_pb_d
*ptr
)
330 fprintf (stderr
, "<nil>\n");
333 /* Debug problem PB. */
336 debug_omega_problem (omega_pb pb
)
338 omega_print_problem (stderr
, pb
);
341 /* Print to FILE problem PB. */
344 omega_print_problem (FILE *file
, omega_pb pb
)
348 if (!pb
->variables_initialized
)
349 omega_initialize_variables (pb
);
351 omega_print_vars (file
, pb
);
353 for (e
= 0; e
< pb
->num_eqs
; e
++)
355 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
356 fprintf (file
, "\n");
359 fprintf (file
, "Done with EQ\n");
361 for (e
= 0; e
< pb
->num_geqs
; e
++)
363 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
364 fprintf (file
, "\n");
367 fprintf (file
, "Done with GEQ\n");
369 for (e
= 0; e
< pb
->num_subs
; e
++)
371 eqn eq
= &pb
->subs
[e
];
373 if (eq
->color
== omega_red
)
377 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
379 fprintf (file
, "#%d := ", eq
->key
);
381 omega_print_term (file
, pb
, eq
, 1);
383 if (eq
->color
== omega_red
)
386 fprintf (file
, "\n");
390 /* Return the number of equations in PB tagged omega_red. */
393 omega_count_red_equations (omega_pb pb
)
398 for (e
= 0; e
< pb
->num_eqs
; e
++)
399 if (pb
->eqs
[e
].color
== omega_red
)
401 for (i
= pb
->num_vars
; i
> 0; i
--)
402 if (pb
->geqs
[e
].coef
[i
])
405 if (i
== 0 && pb
->geqs
[e
].coef
[0] == 1)
411 for (e
= 0; e
< pb
->num_geqs
; e
++)
412 if (pb
->geqs
[e
].color
== omega_red
)
415 for (e
= 0; e
< pb
->num_subs
; e
++)
416 if (pb
->subs
[e
].color
== omega_red
)
422 /* Print to FILE all the equations in PB that are tagged omega_red. */
425 omega_print_red_equations (FILE *file
, omega_pb pb
)
429 if (!pb
->variables_initialized
)
430 omega_initialize_variables (pb
);
432 omega_print_vars (file
, pb
);
434 for (e
= 0; e
< pb
->num_eqs
; e
++)
435 if (pb
->eqs
[e
].color
== omega_red
)
437 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
438 fprintf (file
, "\n");
441 for (e
= 0; e
< pb
->num_geqs
; e
++)
442 if (pb
->geqs
[e
].color
== omega_red
)
444 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
445 fprintf (file
, "\n");
448 for (e
= 0; e
< pb
->num_subs
; e
++)
449 if (pb
->subs
[e
].color
== omega_red
)
451 eqn eq
= &pb
->subs
[e
];
455 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
457 fprintf (file
, "#%d := ", eq
->key
);
459 omega_print_term (file
, pb
, eq
, 1);
460 fprintf (file
, "]\n");
464 /* Pretty print PB to FILE. */
467 omega_pretty_print_problem (FILE *file
, omega_pb pb
)
469 int e
, v
, v1
, v2
, v3
, t
;
470 bool *live
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
471 int stuffPrinted
= 0;
476 } partial_order_type
;
478 partial_order_type
**po
= XNEWVEC (partial_order_type
*,
479 OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
480 int **po_eq
= XNEWVEC (int *, OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
481 int *last_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
482 int *first_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
483 int *chain_length
= XNEWVEC (int, OMEGA_MAX_VARS
);
484 int *chain
= XNEWVEC (int, OMEGA_MAX_VARS
);
488 if (!pb
->variables_initialized
)
489 omega_initialize_variables (pb
);
491 if (pb
->num_vars
> 0)
493 omega_eliminate_redundant (pb
, false);
495 for (e
= 0; e
< pb
->num_eqs
; e
++)
498 fprintf (file
, "; ");
501 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
504 for (e
= 0; e
< pb
->num_geqs
; e
++)
509 for (v
= 1; v
<= pb
->num_vars
; v
++)
511 last_links
[v
] = first_links
[v
] = 0;
514 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
518 for (e
= 0; e
< pb
->num_geqs
; e
++)
521 for (v
= 1; v
<= pb
->num_vars
; v
++)
522 if (pb
->geqs
[e
].coef
[v
] == 1)
524 else if (pb
->geqs
[e
].coef
[v
] == -1)
529 while (v1
> 0 && pb
->geqs
[e
].coef
[v1
] == 0)
534 while (v2
> 0 && pb
->geqs
[e
].coef
[v2
] == 0)
539 while (v3
> 0 && pb
->geqs
[e
].coef
[v3
] == 0)
542 if (pb
->geqs
[e
].coef
[0] > 0 || pb
->geqs
[e
].coef
[0] < -1
544 || pb
->geqs
[e
].coef
[v1
] * pb
->geqs
[e
].coef
[v2
] != -1)
546 /* Not a partial order relation. */
550 if (pb
->geqs
[e
].coef
[v1
] == 1)
557 /* Relation is v1 <= v2 or v1 < v2. */
558 po
[v1
][v2
] = ((pb
->geqs
[e
].coef
[0] == 0) ? le
: lt
);
562 for (v
= 1; v
<= pb
->num_vars
; v
++)
563 chain_length
[v
] = last_links
[v
];
565 /* Just in case pb->num_vars <= 0. */
567 for (t
= 0; t
< pb
->num_vars
; t
++)
571 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
572 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
573 if (po
[v1
][v2
] != none
&&
574 chain_length
[v1
] <= chain_length
[v2
])
576 chain_length
[v1
] = chain_length
[v2
] + 1;
581 /* Caught in cycle. */
582 gcc_assert (!change
);
584 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
585 if (chain_length
[v1
] == 0)
590 for (v1
= 2; v1
<= pb
->num_vars
; v1
++)
591 if (chain_length
[v1
] + first_links
[v1
] >
592 chain_length
[v
] + first_links
[v
])
595 if (chain_length
[v
] + first_links
[v
] == 0)
599 fprintf (file
, "; ");
603 /* Chain starts at v. */
608 for (e
= 0; e
< pb
->num_geqs
; e
++)
609 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == 1)
612 fprintf (file
, ", ");
614 tmp
= pb
->geqs
[e
].coef
[v
];
615 pb
->geqs
[e
].coef
[v
] = 0;
616 omega_print_term (file
, pb
, &pb
->geqs
[e
], -1);
617 pb
->geqs
[e
].coef
[v
] = tmp
;
623 fprintf (file
, " <= ");
632 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
633 if (po
[v
][v2
] && chain_length
[v
] == 1 + chain_length
[v2
])
636 if (v2
> pb
->num_vars
)
643 fprintf (file
, "%s", omega_variable_to_str (pb
, chain
[0]));
645 for (multiprint
= false, i
= 1; i
< m
; i
++)
651 fprintf (file
, " <= ");
653 fprintf (file
, " < ");
655 fprintf (file
, "%s", omega_variable_to_str (pb
, v2
));
656 live
[po_eq
[v
][v2
]] = false;
658 if (!multiprint
&& i
< m
- 1)
659 for (v3
= 1; v3
<= pb
->num_vars
; v3
++)
661 if (v
== v3
|| v2
== v3
662 || po
[v
][v2
] != po
[v
][v3
]
663 || po
[v2
][chain
[i
+ 1]] != po
[v3
][chain
[i
+ 1]])
666 fprintf (file
, ",%s", omega_variable_to_str (pb
, v3
));
667 live
[po_eq
[v
][v3
]] = false;
668 live
[po_eq
[v3
][chain
[i
+ 1]]] = false;
676 /* Print last_links. */
681 for (e
= 0; e
< pb
->num_geqs
; e
++)
682 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == -1)
685 fprintf (file
, ", ");
687 fprintf (file
, " <= ");
689 tmp
= pb
->geqs
[e
].coef
[v
];
690 pb
->geqs
[e
].coef
[v
] = 0;
691 omega_print_term (file
, pb
, &pb
->geqs
[e
], 1);
692 pb
->geqs
[e
].coef
[v
] = tmp
;
699 for (e
= 0; e
< pb
->num_geqs
; e
++)
703 fprintf (file
, "; ");
705 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
708 for (e
= 0; e
< pb
->num_subs
; e
++)
710 eqn eq
= &pb
->subs
[e
];
713 fprintf (file
, "; ");
718 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
720 fprintf (file
, "#%d := ", eq
->key
);
722 omega_print_term (file
, pb
, eq
, 1);
735 /* Assign to variable I in PB the next wildcard name. The name of a
736 wildcard is a negative number. */
737 static int next_wild_card
= 0;
740 omega_name_wild_card (omega_pb pb
, int i
)
743 if (next_wild_card
< -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS
))
745 pb
->var
[i
] = next_wild_card
;
748 /* Return the index of the last protected (or safe) variable in PB,
749 after having added a new wildcard variable. */
752 omega_add_new_wild_card (omega_pb pb
)
755 int i
= ++pb
->safe_vars
;
758 /* Make a free place in the protected (safe) variables, by moving
759 the non protected variable pointed by "I" at the end, ie. at
760 offset pb->num_vars. */
761 if (pb
->num_vars
!= i
)
763 /* Move "I" for all the inequalities. */
764 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
766 if (pb
->geqs
[e
].coef
[i
])
767 pb
->geqs
[e
].touched
= 1;
769 pb
->geqs
[e
].coef
[pb
->num_vars
] = pb
->geqs
[e
].coef
[i
];
772 /* Move "I" for all the equalities. */
773 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
774 pb
->eqs
[e
].coef
[pb
->num_vars
] = pb
->eqs
[e
].coef
[i
];
776 /* Move "I" for all the substitutions. */
777 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
778 pb
->subs
[e
].coef
[pb
->num_vars
] = pb
->subs
[e
].coef
[i
];
780 /* Move the identifier. */
781 pb
->var
[pb
->num_vars
] = pb
->var
[i
];
784 /* Initialize at zero all the coefficients */
785 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
786 pb
->geqs
[e
].coef
[i
] = 0;
788 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
789 pb
->eqs
[e
].coef
[i
] = 0;
791 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
792 pb
->subs
[e
].coef
[i
] = 0;
794 /* And give it a name. */
795 omega_name_wild_card (pb
, i
);
799 /* Delete inequality E from problem PB that has N_VARS variables. */
802 omega_delete_geq (omega_pb pb
, int e
, int n_vars
)
804 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
806 fprintf (dump_file
, "Deleting %d (last:%d): ", e
, pb
->num_geqs
- 1);
807 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
808 fprintf (dump_file
, "\n");
811 if (e
< pb
->num_geqs
- 1)
812 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
817 /* Delete extra inequality E from problem PB that has N_VARS
821 omega_delete_geq_extra (omega_pb pb
, int e
, int n_vars
)
823 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
825 fprintf (dump_file
, "Deleting %d: ",e
);
826 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
827 fprintf (dump_file
, "\n");
830 if (e
< pb
->num_geqs
- 1)
831 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
837 /* Remove variable I from problem PB. */
840 omega_delete_variable (omega_pb pb
, int i
)
842 int n_vars
= pb
->num_vars
;
845 if (omega_safe_var_p (pb
, i
))
847 int j
= pb
->safe_vars
;
849 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
851 pb
->geqs
[e
].touched
= 1;
852 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[j
];
853 pb
->geqs
[e
].coef
[j
] = pb
->geqs
[e
].coef
[n_vars
];
856 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
858 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[j
];
859 pb
->eqs
[e
].coef
[j
] = pb
->eqs
[e
].coef
[n_vars
];
862 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
864 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[j
];
865 pb
->subs
[e
].coef
[j
] = pb
->subs
[e
].coef
[n_vars
];
868 pb
->var
[i
] = pb
->var
[j
];
869 pb
->var
[j
] = pb
->var
[n_vars
];
873 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
874 if (pb
->geqs
[e
].coef
[n_vars
])
876 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[n_vars
];
877 pb
->geqs
[e
].touched
= 1;
880 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
881 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[n_vars
];
883 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
884 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[n_vars
];
886 pb
->var
[i
] = pb
->var
[n_vars
];
889 if (omega_safe_var_p (pb
, i
))
895 /* Because the coefficients of an equation are sparse, PACKING records
896 indices for non null coefficients. */
899 /* Set up the coefficients of PACKING, following the coefficients of
900 equation EQN that has NUM_VARS variables. */
903 setup_packing (eqn eqn
, int num_vars
)
908 for (k
= num_vars
; k
>= 0; k
--)
915 /* Computes a linear combination of EQ and SUB at VAR with coefficient
916 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
917 non null indices of SUB stored in PACKING. */
920 omega_substitute_red_1 (eqn eq
, eqn sub
, int var
, int c
, bool *found_black
,
923 if (eq
->coef
[var
] != 0)
925 if (eq
->color
== omega_black
)
929 int j
, k
= eq
->coef
[var
];
933 for (j
= top_var
; j
>= 0; j
--)
934 eq
->coef
[packing
[j
]] -= sub
->coef
[packing
[j
]] * k
* c
;
939 /* Substitute in PB variable VAR with "C * SUB". */
942 omega_substitute_red (omega_pb pb
, eqn sub
, int var
, int c
, bool *found_black
)
944 int e
, top_var
= setup_packing (sub
, pb
->num_vars
);
946 *found_black
= false;
948 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
950 if (sub
->color
== omega_red
)
951 fprintf (dump_file
, "[");
953 fprintf (dump_file
, "substituting using %s := ",
954 omega_variable_to_str (pb
, var
));
955 omega_print_term (dump_file
, pb
, sub
, -c
);
957 if (sub
->color
== omega_red
)
958 fprintf (dump_file
, "]");
960 fprintf (dump_file
, "\n");
961 omega_print_vars (dump_file
, pb
);
964 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
966 eqn eqn
= &(pb
->eqs
[e
]);
968 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
970 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
972 omega_print_eq (dump_file
, pb
, eqn
);
973 fprintf (dump_file
, "\n");
977 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
979 eqn eqn
= &(pb
->geqs
[e
]);
981 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
983 if (eqn
->coef
[var
] && eqn
->color
== omega_red
)
986 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
988 omega_print_geq (dump_file
, pb
, eqn
);
989 fprintf (dump_file
, "\n");
993 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
995 eqn eqn
= &(pb
->subs
[e
]);
997 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
999 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1001 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1002 omega_print_term (dump_file
, pb
, eqn
, 1);
1003 fprintf (dump_file
, "\n");
1007 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1008 fprintf (dump_file
, "---\n\n");
1010 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1011 *found_black
= true;
1014 /* Substitute in PB variable VAR with "C * SUB". */
1017 omega_substitute (omega_pb pb
, eqn sub
, int var
, int c
)
1020 int top_var
= setup_packing (sub
, pb
->num_vars
);
1022 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1024 fprintf (dump_file
, "substituting using %s := ",
1025 omega_variable_to_str (pb
, var
));
1026 omega_print_term (dump_file
, pb
, sub
, -c
);
1027 fprintf (dump_file
, "\n");
1028 omega_print_vars (dump_file
, pb
);
1033 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1034 pb
->eqs
[e
].coef
[var
] = 0;
1036 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1037 if (pb
->geqs
[e
].coef
[var
] != 0)
1039 pb
->geqs
[e
].touched
= 1;
1040 pb
->geqs
[e
].coef
[var
] = 0;
1043 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1044 pb
->subs
[e
].coef
[var
] = 0;
1046 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1049 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1051 for (k
= pb
->num_vars
; k
>= 0; k
--)
1054 eqn
->key
= pb
->var
[var
];
1055 eqn
->color
= omega_black
;
1058 else if (top_var
== 0 && packing
[0] == 0)
1060 c
= -sub
->coef
[0] * c
;
1062 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1064 pb
->eqs
[e
].coef
[0] += pb
->eqs
[e
].coef
[var
] * c
;
1065 pb
->eqs
[e
].coef
[var
] = 0;
1068 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1069 if (pb
->geqs
[e
].coef
[var
] != 0)
1071 pb
->geqs
[e
].coef
[0] += pb
->geqs
[e
].coef
[var
] * c
;
1072 pb
->geqs
[e
].coef
[var
] = 0;
1073 pb
->geqs
[e
].touched
= 1;
1076 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1078 pb
->subs
[e
].coef
[0] += pb
->subs
[e
].coef
[var
] * c
;
1079 pb
->subs
[e
].coef
[var
] = 0;
1082 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1085 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1087 for (k
= pb
->num_vars
; k
>= 1; k
--)
1091 eqn
->key
= pb
->var
[var
];
1092 eqn
->color
= omega_black
;
1095 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1097 fprintf (dump_file
, "---\n\n");
1098 omega_print_problem (dump_file
, pb
);
1099 fprintf (dump_file
, "===\n\n");
1104 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1106 eqn eqn
= &(pb
->eqs
[e
]);
1107 int k
= eqn
->coef
[var
];
1114 for (j
= top_var
; j
>= 0; j
--)
1117 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1121 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1123 omega_print_eq (dump_file
, pb
, eqn
);
1124 fprintf (dump_file
, "\n");
1128 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1130 eqn eqn
= &(pb
->geqs
[e
]);
1131 int k
= eqn
->coef
[var
];
1139 for (j
= top_var
; j
>= 0; j
--)
1142 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1146 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1148 omega_print_geq (dump_file
, pb
, eqn
);
1149 fprintf (dump_file
, "\n");
1153 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1155 eqn eqn
= &(pb
->subs
[e
]);
1156 int k
= eqn
->coef
[var
];
1163 for (j
= top_var
; j
>= 0; j
--)
1166 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1170 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1172 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1173 omega_print_term (dump_file
, pb
, eqn
, 1);
1174 fprintf (dump_file
, "\n");
1178 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1180 fprintf (dump_file
, "---\n\n");
1181 omega_print_problem (dump_file
, pb
);
1182 fprintf (dump_file
, "===\n\n");
1185 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1188 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1191 for (k
= pb
->num_vars
; k
>= 0; k
--)
1192 eqn
->coef
[k
] = c
* (sub
->coef
[k
]);
1194 eqn
->key
= pb
->var
[var
];
1195 eqn
->color
= sub
->color
;
1200 /* Solve e = factor alpha for x_j and substitute. */
1203 omega_do_mod (omega_pb pb
, int factor
, int e
, int j
)
1206 eqn eq
= omega_alloc_eqns (0, 1);
1208 bool kill_j
= false;
1210 omega_copy_eqn (eq
, &pb
->eqs
[e
], pb
->num_vars
);
1212 for (k
= pb
->num_vars
; k
>= 0; k
--)
1214 eq
->coef
[k
] = int_mod (eq
->coef
[k
], factor
);
1216 if (2 * eq
->coef
[k
] >= factor
)
1217 eq
->coef
[k
] -= factor
;
1220 nfactor
= eq
->coef
[j
];
1222 if (omega_safe_var_p (pb
, j
) && !omega_wildcard_p (pb
, j
))
1224 i
= omega_add_new_wild_card (pb
);
1225 eq
->coef
[pb
->num_vars
] = eq
->coef
[i
];
1227 eq
->coef
[i
] = -factor
;
1232 eq
->coef
[j
] = -factor
;
1233 if (!omega_wildcard_p (pb
, j
))
1234 omega_name_wild_card (pb
, j
);
1237 omega_substitute (pb
, eq
, j
, nfactor
);
1239 for (k
= pb
->num_vars
; k
>= 0; k
--)
1240 pb
->eqs
[e
].coef
[k
] = pb
->eqs
[e
].coef
[k
] / factor
;
1243 omega_delete_variable (pb
, j
);
1245 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1247 fprintf (dump_file
, "Mod-ing and normalizing produces:\n");
1248 omega_print_problem (dump_file
, pb
);
1251 omega_free_eqns (eq
, 1);
1254 /* Multiplies by -1 inequality E. */
1257 omega_negate_geq (omega_pb pb
, int e
)
1261 for (i
= pb
->num_vars
; i
>= 0; i
--)
1262 pb
->geqs
[e
].coef
[i
] *= -1;
1264 pb
->geqs
[e
].coef
[0]--;
1265 pb
->geqs
[e
].touched
= 1;
1268 /* Returns OMEGA_TRUE when problem PB has a solution. */
1270 static enum omega_result
1271 verify_omega_pb (omega_pb pb
)
1273 enum omega_result result
;
1275 bool any_color
= false;
1276 omega_pb tmp_problem
= XNEW (struct omega_pb_d
);
1278 omega_copy_problem (tmp_problem
, pb
);
1279 tmp_problem
->safe_vars
= 0;
1280 tmp_problem
->num_subs
= 0;
1282 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1283 if (pb
->geqs
[e
].color
== omega_red
)
1289 if (please_no_equalities_in_simplified_problems
)
1293 original_problem
= no_problem
;
1295 original_problem
= pb
;
1297 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1299 fprintf (dump_file
, "verifying problem");
1302 fprintf (dump_file
, " (color mode)");
1304 fprintf (dump_file
, " :\n");
1305 omega_print_problem (dump_file
, pb
);
1308 result
= omega_solve_problem (tmp_problem
, omega_unknown
);
1309 original_problem
= no_problem
;
1312 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1314 if (result
!= omega_false
)
1315 fprintf (dump_file
, "verified problem\n");
1317 fprintf (dump_file
, "disproved problem\n");
1318 omega_print_problem (dump_file
, pb
);
1324 /* Add a new equality to problem PB at last position E. */
1327 adding_equality_constraint (omega_pb pb
, int e
)
1329 if (original_problem
!= no_problem
1330 && original_problem
!= pb
1334 int e2
= original_problem
->num_eqs
++;
1336 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1338 "adding equality constraint %d to outer problem\n", e2
);
1339 omega_init_eqn_zero (&original_problem
->eqs
[e2
],
1340 original_problem
->num_vars
);
1342 for (i
= pb
->num_vars
; i
>= 1; i
--)
1344 for (j
= original_problem
->num_vars
; j
>= 1; j
--)
1345 if (original_problem
->var
[j
] == pb
->var
[i
])
1350 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1351 fprintf (dump_file
, "retracting\n");
1352 original_problem
->num_eqs
--;
1355 original_problem
->eqs
[e2
].coef
[j
] = pb
->eqs
[e
].coef
[i
];
1358 original_problem
->eqs
[e2
].coef
[0] = pb
->eqs
[e
].coef
[0];
1360 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1361 omega_print_problem (dump_file
, original_problem
);
1365 static int *fast_lookup
;
1366 static int *fast_lookup_red
;
1370 normalize_uncoupled
,
1372 } normalize_return_type
;
1374 /* Normalizes PB by removing redundant constraints. Returns
1375 normalize_false when the constraints system has no solution,
1376 otherwise returns normalize_coupled or normalize_uncoupled. */
1378 static normalize_return_type
1379 normalize_omega_problem (omega_pb pb
)
1381 int e
, i
, j
, k
, n_vars
;
1382 int coupled_subscripts
= 0;
1384 n_vars
= pb
->num_vars
;
1386 for (e
= 0; e
< pb
->num_geqs
; e
++)
1388 if (!pb
->geqs
[e
].touched
)
1390 if (!single_var_geq (&pb
->geqs
[e
], n_vars
))
1391 coupled_subscripts
= 1;
1395 int g
, top_var
, i0
, hashCode
;
1396 int *p
= &packing
[0];
1398 for (k
= 1; k
<= n_vars
; k
++)
1399 if (pb
->geqs
[e
].coef
[k
])
1402 top_var
= (p
- &packing
[0]) - 1;
1406 if (pb
->geqs
[e
].coef
[0] < 0)
1408 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1410 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1411 fprintf (dump_file
, "\nequations have no solution \n");
1413 return normalize_false
;
1416 omega_delete_geq (pb
, e
, n_vars
);
1420 else if (top_var
== 0)
1422 int singlevar
= packing
[0];
1424 g
= pb
->geqs
[e
].coef
[singlevar
];
1428 pb
->geqs
[e
].coef
[singlevar
] = 1;
1429 pb
->geqs
[e
].key
= singlevar
;
1434 pb
->geqs
[e
].coef
[singlevar
] = -1;
1435 pb
->geqs
[e
].key
= -singlevar
;
1439 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1444 int hash_key_multiplier
= 31;
1446 coupled_subscripts
= 1;
1449 g
= pb
->geqs
[e
].coef
[i
];
1450 hashCode
= g
* (i
+ 3);
1455 for (; i0
>= 0; i0
--)
1460 x
= pb
->geqs
[e
].coef
[i
];
1461 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1476 for (; i0
>= 0; i0
--)
1480 x
= pb
->geqs
[e
].coef
[i
];
1481 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1486 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1489 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1490 hashCode
= pb
->geqs
[e
].coef
[i
] * (i
+ 3);
1492 for (; i0
>= 0; i0
--)
1495 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1496 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3)
1497 + pb
->geqs
[e
].coef
[i
];
1501 g2
= abs (hashCode
);
1503 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1505 fprintf (dump_file
, "Hash code = %d, eqn = ", hashCode
);
1506 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1507 fprintf (dump_file
, "\n");
1510 j
= g2
% HASH_TABLE_SIZE
;
1513 eqn proto
= &(hash_master
[j
]);
1515 if (proto
->touched
== g2
)
1517 if (proto
->coef
[0] == top_var
)
1520 for (i0
= top_var
; i0
>= 0; i0
--)
1524 if (pb
->geqs
[e
].coef
[i
] != proto
->coef
[i
])
1528 for (i0
= top_var
; i0
>= 0; i0
--)
1532 if (pb
->geqs
[e
].coef
[i
] != -proto
->coef
[i
])
1539 pb
->geqs
[e
].key
= proto
->key
;
1541 pb
->geqs
[e
].key
= -proto
->key
;
1546 else if (proto
->touched
< 0)
1548 omega_init_eqn_zero (proto
, pb
->num_vars
);
1550 for (i0
= top_var
; i0
>= 0; i0
--)
1553 proto
->coef
[i
] = pb
->geqs
[e
].coef
[i
];
1556 for (i0
= top_var
; i0
>= 0; i0
--)
1559 proto
->coef
[i
] = -pb
->geqs
[e
].coef
[i
];
1562 proto
->coef
[0] = top_var
;
1563 proto
->touched
= g2
;
1565 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1566 fprintf (dump_file
, " constraint key = %d\n",
1569 proto
->key
= next_key
++;
1571 /* Too many hash keys generated. */
1572 gcc_assert (proto
->key
<= MAX_KEYS
);
1575 pb
->geqs
[e
].key
= proto
->key
;
1577 pb
->geqs
[e
].key
= -proto
->key
;
1582 j
= (j
+ 1) % HASH_TABLE_SIZE
;
1586 pb
->geqs
[e
].touched
= 0;
1590 int eKey
= pb
->geqs
[e
].key
;
1594 int cTerm
= pb
->geqs
[e
].coef
[0];
1595 e2
= fast_lookup
[MAX_KEYS
- eKey
];
1597 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1598 && pb
->geqs
[e2
].color
== omega_black
)
1600 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1602 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1604 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1605 fprintf (dump_file
, "\n");
1606 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1608 "\nequations have no solution \n");
1610 return normalize_false
;
1613 if (pb
->geqs
[e2
].coef
[0] == -cTerm
1615 || pb
->geqs
[e
].color
== omega_black
))
1617 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1619 if (pb
->geqs
[e
].color
== omega_black
)
1620 adding_equality_constraint (pb
, pb
->num_eqs
);
1622 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1626 e2
= fast_lookup_red
[MAX_KEYS
- eKey
];
1628 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1629 && pb
->geqs
[e2
].color
== omega_red
)
1631 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1633 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1635 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1636 fprintf (dump_file
, "\n");
1637 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1639 "\nequations have no solution \n");
1641 return normalize_false
;
1644 if (pb
->geqs
[e2
].coef
[0] == -cTerm
&& create_color
)
1646 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1648 pb
->eqs
[pb
->num_eqs
].color
= omega_red
;
1650 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1654 e2
= fast_lookup
[MAX_KEYS
+ eKey
];
1656 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1657 && pb
->geqs
[e2
].color
== omega_black
)
1659 if (pb
->geqs
[e2
].coef
[0] > cTerm
)
1661 if (pb
->geqs
[e
].color
== omega_black
)
1663 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1666 "Removing Redundant Equation: ");
1667 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1668 fprintf (dump_file
, "\n");
1670 "[a] Made Redundant by: ");
1671 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1672 fprintf (dump_file
, "\n");
1674 pb
->geqs
[e2
].coef
[0] = cTerm
;
1675 omega_delete_geq (pb
, e
, n_vars
);
1682 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1684 fprintf (dump_file
, "Removing Redundant Equation: ");
1685 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1686 fprintf (dump_file
, "\n");
1687 fprintf (dump_file
, "[b] Made Redundant by: ");
1688 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1689 fprintf (dump_file
, "\n");
1691 omega_delete_geq (pb
, e
, n_vars
);
1697 e2
= fast_lookup_red
[MAX_KEYS
+ eKey
];
1699 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1700 && pb
->geqs
[e2
].color
== omega_red
)
1702 if (pb
->geqs
[e2
].coef
[0] >= cTerm
)
1704 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1706 fprintf (dump_file
, "Removing Redundant Equation: ");
1707 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1708 fprintf (dump_file
, "\n");
1709 fprintf (dump_file
, "[c] Made Redundant by: ");
1710 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1711 fprintf (dump_file
, "\n");
1713 pb
->geqs
[e2
].coef
[0] = cTerm
;
1714 pb
->geqs
[e2
].color
= pb
->geqs
[e
].color
;
1716 else if (pb
->geqs
[e
].color
== omega_red
)
1718 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1720 fprintf (dump_file
, "Removing Redundant Equation: ");
1721 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1722 fprintf (dump_file
, "\n");
1723 fprintf (dump_file
, "[d] Made Redundant by: ");
1724 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1725 fprintf (dump_file
, "\n");
1728 omega_delete_geq (pb
, e
, n_vars
);
1735 if (pb
->geqs
[e
].color
== omega_red
)
1736 fast_lookup_red
[MAX_KEYS
+ eKey
] = e
;
1738 fast_lookup
[MAX_KEYS
+ eKey
] = e
;
1742 create_color
= false;
1743 return coupled_subscripts
? normalize_coupled
: normalize_uncoupled
;
1746 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1747 of variables in EQN. */
1750 divide_eqn_by_gcd (eqn eqn
, int n_vars
)
1754 for (var
= n_vars
; var
>= 0; var
--)
1755 g
= gcd (abs (eqn
->coef
[var
]), g
);
1758 for (var
= n_vars
; var
>= 0; var
--)
1759 eqn
->coef
[var
] = eqn
->coef
[var
] / g
;
1762 /* Rewrite some non-safe variables in function of protected
1763 wildcard variables. */
1766 cleanout_wildcards (omega_pb pb
)
1769 int n_vars
= pb
->num_vars
;
1770 bool renormalize
= false;
1772 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1773 for (i
= n_vars
; !omega_safe_var_p (pb
, i
); i
--)
1774 if (pb
->eqs
[e
].coef
[i
] != 0)
1776 /* i is the last nonzero non-safe variable. */
1778 for (j
= i
- 1; !omega_safe_var_p (pb
, j
); j
--)
1779 if (pb
->eqs
[e
].coef
[j
] != 0)
1782 /* j is the next nonzero non-safe variable, or points
1783 to a safe variable: it is then a wildcard variable. */
1786 if (omega_safe_var_p (pb
, j
))
1788 eqn sub
= &(pb
->eqs
[e
]);
1789 int c
= pb
->eqs
[e
].coef
[i
];
1793 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1796 "Found a single wild card equality: ");
1797 omega_print_eq (dump_file
, pb
, &pb
->eqs
[e
]);
1798 fprintf (dump_file
, "\n");
1799 omega_print_problem (dump_file
, pb
);
1802 for (e2
= pb
->num_eqs
- 1; e2
>= 0; e2
--)
1803 if (e
!= e2
&& pb
->eqs
[e2
].coef
[i
]
1804 && (pb
->eqs
[e2
].color
== omega_red
1805 || (pb
->eqs
[e2
].color
== omega_black
1806 && pb
->eqs
[e
].color
== omega_black
)))
1808 eqn eqn
= &(pb
->eqs
[e2
]);
1811 for (var
= n_vars
; var
>= 0; var
--)
1812 eqn
->coef
[var
] *= a
;
1816 for (var
= n_vars
; var
>= 0; var
--)
1817 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1820 divide_eqn_by_gcd (eqn
, n_vars
);
1823 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
1824 if (pb
->geqs
[e2
].coef
[i
]
1825 && (pb
->geqs
[e2
].color
== omega_red
1826 || (pb
->eqs
[e
].color
== omega_black
1827 && pb
->geqs
[e2
].color
== omega_black
)))
1829 eqn eqn
= &(pb
->geqs
[e2
]);
1832 for (var
= n_vars
; var
>= 0; var
--)
1833 eqn
->coef
[var
] *= a
;
1837 for (var
= n_vars
; var
>= 0; var
--)
1838 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1845 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
1846 if (pb
->subs
[e2
].coef
[i
]
1847 && (pb
->subs
[e2
].color
== omega_red
1848 || (pb
->subs
[e2
].color
== omega_black
1849 && pb
->eqs
[e
].color
== omega_black
)))
1851 eqn eqn
= &(pb
->subs
[e2
]);
1854 for (var
= n_vars
; var
>= 0; var
--)
1855 eqn
->coef
[var
] *= a
;
1859 for (var
= n_vars
; var
>= 0; var
--)
1860 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1863 divide_eqn_by_gcd (eqn
, n_vars
);
1866 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1868 fprintf (dump_file
, "cleaned-out wildcard: ");
1869 omega_print_problem (dump_file
, pb
);
1876 normalize_omega_problem (pb
);
1879 /* Make variable IDX unprotected in PB, by swapping its index at the
1880 PB->safe_vars rank. */
1883 omega_unprotect_1 (omega_pb pb
, int *idx
, bool *unprotect
)
1885 /* If IDX is protected... */
1886 if (*idx
< pb
->safe_vars
)
1888 /* ... swap its index with the last non protected index. */
1889 int j
= pb
->safe_vars
;
1892 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1894 pb
->geqs
[e
].touched
= 1;
1895 std::swap (pb
->geqs
[e
].coef
[*idx
], pb
->geqs
[e
].coef
[j
]);
1898 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1899 std::swap (pb
->eqs
[e
].coef
[*idx
], pb
->eqs
[e
].coef
[j
]);
1901 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1902 std::swap (pb
->subs
[e
].coef
[*idx
], pb
->subs
[e
].coef
[j
]);
1905 std::swap (unprotect
[*idx
], unprotect
[j
]);
1907 std::swap (pb
->var
[*idx
], pb
->var
[j
]);
1908 pb
->forwarding_address
[pb
->var
[*idx
]] = *idx
;
1909 pb
->forwarding_address
[pb
->var
[j
]] = j
;
1913 /* The variable at pb->safe_vars is also unprotected now. */
1917 /* During the Fourier-Motzkin elimination some variables are
1918 substituted with other variables. This function resurrects the
1919 substituted variables in PB. */
1922 resurrect_subs (omega_pb pb
)
1924 if (pb
->num_subs
> 0
1925 && please_no_equalities_in_simplified_problems
== 0)
1929 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1932 "problem reduced, bringing variables back to life\n");
1933 omega_print_problem (dump_file
, pb
);
1936 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
1937 if (omega_wildcard_p (pb
, i
))
1938 omega_unprotect_1 (pb
, &i
, NULL
);
1942 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1943 if (single_var_geq (&pb
->geqs
[e
], pb
->num_vars
))
1945 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
1946 pb
->geqs
[e
].key
+= (pb
->geqs
[e
].key
> 0 ? m
: -m
);
1950 pb
->geqs
[e
].touched
= 1;
1951 pb
->geqs
[e
].key
= 0;
1954 for (i
= pb
->num_vars
; !omega_safe_var_p (pb
, i
); i
--)
1956 pb
->var
[i
+ m
] = pb
->var
[i
];
1958 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1959 pb
->geqs
[e
].coef
[i
+ m
] = pb
->geqs
[e
].coef
[i
];
1961 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1962 pb
->eqs
[e
].coef
[i
+ m
] = pb
->eqs
[e
].coef
[i
];
1964 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1965 pb
->subs
[e
].coef
[i
+ m
] = pb
->subs
[e
].coef
[i
];
1968 for (i
= pb
->safe_vars
+ m
; !omega_safe_var_p (pb
, i
); i
--)
1970 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1971 pb
->geqs
[e
].coef
[i
] = 0;
1973 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1974 pb
->eqs
[e
].coef
[i
] = 0;
1976 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1977 pb
->subs
[e
].coef
[i
] = 0;
1982 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1984 pb
->var
[pb
->safe_vars
+ 1 + e
] = pb
->subs
[e
].key
;
1985 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e
]),
1987 pb
->eqs
[pb
->num_eqs
].coef
[pb
->safe_vars
+ 1 + e
] = -1;
1988 pb
->eqs
[pb
->num_eqs
].color
= omega_black
;
1990 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1992 fprintf (dump_file
, "brought back: ");
1993 omega_print_eq (dump_file
, pb
, &pb
->eqs
[pb
->num_eqs
]);
1994 fprintf (dump_file
, "\n");
1998 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2004 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2006 fprintf (dump_file
, "variables brought back to life\n");
2007 omega_print_problem (dump_file
, pb
);
2010 cleanout_wildcards (pb
);
2015 implies (unsigned int a
, unsigned int b
)
2017 return (a
== (a
& b
));
2020 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2021 extra step is performed. Returns omega_false when there exist no
2022 solution, omega_true otherwise. */
2025 omega_eliminate_redundant (omega_pb pb
, bool expensive
)
2027 int c
, e
, e1
, e2
, e3
, p
, q
, i
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2028 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2029 omega_pb tmp_problem
;
2031 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2032 unsigned int *peqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2033 unsigned int *zeqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2034 unsigned int *neqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2036 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2037 unsigned int pp
, pz
, pn
;
2039 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2041 fprintf (dump_file
, "in eliminate Redundant:\n");
2042 omega_print_problem (dump_file
, pb
);
2045 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2050 peqs
[e
] = zeqs
[e
] = neqs
[e
] = 0;
2052 for (i
= pb
->num_vars
; i
>= 1; i
--)
2054 if (pb
->geqs
[e
].coef
[i
] > 0)
2056 else if (pb
->geqs
[e
].coef
[i
] < 0)
2066 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2068 for (e2
= e1
- 1; e2
>= 0; e2
--)
2071 for (p
= pb
->num_vars
; p
> 1; p
--)
2072 for (q
= p
- 1; q
> 0; q
--)
2073 if ((alpha
= pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
]
2074 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]) != 0)
2080 pz
= ((zeqs
[e1
] & zeqs
[e2
]) | (peqs
[e1
] & neqs
[e2
])
2081 | (neqs
[e1
] & peqs
[e2
]));
2082 pp
= peqs
[e1
] | peqs
[e2
];
2083 pn
= neqs
[e1
] | neqs
[e2
];
2085 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2086 if (e3
!= e1
&& e3
!= e2
)
2088 if (!implies (zeqs
[e3
], pz
))
2091 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2092 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2093 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2094 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2097 if (alpha1
* alpha2
<= 0)
2109 /* Trying to prove e3 is redundant. */
2110 if (!implies (peqs
[e3
], pp
)
2111 || !implies (neqs
[e3
], pn
))
2114 if (pb
->geqs
[e3
].color
== omega_black
2115 && (pb
->geqs
[e1
].color
== omega_red
2116 || pb
->geqs
[e2
].color
== omega_red
))
2119 for (k
= pb
->num_vars
; k
>= 1; k
--)
2120 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2121 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2122 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2125 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2126 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2128 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2130 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2133 "found redundant inequality\n");
2135 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2136 alpha1
, alpha2
, alpha3
);
2138 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2139 fprintf (dump_file
, "\n");
2140 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2141 fprintf (dump_file
, "\n=> ");
2142 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2143 fprintf (dump_file
, "\n\n");
2151 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2152 or trying to prove e3 < 0, and therefore the
2153 problem has no solutions. */
2154 if (!implies (peqs
[e3
], pn
)
2155 || !implies (neqs
[e3
], pp
))
2158 if (pb
->geqs
[e1
].color
== omega_red
2159 || pb
->geqs
[e2
].color
== omega_red
2160 || pb
->geqs
[e3
].color
== omega_red
)
2163 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2164 for (k
= pb
->num_vars
; k
>= 1; k
--)
2165 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2166 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2167 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2170 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2171 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2173 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0]))
2175 /* We just proved e3 < 0, so no solutions exist. */
2176 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2179 "found implied over tight inequality\n");
2181 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2182 alpha1
, alpha2
, -alpha3
);
2183 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2184 fprintf (dump_file
, "\n");
2185 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2186 fprintf (dump_file
, "\n=> not ");
2187 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2188 fprintf (dump_file
, "\n\n");
2196 else if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] - 1))
2198 /* We just proved that e3 <=0, so e3 = 0. */
2199 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2202 "found implied tight inequality\n");
2204 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2205 alpha1
, alpha2
, -alpha3
);
2206 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2207 fprintf (dump_file
, "\n");
2208 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2209 fprintf (dump_file
, "\n=> inverse ");
2210 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2211 fprintf (dump_file
, "\n\n");
2214 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++],
2215 &pb
->geqs
[e3
], pb
->num_vars
);
2216 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2217 adding_equality_constraint (pb
, pb
->num_eqs
- 1);
2225 /* Delete the inequalities that were marked as dead. */
2226 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2228 omega_delete_geq (pb
, e
, pb
->num_vars
);
2231 goto eliminate_redundant_done
;
2233 tmp_problem
= XNEW (struct omega_pb_d
);
2236 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2238 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2241 "checking equation %d to see if it is redundant: ", e
);
2242 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2243 fprintf (dump_file
, "\n");
2246 omega_copy_problem (tmp_problem
, pb
);
2247 omega_negate_geq (tmp_problem
, e
);
2248 tmp_problem
->safe_vars
= 0;
2249 tmp_problem
->variables_freed
= false;
2251 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2252 omega_delete_geq (pb
, e
, pb
->num_vars
);
2258 if (!omega_reduce_with_subs
)
2260 resurrect_subs (pb
);
2261 gcc_assert (please_no_equalities_in_simplified_problems
2262 || pb
->num_subs
== 0);
2265 eliminate_redundant_done
:
2273 /* For each inequality that has coefficients bigger than 20, try to
2274 create a new constraint that cannot be derived from the original
2275 constraint and that has smaller coefficients. Add the new
2276 constraint at the end of geqs. Return the number of inequalities
2277 that have been added to PB. */
2280 smooth_weird_equations (omega_pb pb
)
2282 int e1
, e2
, e3
, p
, q
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2287 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2288 if (pb
->geqs
[e1
].color
== omega_black
)
2292 for (v
= pb
->num_vars
; v
>= 1; v
--)
2293 if (pb
->geqs
[e1
].coef
[v
] != 0 && abs (pb
->geqs
[e1
].coef
[v
]) < g
)
2294 g
= abs (pb
->geqs
[e1
].coef
[v
]);
2301 for (v
= pb
->num_vars
; v
>= 1; v
--)
2302 pb
->geqs
[e3
].coef
[v
] = int_div (6 * pb
->geqs
[e1
].coef
[v
] + g
/ 2,
2305 pb
->geqs
[e3
].color
= omega_black
;
2306 pb
->geqs
[e3
].touched
= 1;
2308 pb
->geqs
[e3
].coef
[0] = 9997;
2310 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2312 fprintf (dump_file
, "Checking to see if we can derive: ");
2313 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2314 fprintf (dump_file
, "\n from: ");
2315 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e1
]);
2316 fprintf (dump_file
, "\n");
2319 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
2320 if (e1
!= e2
&& pb
->geqs
[e2
].color
== omega_black
)
2322 for (p
= pb
->num_vars
; p
> 1; p
--)
2324 for (q
= p
- 1; q
> 0; q
--)
2327 (pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
] -
2328 pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]);
2337 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2338 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2339 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2340 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2343 if (alpha1
* alpha2
<= 0)
2355 /* Try to prove e3 is redundant: verify
2356 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2357 for (k
= pb
->num_vars
; k
>= 1; k
--)
2358 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2359 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2360 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2363 c
= alpha1
* pb
->geqs
[e1
].coef
[0]
2364 + alpha2
* pb
->geqs
[e2
].coef
[0];
2366 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2367 pb
->geqs
[e3
].coef
[0] = int_div (c
, alpha3
);
2372 if (pb
->geqs
[e3
].coef
[0] < 9997)
2377 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2380 "Smoothing weird equations; adding:\n");
2381 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2382 fprintf (dump_file
, "\nto:\n");
2383 omega_print_problem (dump_file
, pb
);
2384 fprintf (dump_file
, "\n\n");
2392 /* Replace tuples of inequalities, that define upper and lower half
2393 spaces, with an equation. */
2396 coalesce (omega_pb pb
)
2401 int found_something
= 0;
2403 for (e
= 0; e
< pb
->num_geqs
; e
++)
2404 if (pb
->geqs
[e
].color
== omega_red
)
2410 is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2412 for (e
= 0; e
< pb
->num_geqs
; e
++)
2415 for (e
= 0; e
< pb
->num_geqs
; e
++)
2416 if (pb
->geqs
[e
].color
== omega_red
2417 && !pb
->geqs
[e
].touched
)
2418 for (e2
= e
+ 1; e2
< pb
->num_geqs
; e2
++)
2419 if (!pb
->geqs
[e2
].touched
2420 && pb
->geqs
[e
].key
== -pb
->geqs
[e2
].key
2421 && pb
->geqs
[e
].coef
[0] == -pb
->geqs
[e2
].coef
[0]
2422 && pb
->geqs
[e2
].color
== omega_red
)
2424 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++], &pb
->geqs
[e
],
2426 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2432 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2434 omega_delete_geq (pb
, e
, pb
->num_vars
);
2436 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && found_something
)
2438 fprintf (dump_file
, "Coalesced pb->geqs into %d EQ's:\n",
2440 omega_print_problem (dump_file
, pb
);
2446 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2447 true, continue to eliminate all the red inequalities. */
2450 omega_eliminate_red (omega_pb pb
, bool eliminate_all
)
2452 int e
, e2
, e3
, i
, j
, k
, a
, alpha1
, alpha2
;
2454 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2457 omega_pb tmp_problem
;
2459 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2461 fprintf (dump_file
, "in eliminate RED:\n");
2462 omega_print_problem (dump_file
, pb
);
2465 if (pb
->num_eqs
> 0)
2466 omega_simplify_problem (pb
);
2468 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2471 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2472 if (pb
->geqs
[e
].color
== omega_black
&& !is_dead
[e
])
2473 for (e2
= e
- 1; e2
>= 0; e2
--)
2474 if (pb
->geqs
[e2
].color
== omega_black
2479 for (i
= pb
->num_vars
; i
> 1; i
--)
2480 for (j
= i
- 1; j
> 0; j
--)
2481 if ((a
= (pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e2
].coef
[j
]
2482 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e
].coef
[j
])) != 0)
2488 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2491 "found two equations to combine, i = %s, ",
2492 omega_variable_to_str (pb
, i
));
2493 fprintf (dump_file
, "j = %s, alpha = %d\n",
2494 omega_variable_to_str (pb
, j
), a
);
2495 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2496 fprintf (dump_file
, "\n");
2497 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2498 fprintf (dump_file
, "\n");
2501 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2502 if (pb
->geqs
[e3
].color
== omega_red
)
2504 alpha1
= (pb
->geqs
[e2
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2505 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2506 alpha2
= -(pb
->geqs
[e
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2507 - pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2509 if ((a
> 0 && alpha1
> 0 && alpha2
> 0)
2510 || (a
< 0 && alpha1
< 0 && alpha2
< 0))
2512 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2515 "alpha1 = %d, alpha2 = %d;"
2516 "comparing against: ",
2518 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2519 fprintf (dump_file
, "\n");
2522 for (k
= pb
->num_vars
; k
>= 0; k
--)
2524 c
= (alpha1
* pb
->geqs
[e
].coef
[k
]
2525 + alpha2
* pb
->geqs
[e2
].coef
[k
]);
2527 if (c
!= a
* pb
->geqs
[e3
].coef
[k
])
2530 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && k
> 0)
2531 fprintf (dump_file
, " %s: %d, %d\n",
2532 omega_variable_to_str (pb
, k
), c
,
2533 a
* pb
->geqs
[e3
].coef
[k
]);
2538 ((a
> 0 && c
< a
* pb
->geqs
[e3
].coef
[k
])
2539 || (a
< 0 && c
> a
* pb
->geqs
[e3
].coef
[k
]))))
2541 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2545 "red equation#%d is dead "
2546 "(%d dead so far, %d remain)\n",
2548 pb
->num_geqs
- dead_count
);
2549 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2550 fprintf (dump_file
, "\n");
2551 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2552 fprintf (dump_file
, "\n");
2553 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2554 fprintf (dump_file
, "\n");
2562 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2564 omega_delete_geq (pb
, e
, pb
->num_vars
);
2568 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2570 fprintf (dump_file
, "in eliminate RED, easy tests done:\n");
2571 omega_print_problem (dump_file
, pb
);
2574 for (red_found
= 0, e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2575 if (pb
->geqs
[e
].color
== omega_red
)
2583 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2584 fprintf (dump_file
, "fast checks worked\n");
2586 if (!omega_reduce_with_subs
)
2587 gcc_assert (please_no_equalities_in_simplified_problems
2588 || pb
->num_subs
== 0);
2593 if (!omega_verify_simplification
2594 && verify_omega_pb (pb
) == omega_false
)
2598 tmp_problem
= XNEW (struct omega_pb_d
);
2600 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2601 if (pb
->geqs
[e
].color
== omega_red
)
2603 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2606 "checking equation %d to see if it is redundant: ", e
);
2607 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2608 fprintf (dump_file
, "\n");
2611 omega_copy_problem (tmp_problem
, pb
);
2612 omega_negate_geq (tmp_problem
, e
);
2613 tmp_problem
->safe_vars
= 0;
2614 tmp_problem
->variables_freed
= false;
2615 tmp_problem
->num_subs
= 0;
2617 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2619 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2620 fprintf (dump_file
, "it is redundant\n");
2621 omega_delete_geq (pb
, e
, pb
->num_vars
);
2625 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2626 fprintf (dump_file
, "it is not redundant\n");
2630 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2631 fprintf (dump_file
, "no need to check other red equations\n");
2639 /* omega_simplify_problem (pb); */
2641 if (!omega_reduce_with_subs
)
2642 gcc_assert (please_no_equalities_in_simplified_problems
2643 || pb
->num_subs
== 0);
2646 /* Transform some wildcard variables to non-safe variables. */
2649 chain_unprotect (omega_pb pb
)
2652 bool *unprotect
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2654 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2656 unprotect
[i
] = omega_wildcard_p (pb
, i
);
2658 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2659 if (pb
->subs
[e
].coef
[i
])
2660 unprotect
[i
] = false;
2663 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2665 fprintf (dump_file
, "Doing chain reaction unprotection\n");
2666 omega_print_problem (dump_file
, pb
);
2668 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2670 fprintf (dump_file
, "unprotecting %s\n",
2671 omega_variable_to_str (pb
, i
));
2674 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2676 omega_unprotect_1 (pb
, &i
, unprotect
);
2678 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2680 fprintf (dump_file
, "After chain reactions\n");
2681 omega_print_problem (dump_file
, pb
);
2687 /* Reduce problem PB. */
2690 omega_problem_reduced (omega_pb pb
)
2692 if (omega_verify_simplification
2693 && !in_approximate_mode
2694 && verify_omega_pb (pb
) == omega_false
)
2697 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS
)
2698 && !omega_eliminate_redundant (pb
, true))
2701 omega_found_reduction
= omega_true
;
2703 if (!please_no_equalities_in_simplified_problems
)
2706 if (omega_reduce_with_subs
2707 || please_no_equalities_in_simplified_problems
)
2708 chain_unprotect (pb
);
2710 resurrect_subs (pb
);
2712 if (!return_single_result
)
2716 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2717 pb
->forwarding_address
[pb
->var
[i
]] = i
;
2719 for (i
= 0; i
< pb
->num_subs
; i
++)
2720 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
2722 (*omega_when_reduced
) (pb
);
2725 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2727 fprintf (dump_file
, "-------------------------------------------\n");
2728 fprintf (dump_file
, "problem reduced:\n");
2729 omega_print_problem (dump_file
, pb
);
2730 fprintf (dump_file
, "-------------------------------------------\n");
2734 /* Eliminates all the free variables for problem PB, that is all the
2735 variables from FV to PB->NUM_VARS. */
2738 omega_free_eliminations (omega_pb pb
, int fv
)
2740 bool try_again
= true;
2742 int n_vars
= pb
->num_vars
;
2748 for (i
= n_vars
; i
> fv
; i
--)
2750 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2751 if (pb
->geqs
[e
].coef
[i
])
2756 else if (pb
->geqs
[e
].coef
[i
] > 0)
2758 for (e2
= e
- 1; e2
>= 0; e2
--)
2759 if (pb
->geqs
[e2
].coef
[i
] < 0)
2764 for (e2
= e
- 1; e2
>= 0; e2
--)
2765 if (pb
->geqs
[e2
].coef
[i
] > 0)
2772 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2773 if (pb
->subs
[e3
].coef
[i
])
2779 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2780 if (pb
->eqs
[e3
].coef
[i
])
2786 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2787 fprintf (dump_file
, "a free elimination of %s\n",
2788 omega_variable_to_str (pb
, i
));
2792 omega_delete_geq (pb
, e
, n_vars
);
2794 for (e
--; e
>= 0; e
--)
2795 if (pb
->geqs
[e
].coef
[i
])
2796 omega_delete_geq (pb
, e
, n_vars
);
2798 try_again
= (i
< n_vars
);
2801 omega_delete_variable (pb
, i
);
2802 n_vars
= pb
->num_vars
;
2807 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2809 fprintf (dump_file
, "\nafter free eliminations:\n");
2810 omega_print_problem (dump_file
, pb
);
2811 fprintf (dump_file
, "\n");
2815 /* Do free red eliminations. */
2818 free_red_eliminations (omega_pb pb
)
2820 bool try_again
= true;
2822 int n_vars
= pb
->num_vars
;
2823 bool *is_red_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2824 bool *is_dead_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2825 bool *is_dead_geq
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2827 for (i
= n_vars
; i
> 0; i
--)
2829 is_red_var
[i
] = false;
2830 is_dead_var
[i
] = false;
2833 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2835 is_dead_geq
[e
] = false;
2837 if (pb
->geqs
[e
].color
== omega_red
)
2838 for (i
= n_vars
; i
> 0; i
--)
2839 if (pb
->geqs
[e
].coef
[i
] != 0)
2840 is_red_var
[i
] = true;
2846 for (i
= n_vars
; i
> 0; i
--)
2847 if (!is_red_var
[i
] && !is_dead_var
[i
])
2849 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2850 if (!is_dead_geq
[e
] && pb
->geqs
[e
].coef
[i
])
2855 else if (pb
->geqs
[e
].coef
[i
] > 0)
2857 for (e2
= e
- 1; e2
>= 0; e2
--)
2858 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] < 0)
2863 for (e2
= e
- 1; e2
>= 0; e2
--)
2864 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] > 0)
2871 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2872 if (pb
->subs
[e3
].coef
[i
])
2878 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2879 if (pb
->eqs
[e3
].coef
[i
])
2885 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2886 fprintf (dump_file
, "a free red elimination of %s\n",
2887 omega_variable_to_str (pb
, i
));
2890 if (pb
->geqs
[e
].coef
[i
])
2891 is_dead_geq
[e
] = true;
2894 is_dead_var
[i
] = true;
2899 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2901 omega_delete_geq (pb
, e
, n_vars
);
2903 for (i
= n_vars
; i
> 0; i
--)
2905 omega_delete_variable (pb
, i
);
2907 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2909 fprintf (dump_file
, "\nafter free red eliminations:\n");
2910 omega_print_problem (dump_file
, pb
);
2911 fprintf (dump_file
, "\n");
2919 /* For equation EQ of the form "0 = EQN", insert in PB two
2920 inequalities "0 <= EQN" and "0 <= -EQN". */
2923 omega_convert_eq_to_geqs (omega_pb pb
, int eq
)
2927 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2928 fprintf (dump_file
, "Converting Eq to Geqs\n");
2930 /* Insert "0 <= EQN". */
2931 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2932 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2935 /* Insert "0 <= -EQN". */
2936 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2937 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2939 for (i
= 0; i
<= pb
->num_vars
; i
++)
2940 pb
->geqs
[pb
->num_geqs
].coef
[i
] *= -1;
2944 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2945 omega_print_problem (dump_file
, pb
);
2948 /* Eliminates variable I from PB. */
2951 omega_do_elimination (omega_pb pb
, int e
, int i
)
2953 eqn sub
= omega_alloc_eqns (0, 1);
2955 int n_vars
= pb
->num_vars
;
2957 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2958 fprintf (dump_file
, "eliminating variable %s\n",
2959 omega_variable_to_str (pb
, i
));
2961 omega_copy_eqn (sub
, &pb
->eqs
[e
], pb
->num_vars
);
2964 if (c
== 1 || c
== -1)
2966 if (pb
->eqs
[e
].color
== omega_red
)
2969 omega_substitute_red (pb
, sub
, i
, c
, &fB
);
2971 omega_convert_eq_to_geqs (pb
, e
);
2973 omega_delete_variable (pb
, i
);
2977 omega_substitute (pb
, sub
, i
, c
);
2978 omega_delete_variable (pb
, i
);
2986 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2987 fprintf (dump_file
, "performing non-exact elimination, c = %d\n", c
);
2989 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
2990 if (pb
->eqs
[e
].coef
[i
])
2992 eqn eqn
= &(pb
->eqs
[e
]);
2994 for (j
= n_vars
; j
>= 0; j
--)
2998 if (sub
->color
== omega_red
)
2999 eqn
->color
= omega_red
;
3000 for (j
= n_vars
; j
>= 0; j
--)
3001 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3004 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3005 if (pb
->geqs
[e
].coef
[i
])
3007 eqn eqn
= &(pb
->geqs
[e
]);
3010 if (sub
->color
== omega_red
)
3011 eqn
->color
= omega_red
;
3013 for (j
= n_vars
; j
>= 0; j
--)
3020 for (j
= n_vars
; j
>= 0; j
--)
3021 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3025 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3026 if (pb
->subs
[e
].coef
[i
])
3028 eqn eqn
= &(pb
->subs
[e
]);
3031 gcc_assert (sub
->color
== omega_black
);
3032 for (j
= n_vars
; j
>= 0; j
--)
3036 for (j
= n_vars
; j
>= 0; j
--)
3037 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3040 if (in_approximate_mode
)
3041 omega_delete_variable (pb
, i
);
3043 omega_convert_eq_to_geqs (pb
, e2
);
3046 omega_free_eqns (sub
, 1);
3049 /* Helper function for printing "sorry, no solution". */
3051 static inline enum omega_result
3052 omega_problem_has_no_solution (void)
3054 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3055 fprintf (dump_file
, "\nequations have no solution \n");
3060 /* Helper function: solve equations in PB one at a time, following the
3061 DESIRED_RES result. */
3063 static enum omega_result
3064 omega_solve_eq (omega_pb pb
, enum omega_result desired_res
)
3071 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && pb
->num_eqs
> 0)
3073 fprintf (dump_file
, "\nomega_solve_eq (%d, %d)\n",
3074 desired_res
, may_be_red
);
3075 omega_print_problem (dump_file
, pb
);
3076 fprintf (dump_file
, "\n");
3082 j
= pb
->num_eqs
- 1;
3088 while (i
<= j
&& pb
->eqs
[i
].color
== omega_red
)
3091 while (i
<= j
&& pb
->eqs
[j
].color
== omega_black
)
3097 eq
= omega_alloc_eqns (0, 1);
3098 omega_copy_eqn (eq
, &pb
->eqs
[i
], pb
->num_vars
);
3099 omega_copy_eqn (&pb
->eqs
[i
], &pb
->eqs
[j
], pb
->num_vars
);
3100 omega_copy_eqn (&pb
->eqs
[j
], eq
, pb
->num_vars
);
3101 omega_free_eqns (eq
, 1);
3107 /* Eliminate all EQ equations */
3108 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
3110 eqn eqn
= &(pb
->eqs
[e
]);
3113 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3114 fprintf (dump_file
, "----\n");
3116 for (i
= pb
->num_vars
; i
> 0; i
--)
3122 for (j
= i
- 1; j
> 0; j
--)
3126 /* i is the position of last nonzero coefficient,
3127 g is the coefficient of i,
3128 j is the position of next nonzero coefficient. */
3132 if (eqn
->coef
[0] % g
!= 0)
3133 return omega_problem_has_no_solution ();
3135 eqn
->coef
[0] = eqn
->coef
[0] / g
;
3138 omega_do_elimination (pb
, e
, i
);
3144 if (eqn
->coef
[0] != 0)
3145 return omega_problem_has_no_solution ();
3157 omega_do_elimination (pb
, e
, i
);
3163 bool promotion_possible
=
3164 (omega_safe_var_p (pb
, j
)
3165 && pb
->safe_vars
+ 1 == i
3166 && !omega_eqn_is_red (eqn
, desired_res
)
3167 && !in_approximate_mode
);
3169 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && promotion_possible
)
3170 fprintf (dump_file
, " Promotion possible\n");
3173 if (!omega_safe_var_p (pb
, j
))
3175 for (; g
!= 1 && !omega_safe_var_p (pb
, j
); j
--)
3176 g
= gcd (abs (eqn
->coef
[j
]), g
);
3179 else if (!omega_safe_var_p (pb
, i
))
3184 for (; g
!= 1 && j
> 0; j
--)
3185 g
= gcd (abs (eqn
->coef
[j
]), g
);
3189 if (eqn
->coef
[0] % g
!= 0)
3190 return omega_problem_has_no_solution ();
3192 for (j
= 0; j
<= pb
->num_vars
; j
++)
3202 for (e2
= e
- 1; e2
>= 0; e2
--)
3203 if (pb
->eqs
[e2
].coef
[i
])
3207 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
3208 if (pb
->geqs
[e2
].coef
[i
])
3212 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
3213 if (pb
->subs
[e2
].coef
[i
])
3218 bool change
= false;
3220 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3222 fprintf (dump_file
, "Ha! We own it! \n");
3223 omega_print_eq (dump_file
, pb
, eqn
);
3224 fprintf (dump_file
, " \n");
3230 for (j
= i
- 1; j
>= 0; j
--)
3232 int t
= int_mod (eqn
->coef
[j
], g
);
3237 if (t
!= eqn
->coef
[j
])
3246 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3247 fprintf (dump_file
, "So what?\n");
3252 omega_name_wild_card (pb
, i
);
3254 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3256 omega_print_eq (dump_file
, pb
, eqn
);
3257 fprintf (dump_file
, " \n");
3266 if (promotion_possible
)
3268 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3270 fprintf (dump_file
, "promoting %s to safety\n",
3271 omega_variable_to_str (pb
, i
));
3272 omega_print_vars (dump_file
, pb
);
3277 if (!omega_wildcard_p (pb
, i
))
3278 omega_name_wild_card (pb
, i
);
3280 promotion_possible
= false;
3285 if (g2
> 1 && !in_approximate_mode
)
3287 if (pb
->eqs
[e
].color
== omega_red
)
3289 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3290 fprintf (dump_file
, "handling red equality\n");
3293 omega_do_elimination (pb
, e
, i
);
3297 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3300 "adding equation to handle safe variable \n");
3301 omega_print_eq (dump_file
, pb
, eqn
);
3302 fprintf (dump_file
, "\n----\n");
3303 omega_print_problem (dump_file
, pb
);
3304 fprintf (dump_file
, "\n----\n");
3305 fprintf (dump_file
, "\n----\n");
3308 i
= omega_add_new_wild_card (pb
);
3310 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
3311 omega_init_eqn_zero (&pb
->eqs
[e
+ 1], pb
->num_vars
);
3312 omega_copy_eqn (&pb
->eqs
[e
+ 1], eqn
, pb
->safe_vars
);
3314 for (j
= pb
->num_vars
; j
>= 0; j
--)
3316 pb
->eqs
[e
+ 1].coef
[j
] = int_mod (pb
->eqs
[e
+ 1].coef
[j
], g2
);
3318 if (2 * pb
->eqs
[e
+ 1].coef
[j
] >= g2
)
3319 pb
->eqs
[e
+ 1].coef
[j
] -= g2
;
3322 pb
->eqs
[e
+ 1].coef
[i
] = g2
;
3325 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3326 omega_print_problem (dump_file
, pb
);
3335 /* Find variable to eliminate. */
3338 gcc_assert (in_approximate_mode
);
3340 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3342 fprintf (dump_file
, "non-exact elimination: ");
3343 omega_print_eq (dump_file
, pb
, eqn
);
3344 fprintf (dump_file
, "\n");
3345 omega_print_problem (dump_file
, pb
);
3348 for (i
= pb
->num_vars
; i
> sv
; i
--)
3349 if (pb
->eqs
[e
].coef
[i
] != 0)
3353 for (i
= pb
->num_vars
; i
> sv
; i
--)
3354 if (pb
->eqs
[e
].coef
[i
] == 1 || pb
->eqs
[e
].coef
[i
] == -1)
3360 omega_do_elimination (pb
, e
, i
);
3362 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && g2
> 1)
3364 fprintf (dump_file
, "result of non-exact elimination:\n");
3365 omega_print_problem (dump_file
, pb
);
3370 int factor
= (INT_MAX
);
3373 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3374 fprintf (dump_file
, "doing moding\n");
3376 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3377 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3382 for (; i
!= sv
; i
--)
3383 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3389 if (j
!= 0 && i
== sv
)
3391 omega_do_mod (pb
, 2, e
, j
);
3397 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3398 if (pb
->eqs
[e
].coef
[i
] != 0
3399 && factor
> abs (pb
->eqs
[e
].coef
[i
]) + 1)
3401 factor
= abs (pb
->eqs
[e
].coef
[i
]) + 1;
3407 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3408 fprintf (dump_file
, "should not have happened\n");
3412 omega_do_mod (pb
, factor
, e
, j
);
3413 /* Go back and try this equation again. */
3420 return omega_unknown
;
3423 /* Transform an inequation E to an equality, then solve DIFF problems
3424 based on PB, and only differing by the constant part that is
3425 diminished by one, trying to figure out which of the constants
3428 static enum omega_result
3429 parallel_splinter (omega_pb pb
, int e
, int diff
,
3430 enum omega_result desired_res
)
3432 omega_pb tmp_problem
;
3435 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3437 fprintf (dump_file
, "Using parallel splintering\n");
3438 omega_print_problem (dump_file
, pb
);
3441 tmp_problem
= XNEW (struct omega_pb_d
);
3442 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
], pb
->num_vars
);
3445 for (i
= 0; i
<= diff
; i
++)
3447 omega_copy_problem (tmp_problem
, pb
);
3449 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3451 fprintf (dump_file
, "Splinter # %i\n", i
);
3452 omega_print_problem (dump_file
, pb
);
3455 if (omega_solve_problem (tmp_problem
, desired_res
) == omega_true
)
3461 pb
->eqs
[0].coef
[0]--;
3468 /* Helper function: solve equations one at a time. */
3470 static enum omega_result
3471 omega_solve_geq (omega_pb pb
, enum omega_result desired_res
)
3475 enum omega_result result
;
3476 bool coupled_subscripts
= false;
3477 bool smoothed
= false;
3478 bool eliminate_again
;
3479 bool tried_eliminating_redundant
= false;
3481 if (desired_res
!= omega_simplify
)
3489 gcc_assert (desired_res
== omega_simplify
|| pb
->num_subs
== 0);
3491 /* Verify that there are not too many inequalities. */
3492 gcc_assert (pb
->num_geqs
<= OMEGA_MAX_GEQS
);
3494 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3496 fprintf (dump_file
, "\nomega_solve_geq (%d,%d):\n",
3497 desired_res
, please_no_equalities_in_simplified_problems
);
3498 omega_print_problem (dump_file
, pb
);
3499 fprintf (dump_file
, "\n");
3502 n_vars
= pb
->num_vars
;
3506 enum omega_eqn_color u_color
= omega_black
;
3507 enum omega_eqn_color l_color
= omega_black
;
3508 int upper_bound
= pos_infinity
;
3509 int lower_bound
= neg_infinity
;
3511 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3513 int a
= pb
->geqs
[e
].coef
[1];
3514 int c
= pb
->geqs
[e
].coef
[0];
3516 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3520 return omega_problem_has_no_solution ();
3527 if (lower_bound
< -c
3528 || (lower_bound
== -c
3529 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3532 l_color
= pb
->geqs
[e
].color
;
3538 c
= int_div (c
, -a
);
3541 || (upper_bound
== c
3542 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3545 u_color
= pb
->geqs
[e
].color
;
3550 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3552 fprintf (dump_file
, "upper bound = %d\n", upper_bound
);
3553 fprintf (dump_file
, "lower bound = %d\n", lower_bound
);
3556 if (lower_bound
> upper_bound
)
3557 return omega_problem_has_no_solution ();
3559 if (desired_res
== omega_simplify
)
3562 if (pb
->safe_vars
== 1)
3565 if (lower_bound
== upper_bound
3566 && u_color
== omega_black
3567 && l_color
== omega_black
)
3569 pb
->eqs
[0].coef
[0] = -lower_bound
;
3570 pb
->eqs
[0].coef
[1] = 1;
3571 pb
->eqs
[0].color
= omega_black
;
3573 return omega_solve_problem (pb
, desired_res
);
3577 if (lower_bound
> neg_infinity
)
3579 pb
->geqs
[0].coef
[0] = -lower_bound
;
3580 pb
->geqs
[0].coef
[1] = 1;
3581 pb
->geqs
[0].key
= 1;
3582 pb
->geqs
[0].color
= l_color
;
3583 pb
->geqs
[0].touched
= 0;
3587 if (upper_bound
< pos_infinity
)
3589 pb
->geqs
[pb
->num_geqs
].coef
[0] = upper_bound
;
3590 pb
->geqs
[pb
->num_geqs
].coef
[1] = -1;
3591 pb
->geqs
[pb
->num_geqs
].key
= -1;
3592 pb
->geqs
[pb
->num_geqs
].color
= u_color
;
3593 pb
->geqs
[pb
->num_geqs
].touched
= 0;
3601 omega_problem_reduced (pb
);
3605 if (original_problem
!= no_problem
3606 && l_color
== omega_black
3607 && u_color
== omega_black
3609 && lower_bound
== upper_bound
)
3611 pb
->eqs
[0].coef
[0] = -lower_bound
;
3612 pb
->eqs
[0].coef
[1] = 1;
3614 adding_equality_constraint (pb
, 0);
3620 if (!pb
->variables_freed
)
3622 pb
->variables_freed
= true;
3624 if (desired_res
!= omega_simplify
)
3625 omega_free_eliminations (pb
, 0);
3627 omega_free_eliminations (pb
, pb
->safe_vars
);
3629 n_vars
= pb
->num_vars
;
3635 switch (normalize_omega_problem (pb
))
3637 case normalize_false
:
3641 case normalize_coupled
:
3642 coupled_subscripts
= true;
3645 case normalize_uncoupled
:
3646 coupled_subscripts
= false;
3653 n_vars
= pb
->num_vars
;
3655 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3657 fprintf (dump_file
, "\nafter normalization:\n");
3658 omega_print_problem (dump_file
, pb
);
3659 fprintf (dump_file
, "\n");
3660 fprintf (dump_file
, "eliminating variable using Fourier-Motzkin.\n");
3664 int parallel_difference
= INT_MAX
;
3665 int best_parallel_eqn
= -1;
3666 int minC
, maxC
, minCj
= 0;
3667 int lower_bound_count
= 0;
3669 bool possible_easy_int_solution
;
3670 int max_splinters
= 1;
3672 bool lucky_exact
= false;
3673 int best
= (INT_MAX
);
3674 int j
= 0, jLe
= 0, jLowerBoundCount
= 0;
3677 eliminate_again
= false;
3679 if (pb
->num_eqs
> 0)
3680 return omega_solve_problem (pb
, desired_res
);
3682 if (!coupled_subscripts
)
3684 if (pb
->safe_vars
== 0)
3687 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3688 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
3689 omega_delete_geq (pb
, e
, n_vars
);
3691 pb
->num_vars
= pb
->safe_vars
;
3693 if (desired_res
== omega_simplify
)
3695 omega_problem_reduced (pb
);
3702 if (desired_res
!= omega_simplify
)
3707 if (pb
->num_geqs
== 0)
3709 if (desired_res
== omega_simplify
)
3711 pb
->num_vars
= pb
->safe_vars
;
3712 omega_problem_reduced (pb
);
3718 if (desired_res
== omega_simplify
&& n_vars
== pb
->safe_vars
)
3720 omega_problem_reduced (pb
);
3724 if (pb
->num_geqs
> OMEGA_MAX_GEQS
- 30
3725 || pb
->num_geqs
> 2 * n_vars
* n_vars
+ 4 * n_vars
+ 10)
3727 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3729 "TOO MANY EQUATIONS; "
3730 "%d equations, %d variables, "
3731 "ELIMINATING REDUNDANT ONES\n",
3732 pb
->num_geqs
, n_vars
);
3734 if (!omega_eliminate_redundant (pb
, false))
3737 n_vars
= pb
->num_vars
;
3739 if (pb
->num_eqs
> 0)
3740 return omega_solve_problem (pb
, desired_res
);
3742 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3743 fprintf (dump_file
, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3746 if (desired_res
!= omega_simplify
)
3751 for (i
= n_vars
; i
!= fv
; i
--)
3757 int upper_bound_count
= 0;
3759 lower_bound_count
= 0;
3762 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3763 if (pb
->geqs
[e
].coef
[i
] < 0)
3765 minC
= MIN (minC
, pb
->geqs
[e
].coef
[i
]);
3766 upper_bound_count
++;
3767 if (pb
->geqs
[e
].coef
[i
] < -1)
3775 else if (pb
->geqs
[e
].coef
[i
] > 0)
3777 maxC
= MAX (maxC
, pb
->geqs
[e
].coef
[i
]);
3778 lower_bound_count
++;
3780 if (pb
->geqs
[e
].coef
[i
] > 1)
3789 if (lower_bound_count
== 0
3790 || upper_bound_count
== 0)
3792 lower_bound_count
= 0;
3796 if (ub
>= 0 && lb
>= 0
3797 && pb
->geqs
[lb
].key
== -pb
->geqs
[ub
].key
)
3799 int Lc
= pb
->geqs
[lb
].coef
[i
];
3800 int Uc
= -pb
->geqs
[ub
].coef
[i
];
3802 Lc
* pb
->geqs
[ub
].coef
[0] + Uc
* pb
->geqs
[lb
].coef
[0];
3803 lucky
= (diff
>= (Uc
- 1) * (Lc
- 1));
3809 || in_approximate_mode
)
3811 score
= upper_bound_count
* lower_bound_count
;
3813 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3815 "For %s, exact, score = %d*%d, range = %d ... %d,"
3816 "\nlucky = %d, in_approximate_mode=%d \n",
3817 omega_variable_to_str (pb
, i
),
3819 lower_bound_count
, minC
, maxC
, lucky
,
3820 in_approximate_mode
);
3830 jLowerBoundCount
= lower_bound_count
;
3832 lucky_exact
= lucky
;
3839 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3841 "For %s, non-exact, score = %d*%d,"
3842 "range = %d ... %d \n",
3843 omega_variable_to_str (pb
, i
),
3845 lower_bound_count
, minC
, maxC
);
3847 score
= maxC
- minC
;
3855 jLowerBoundCount
= lower_bound_count
;
3860 if (lower_bound_count
== 0)
3862 omega_free_eliminations (pb
, pb
->safe_vars
);
3863 n_vars
= pb
->num_vars
;
3864 eliminate_again
= true;
3871 lower_bound_count
= jLowerBoundCount
;
3873 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3874 if (pb
->geqs
[e
].coef
[i
] > 0)
3876 if (pb
->geqs
[e
].coef
[i
] == -minC
)
3877 max_splinters
+= -minC
- 1;
3880 pos_mul_hwi ((pb
->geqs
[e
].coef
[i
] - 1),
3881 (-minC
- 1)) / (-minC
) + 1;
3885 /* Trying to produce exact elimination by finding redundant
3887 if (!exact
&& !tried_eliminating_redundant
)
3889 omega_eliminate_redundant (pb
, false);
3890 tried_eliminating_redundant
= true;
3891 eliminate_again
= true;
3894 tried_eliminating_redundant
= false;
3897 if (return_single_result
&& desired_res
== omega_simplify
&& !exact
)
3899 omega_problem_reduced (pb
);
3903 /* #ifndef Omega3 */
3904 /* Trying to produce exact elimination by finding redundant
3906 if (!exact
&& !tried_eliminating_redundant
)
3908 omega_eliminate_redundant (pb
, false);
3909 tried_eliminating_redundant
= true;
3912 tried_eliminating_redundant
= false;
3919 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
3920 if (pb
->geqs
[e1
].color
== omega_black
)
3921 for (e2
= e1
- 1; e2
>= 0; e2
--)
3922 if (pb
->geqs
[e2
].color
== omega_black
3923 && pb
->geqs
[e1
].key
== -pb
->geqs
[e2
].key
3924 && ((pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3925 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3926 / 2 < parallel_difference
))
3928 parallel_difference
=
3929 (pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3930 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3932 best_parallel_eqn
= e1
;
3935 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
3936 && best_parallel_eqn
>= 0)
3939 "Possible parallel projection, diff = %d, in ",
3940 parallel_difference
);
3941 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[best_parallel_eqn
]));
3942 fprintf (dump_file
, "\n");
3943 omega_print_problem (dump_file
, pb
);
3947 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3949 fprintf (dump_file
, "going to eliminate %s, (%d,%d,%d)\n",
3950 omega_variable_to_str (pb
, i
), i
, minC
,
3952 omega_print_problem (dump_file
, pb
);
3955 fprintf (dump_file
, "(a lucky exact elimination)\n");
3958 fprintf (dump_file
, "(an exact elimination)\n");
3960 fprintf (dump_file
, "Max # of splinters = %d\n", max_splinters
);
3963 gcc_assert (max_splinters
>= 1);
3965 if (!exact
&& desired_res
== omega_simplify
&& best_parallel_eqn
>= 0
3966 && parallel_difference
<= max_splinters
)
3967 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 std::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 std::swap (pb
->geqs
[e
].coef
[i
], pb
->geqs
[e
].coef
[j
]);
3991 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3992 if (pb
->subs
[e
].coef
[i
] != pb
->subs
[e
].coef
[j
])
3993 std::swap (pb
->subs
[e
].coef
[i
], pb
->subs
[e
].coef
[j
]);
3995 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3997 fprintf (dump_file
, "Swapping complete \n");
3998 omega_print_problem (dump_file
, pb
);
3999 fprintf (dump_file
, "\n");
4005 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4007 fprintf (dump_file
, "No swap needed\n");
4008 omega_print_problem (dump_file
, pb
);
4012 n_vars
= pb
->num_vars
;
4018 int upper_bound
= pos_infinity
;
4019 int lower_bound
= neg_infinity
;
4020 enum omega_eqn_color ub_color
= omega_black
;
4021 enum omega_eqn_color lb_color
= omega_black
;
4022 int topeqn
= pb
->num_geqs
- 1;
4023 int Lc
= pb
->geqs
[Le
].coef
[i
];
4025 for (Le
= topeqn
; Le
>= 0; Le
--)
4026 if ((Lc
= pb
->geqs
[Le
].coef
[i
]) == 0)
4028 if (pb
->geqs
[Le
].coef
[1] == 1)
4030 int constantTerm
= -pb
->geqs
[Le
].coef
[0];
4032 if (constantTerm
> lower_bound
||
4033 (constantTerm
== lower_bound
&&
4034 !omega_eqn_is_red (&pb
->geqs
[Le
], desired_res
)))
4036 lower_bound
= constantTerm
;
4037 lb_color
= pb
->geqs
[Le
].color
;
4040 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4042 if (pb
->geqs
[Le
].color
== omega_black
)
4043 fprintf (dump_file
, " :::=> %s >= %d\n",
4044 omega_variable_to_str (pb
, 1),
4048 " :::=> [%s >= %d]\n",
4049 omega_variable_to_str (pb
, 1),
4055 int constantTerm
= pb
->geqs
[Le
].coef
[0];
4056 if (constantTerm
< upper_bound
||
4057 (constantTerm
== upper_bound
4058 && !omega_eqn_is_red (&pb
->geqs
[Le
],
4061 upper_bound
= constantTerm
;
4062 ub_color
= pb
->geqs
[Le
].color
;
4065 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4067 if (pb
->geqs
[Le
].color
== omega_black
)
4068 fprintf (dump_file
, " :::=> %s <= %d\n",
4069 omega_variable_to_str (pb
, 1),
4073 " :::=> [%s <= %d]\n",
4074 omega_variable_to_str (pb
, 1),
4080 for (Ue
= topeqn
; Ue
>= 0; Ue
--)
4081 if (pb
->geqs
[Ue
].coef
[i
] < 0
4082 && pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4084 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4085 int coefficient
= pb
->geqs
[Ue
].coef
[1] * Lc
4086 + pb
->geqs
[Le
].coef
[1] * Uc
;
4087 int constantTerm
= pb
->geqs
[Ue
].coef
[0] * Lc
4088 + pb
->geqs
[Le
].coef
[0] * Uc
;
4090 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4092 omega_print_geq_extra (dump_file
, pb
,
4094 fprintf (dump_file
, "\n");
4095 omega_print_geq_extra (dump_file
, pb
,
4097 fprintf (dump_file
, "\n");
4100 if (coefficient
> 0)
4102 constantTerm
= -int_div (constantTerm
, coefficient
);
4104 if (constantTerm
> lower_bound
4105 || (constantTerm
== lower_bound
4106 && (desired_res
!= omega_simplify
4107 || (pb
->geqs
[Ue
].color
== omega_black
4108 && pb
->geqs
[Le
].color
== omega_black
))))
4110 lower_bound
= constantTerm
;
4111 lb_color
= (pb
->geqs
[Ue
].color
== omega_red
4112 || pb
->geqs
[Le
].color
== omega_red
)
4113 ? omega_red
: omega_black
;
4116 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4118 if (pb
->geqs
[Ue
].color
== omega_red
4119 || pb
->geqs
[Le
].color
== omega_red
)
4121 " ::=> [%s >= %d]\n",
4122 omega_variable_to_str (pb
, 1),
4127 omega_variable_to_str (pb
, 1),
4133 constantTerm
= int_div (constantTerm
, -coefficient
);
4134 if (constantTerm
< upper_bound
4135 || (constantTerm
== upper_bound
4136 && pb
->geqs
[Ue
].color
== omega_black
4137 && pb
->geqs
[Le
].color
== omega_black
))
4139 upper_bound
= constantTerm
;
4140 ub_color
= (pb
->geqs
[Ue
].color
== omega_red
4141 || pb
->geqs
[Le
].color
== omega_red
)
4142 ? omega_red
: omega_black
;
4146 && (dump_flags
& TDF_DETAILS
))
4148 if (pb
->geqs
[Ue
].color
== omega_red
4149 || pb
->geqs
[Le
].color
== omega_red
)
4151 " ::=> [%s <= %d]\n",
4152 omega_variable_to_str (pb
, 1),
4157 omega_variable_to_str (pb
, 1),
4165 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4167 " therefore, %c%d <= %c%s%c <= %d%c\n",
4168 lb_color
== omega_red
? '[' : ' ', lower_bound
,
4169 (lb_color
== omega_red
&& ub_color
== omega_black
)
4171 omega_variable_to_str (pb
, 1),
4172 (lb_color
== omega_black
&& ub_color
== omega_red
)
4174 upper_bound
, ub_color
== omega_red
? ']' : ' ');
4176 if (lower_bound
> upper_bound
)
4179 if (pb
->safe_vars
== 1)
4181 if (upper_bound
== lower_bound
4182 && !(ub_color
== omega_red
|| lb_color
== omega_red
)
4183 && !please_no_equalities_in_simplified_problems
)
4186 pb
->eqs
[0].coef
[1] = -1;
4187 pb
->eqs
[0].coef
[0] = upper_bound
;
4189 if (ub_color
== omega_red
4190 || lb_color
== omega_red
)
4191 pb
->eqs
[0].color
= omega_red
;
4193 if (desired_res
== omega_simplify
4194 && pb
->eqs
[0].color
== omega_black
)
4195 return omega_solve_problem (pb
, desired_res
);
4198 if (upper_bound
!= pos_infinity
)
4200 pb
->geqs
[0].coef
[1] = -1;
4201 pb
->geqs
[0].coef
[0] = upper_bound
;
4202 pb
->geqs
[0].color
= ub_color
;
4203 pb
->geqs
[0].key
= -1;
4204 pb
->geqs
[0].touched
= 0;
4208 if (lower_bound
!= neg_infinity
)
4210 pb
->geqs
[pb
->num_geqs
].coef
[1] = 1;
4211 pb
->geqs
[pb
->num_geqs
].coef
[0] = -lower_bound
;
4212 pb
->geqs
[pb
->num_geqs
].color
= lb_color
;
4213 pb
->geqs
[pb
->num_geqs
].key
= 1;
4214 pb
->geqs
[pb
->num_geqs
].touched
= 0;
4219 if (desired_res
== omega_simplify
)
4221 omega_problem_reduced (pb
);
4227 && (desired_res
!= omega_simplify
4228 || (lb_color
== omega_black
4229 && ub_color
== omega_black
))
4230 && original_problem
!= no_problem
4231 && lower_bound
== upper_bound
)
4233 for (i
= original_problem
->num_vars
; i
>= 0; i
--)
4234 if (original_problem
->var
[i
] == pb
->var
[1])
4240 e
= original_problem
->num_eqs
++;
4241 omega_init_eqn_zero (&original_problem
->eqs
[e
],
4242 original_problem
->num_vars
);
4243 original_problem
->eqs
[e
].coef
[i
] = -1;
4244 original_problem
->eqs
[e
].coef
[0] = upper_bound
;
4246 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4249 "adding equality %d to outer problem\n", e
);
4250 omega_print_problem (dump_file
, original_problem
);
4257 eliminate_again
= true;
4259 if (lower_bound_count
== 1)
4261 eqn lbeqn
= omega_alloc_eqns (0, 1);
4262 int Lc
= pb
->geqs
[Le
].coef
[i
];
4264 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4265 fprintf (dump_file
, "an inplace elimination\n");
4267 omega_copy_eqn (lbeqn
, &pb
->geqs
[Le
], (n_vars
+ 1));
4268 omega_delete_geq_extra (pb
, Le
, n_vars
+ 1);
4270 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4271 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4273 if (lbeqn
->key
== -pb
->geqs
[Ue
].key
)
4274 omega_delete_geq_extra (pb
, Ue
, n_vars
+ 1);
4278 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4279 pb
->geqs
[Ue
].touched
= 1;
4280 eliminate_again
= false;
4282 if (lbeqn
->color
== omega_red
)
4283 pb
->geqs
[Ue
].color
= omega_red
;
4285 for (k
= 0; k
<= n_vars
; k
++)
4286 pb
->geqs
[Ue
].coef
[k
] =
4287 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4288 mul_hwi (lbeqn
->coef
[k
], Uc
);
4290 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4292 omega_print_geq (dump_file
, pb
,
4294 fprintf (dump_file
, "\n");
4299 omega_free_eqns (lbeqn
, 1);
4304 int *dead_eqns
= XNEWVEC (int, OMEGA_MAX_GEQS
);
4305 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
4307 int top_eqn
= pb
->num_geqs
- 1;
4308 lower_bound_count
--;
4310 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4311 fprintf (dump_file
, "lower bound count = %d\n",
4314 for (Le
= top_eqn
; Le
>= 0; Le
--)
4315 if (pb
->geqs
[Le
].coef
[i
] > 0)
4317 int Lc
= pb
->geqs
[Le
].coef
[i
];
4318 for (Ue
= top_eqn
; Ue
>= 0; Ue
--)
4319 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4321 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4324 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4327 e2
= pb
->num_geqs
++;
4329 e2
= dead_eqns
[--num_dead
];
4331 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4333 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4336 "Le = %d, Ue = %d, gen = %d\n",
4338 omega_print_geq_extra (dump_file
, pb
,
4340 fprintf (dump_file
, "\n");
4341 omega_print_geq_extra (dump_file
, pb
,
4343 fprintf (dump_file
, "\n");
4346 eliminate_again
= false;
4348 for (k
= n_vars
; k
>= 0; k
--)
4349 pb
->geqs
[e2
].coef
[k
] =
4350 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4351 mul_hwi (pb
->geqs
[Le
].coef
[k
], Uc
);
4353 pb
->geqs
[e2
].coef
[n_vars
+ 1] = 0;
4354 pb
->geqs
[e2
].touched
= 1;
4356 if (pb
->geqs
[Ue
].color
== omega_red
4357 || pb
->geqs
[Le
].color
== omega_red
)
4358 pb
->geqs
[e2
].color
= omega_red
;
4360 pb
->geqs
[e2
].color
= omega_black
;
4362 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4364 omega_print_geq (dump_file
, pb
,
4366 fprintf (dump_file
, "\n");
4370 if (lower_bound_count
== 0)
4372 dead_eqns
[num_dead
++] = Ue
;
4374 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4375 fprintf (dump_file
, "Killed %d\n", Ue
);
4379 lower_bound_count
--;
4380 dead_eqns
[num_dead
++] = Le
;
4382 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4383 fprintf (dump_file
, "Killed %d\n", Le
);
4386 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4389 while (num_dead
> 0)
4390 is_dead
[dead_eqns
[--num_dead
]] = true;
4392 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4394 omega_delete_geq_extra (pb
, e
, n_vars
+ 1);
4405 rS
= omega_alloc_problem (0, 0);
4406 iS
= omega_alloc_problem (0, 0);
4408 possible_easy_int_solution
= true;
4410 for (e
= 0; e
< pb
->num_geqs
; e
++)
4411 if (pb
->geqs
[e
].coef
[i
] == 0)
4413 omega_copy_eqn (&(rS
->geqs
[e2
]), &pb
->geqs
[e
],
4415 omega_copy_eqn (&(iS
->geqs
[e2
]), &pb
->geqs
[e
],
4418 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4421 fprintf (dump_file
, "Copying (%d, %d): ", i
,
4422 pb
->geqs
[e
].coef
[i
]);
4423 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
4424 fprintf (dump_file
, "\n");
4425 for (t
= 0; t
<= n_vars
+ 1; t
++)
4426 fprintf (dump_file
, "%d ", pb
->geqs
[e
].coef
[t
]);
4427 fprintf (dump_file
, "\n");
4431 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4434 for (Le
= pb
->num_geqs
- 1; Le
>= 0; Le
--)
4435 if (pb
->geqs
[Le
].coef
[i
] > 0)
4436 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4437 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4440 int Lc
= pb
->geqs
[Le
].coef
[i
];
4441 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4443 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4446 rS
->geqs
[e2
].touched
= iS
->geqs
[e2
].touched
= 1;
4448 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4450 fprintf (dump_file
, "---\n");
4452 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4453 Le
, Lc
, Ue
, Uc
, e2
);
4454 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Le
]);
4455 fprintf (dump_file
, "\n");
4456 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Ue
]);
4457 fprintf (dump_file
, "\n");
4462 for (k
= n_vars
; k
>= 0; k
--)
4463 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4464 pb
->geqs
[Ue
].coef
[k
] + pb
->geqs
[Le
].coef
[k
];
4466 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1);
4470 for (k
= n_vars
; k
>= 0; k
--)
4471 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4472 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4473 mul_hwi (pb
->geqs
[Le
].coef
[k
], Uc
);
4475 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1) * (Lc
- 1);
4478 if (pb
->geqs
[Ue
].color
== omega_red
4479 || pb
->geqs
[Le
].color
== omega_red
)
4480 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_red
;
4482 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_black
;
4484 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4486 omega_print_geq (dump_file
, pb
, &(rS
->geqs
[e2
]));
4487 fprintf (dump_file
, "\n");
4491 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4493 else if (pb
->geqs
[Ue
].coef
[0] * Lc
+
4494 pb
->geqs
[Le
].coef
[0] * Uc
-
4495 (Uc
- 1) * (Lc
- 1) < 0)
4496 possible_easy_int_solution
= false;
4499 iS
->variables_initialized
= rS
->variables_initialized
= true;
4500 iS
->num_vars
= rS
->num_vars
= pb
->num_vars
;
4501 iS
->num_geqs
= rS
->num_geqs
= e2
;
4502 iS
->num_eqs
= rS
->num_eqs
= 0;
4503 iS
->num_subs
= rS
->num_subs
= pb
->num_subs
;
4504 iS
->safe_vars
= rS
->safe_vars
= pb
->safe_vars
;
4506 for (e
= n_vars
; e
>= 0; e
--)
4507 rS
->var
[e
] = pb
->var
[e
];
4509 for (e
= n_vars
; e
>= 0; e
--)
4510 iS
->var
[e
] = pb
->var
[e
];
4512 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
4514 omega_copy_eqn (&(rS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4515 omega_copy_eqn (&(iS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4519 n_vars
= pb
->num_vars
;
4521 if (desired_res
!= omega_true
)
4523 if (original_problem
== no_problem
)
4525 original_problem
= pb
;
4526 result
= omega_solve_geq (rS
, omega_false
);
4527 original_problem
= no_problem
;
4530 result
= omega_solve_geq (rS
, omega_false
);
4532 if (result
== omega_false
)
4539 if (pb
->num_eqs
> 0)
4541 /* An equality constraint must have been found */
4544 return omega_solve_problem (pb
, desired_res
);
4548 if (desired_res
!= omega_false
)
4551 int lower_bounds
= 0;
4552 int *lower_bound
= XNEWVEC (int, OMEGA_MAX_GEQS
);
4554 if (possible_easy_int_solution
)
4557 result
= omega_solve_geq (iS
, desired_res
);
4560 if (result
!= omega_false
)
4569 if (!exact
&& best_parallel_eqn
>= 0
4570 && parallel_difference
<= max_splinters
)
4575 return parallel_splinter (pb
, best_parallel_eqn
,
4576 parallel_difference
,
4580 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4581 fprintf (dump_file
, "have to do exact analysis\n");
4585 for (e
= 0; e
< pb
->num_geqs
; e
++)
4586 if (pb
->geqs
[e
].coef
[i
] > 1)
4587 lower_bound
[lower_bounds
++] = e
;
4589 /* Sort array LOWER_BOUND. */
4590 for (j
= 0; j
< lower_bounds
; j
++)
4594 for (int k
= j
+ 1; k
< lower_bounds
; k
++)
4595 if (pb
->geqs
[lower_bound
[smallest
]].coef
[i
] >
4596 pb
->geqs
[lower_bound
[k
]].coef
[i
])
4599 std::swap (lower_bound
[smallest
], lower_bound
[j
]);
4602 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4604 fprintf (dump_file
, "lower bound coefficients = ");
4606 for (j
= 0; j
< lower_bounds
; j
++)
4607 fprintf (dump_file
, " %d",
4608 pb
->geqs
[lower_bound
[j
]].coef
[i
]);
4610 fprintf (dump_file
, "\n");
4613 for (j
= 0; j
< lower_bounds
; j
++)
4617 int worst_lower_bound_constant
= -minC
;
4620 max_incr
= (((pb
->geqs
[e
].coef
[i
] - 1) *
4621 (worst_lower_bound_constant
- 1) - 1)
4622 / worst_lower_bound_constant
);
4623 /* max_incr += 2; */
4625 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4627 fprintf (dump_file
, "for equation ");
4628 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
4630 "\ntry decrements from 0 to %d\n",
4632 omega_print_problem (dump_file
, pb
);
4635 if (max_incr
> 50 && !smoothed
4636 && smooth_weird_equations (pb
))
4642 goto solve_geq_start
;
4645 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
],
4647 pb
->eqs
[0].color
= omega_black
;
4648 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
4649 pb
->geqs
[e
].touched
= 1;
4652 for (c
= max_incr
; c
>= 0; c
--)
4654 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4657 "trying next decrement of %d\n",
4659 omega_print_problem (dump_file
, pb
);
4662 omega_copy_problem (rS
, pb
);
4664 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4665 omega_print_problem (dump_file
, rS
);
4667 result
= omega_solve_problem (rS
, desired_res
);
4669 if (result
== omega_true
)
4678 pb
->eqs
[0].coef
[0]--;
4681 if (j
+ 1 < lower_bounds
)
4684 omega_copy_eqn (&pb
->geqs
[e
], &pb
->eqs
[0],
4686 pb
->geqs
[e
].touched
= 1;
4687 pb
->geqs
[e
].color
= omega_black
;
4688 omega_copy_problem (rS
, pb
);
4690 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4692 "exhausted lower bound, "
4693 "checking if still feasible ");
4695 result
= omega_solve_problem (rS
, omega_false
);
4697 if (result
== omega_false
)
4702 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4703 fprintf (dump_file
, "fall-off the end\n");
4715 return omega_unknown
;
4716 } while (eliminate_again
);
4720 /* Because the omega solver is recursive, this counter limits the
4722 static int omega_solve_depth
= 0;
4724 /* Return omega_true when the problem PB has a solution following the
4728 omega_solve_problem (omega_pb pb
, enum omega_result desired_res
)
4730 enum omega_result result
;
4732 gcc_assert (pb
->num_vars
>= pb
->safe_vars
);
4733 omega_solve_depth
++;
4735 if (desired_res
!= omega_simplify
)
4738 if (omega_solve_depth
> 50)
4740 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4743 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4744 omega_solve_depth
, in_approximate_mode
);
4745 omega_print_problem (dump_file
, pb
);
4750 if (omega_solve_eq (pb
, desired_res
) == omega_false
)
4752 omega_solve_depth
--;
4756 if (in_approximate_mode
&& !pb
->num_geqs
)
4758 result
= omega_true
;
4759 pb
->num_vars
= pb
->safe_vars
;
4760 omega_problem_reduced (pb
);
4763 result
= omega_solve_geq (pb
, desired_res
);
4765 omega_solve_depth
--;
4767 if (!omega_reduce_with_subs
)
4769 resurrect_subs (pb
);
4770 gcc_assert (please_no_equalities_in_simplified_problems
4771 || !result
|| pb
->num_subs
== 0);
4777 /* Return true if red equations constrain the set of possible solutions.
4778 We assume that there are solutions to the black equations by
4779 themselves, so if there is no solution to the combined problem, we
4783 omega_problem_has_red_equations (omega_pb pb
)
4789 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4791 fprintf (dump_file
, "Checking for red equations:\n");
4792 omega_print_problem (dump_file
, pb
);
4795 please_no_equalities_in_simplified_problems
++;
4798 if (omega_single_result
)
4799 return_single_result
++;
4801 create_color
= true;
4802 result
= (omega_simplify_problem (pb
) == omega_false
);
4804 if (omega_single_result
)
4805 return_single_result
--;
4808 please_no_equalities_in_simplified_problems
--;
4812 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4813 fprintf (dump_file
, "Gist is FALSE\n");
4818 pb
->eqs
[0].color
= omega_red
;
4820 for (i
= pb
->num_vars
; i
> 0; i
--)
4821 pb
->eqs
[0].coef
[i
] = 0;
4823 pb
->eqs
[0].coef
[0] = 1;
4827 free_red_eliminations (pb
);
4828 gcc_assert (pb
->num_eqs
== 0);
4830 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4831 if (pb
->geqs
[e
].color
== omega_red
)
4840 for (i
= pb
->safe_vars
; i
>= 1; i
--)
4845 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4847 if (pb
->geqs
[e
].coef
[i
])
4849 if (pb
->geqs
[e
].coef
[i
] > 0)
4850 lb
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4853 ub
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4857 if (ub
== 2 || lb
== 2)
4860 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4861 fprintf (dump_file
, "checks for upper/lower bounds worked!\n");
4863 if (!omega_reduce_with_subs
)
4865 resurrect_subs (pb
);
4866 gcc_assert (pb
->num_subs
== 0);
4874 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4876 "*** Doing potentially expensive elimination tests "
4877 "for red equations\n");
4879 please_no_equalities_in_simplified_problems
++;
4880 omega_eliminate_red (pb
, true);
4881 please_no_equalities_in_simplified_problems
--;
4884 gcc_assert (pb
->num_eqs
== 0);
4886 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4887 if (pb
->geqs
[e
].color
== omega_red
)
4893 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4897 "******************** Redundant Red Equations eliminated!!\n");
4900 "******************** Red Equations remain\n");
4902 omega_print_problem (dump_file
, pb
);
4905 if (!omega_reduce_with_subs
)
4907 normalize_return_type r
;
4909 resurrect_subs (pb
);
4910 r
= normalize_omega_problem (pb
);
4911 gcc_assert (r
!= normalize_false
);
4914 cleanout_wildcards (pb
);
4915 gcc_assert (pb
->num_subs
== 0);
4921 /* Calls omega_simplify_problem in approximate mode. */
4924 omega_simplify_approximate (omega_pb pb
)
4926 enum omega_result result
;
4928 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4929 fprintf (dump_file
, "(Entering approximate mode\n");
4931 in_approximate_mode
= true;
4932 result
= omega_simplify_problem (pb
);
4933 in_approximate_mode
= false;
4935 gcc_assert (pb
->num_vars
== pb
->safe_vars
);
4936 if (!omega_reduce_with_subs
)
4937 gcc_assert (pb
->num_subs
== 0);
4939 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4940 fprintf (dump_file
, "Leaving approximate mode)\n");
4946 /* Simplifies problem PB by eliminating redundant constraints and
4947 reducing the constraints system to a minimal form. Returns
4948 omega_true when the problem was successfully reduced, omega_unknown
4949 when the solver is unable to determine an answer. */
4952 omega_simplify_problem (omega_pb pb
)
4956 omega_found_reduction
= omega_false
;
4958 if (!pb
->variables_initialized
)
4959 omega_initialize_variables (pb
);
4961 if (next_key
* 3 > MAX_KEYS
)
4966 next_key
= OMEGA_MAX_VARS
+ 1;
4968 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4969 pb
->geqs
[e
].touched
= 1;
4971 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
4972 hash_master
[i
].touched
= -1;
4974 pb
->hash_version
= hash_version
;
4977 else if (pb
->hash_version
!= hash_version
)
4981 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4982 pb
->geqs
[e
].touched
= 1;
4984 pb
->hash_version
= hash_version
;
4987 if (pb
->num_vars
> pb
->num_eqs
+ 3 * pb
->safe_vars
)
4988 omega_free_eliminations (pb
, pb
->safe_vars
);
4990 if (!may_be_red
&& pb
->num_subs
== 0 && pb
->safe_vars
== 0)
4992 omega_found_reduction
= omega_solve_problem (pb
, omega_unknown
);
4994 if (omega_found_reduction
!= omega_false
4995 && !return_single_result
)
4999 (*omega_when_reduced
) (pb
);
5002 return omega_found_reduction
;
5005 omega_solve_problem (pb
, omega_simplify
);
5007 if (omega_found_reduction
!= omega_false
)
5009 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
5010 pb
->forwarding_address
[pb
->var
[i
]] = i
;
5012 for (i
= 0; i
< pb
->num_subs
; i
++)
5013 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
5016 if (!omega_reduce_with_subs
)
5017 gcc_assert (please_no_equalities_in_simplified_problems
5018 || omega_found_reduction
== omega_false
5019 || pb
->num_subs
== 0);
5021 return omega_found_reduction
;
5024 /* Make variable VAR unprotected: it then can be eliminated. */
5027 omega_unprotect_variable (omega_pb pb
, int var
)
5030 idx
= pb
->forwarding_address
[var
];
5037 if (idx
< pb
->num_subs
)
5039 omega_copy_eqn (&pb
->subs
[idx
], &pb
->subs
[pb
->num_subs
],
5041 pb
->forwarding_address
[pb
->subs
[idx
].key
] = -idx
- 1;
5046 int *bring_to_life
= XNEWVEC (int, OMEGA_MAX_VARS
);
5049 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5050 bring_to_life
[e
] = (pb
->subs
[e
].coef
[idx
] != 0);
5052 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
5053 if (bring_to_life
[e2
])
5058 if (pb
->safe_vars
< pb
->num_vars
)
5060 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5062 pb
->geqs
[e
].coef
[pb
->num_vars
] =
5063 pb
->geqs
[e
].coef
[pb
->safe_vars
];
5065 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5068 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5070 pb
->eqs
[e
].coef
[pb
->num_vars
] =
5071 pb
->eqs
[e
].coef
[pb
->safe_vars
];
5073 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5076 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5078 pb
->subs
[e
].coef
[pb
->num_vars
] =
5079 pb
->subs
[e
].coef
[pb
->safe_vars
];
5081 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5084 pb
->var
[pb
->num_vars
] = pb
->var
[pb
->safe_vars
];
5085 pb
->forwarding_address
[pb
->var
[pb
->num_vars
]] =
5090 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5091 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5093 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5094 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5096 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5097 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5100 pb
->var
[pb
->safe_vars
] = pb
->subs
[e2
].key
;
5101 pb
->forwarding_address
[pb
->subs
[e2
].key
] = pb
->safe_vars
;
5103 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e2
]),
5105 pb
->eqs
[pb
->num_eqs
++].coef
[pb
->safe_vars
] = -1;
5106 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5108 if (e2
< pb
->num_subs
- 1)
5109 omega_copy_eqn (&(pb
->subs
[e2
]), &(pb
->subs
[pb
->num_subs
- 1]),
5115 omega_unprotect_1 (pb
, &idx
, NULL
);
5116 free (bring_to_life
);
5119 chain_unprotect (pb
);
5122 /* Unprotects VAR and simplifies PB. */
5125 omega_constrain_variable_sign (omega_pb pb
, enum omega_eqn_color color
,
5128 int n_vars
= pb
->num_vars
;
5130 int k
= pb
->forwarding_address
[var
];
5139 omega_copy_eqn (&pb
->geqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5141 for (j
= 0; j
<= n_vars
; j
++)
5142 pb
->geqs
[e
].coef
[j
] *= sign
;
5144 pb
->geqs
[e
].coef
[0]--;
5145 pb
->geqs
[e
].touched
= 1;
5146 pb
->geqs
[e
].color
= color
;
5151 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5152 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5153 pb
->eqs
[e
].color
= color
;
5159 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
5160 pb
->geqs
[e
].coef
[k
] = sign
;
5161 pb
->geqs
[e
].coef
[0] = -1;
5162 pb
->geqs
[e
].touched
= 1;
5163 pb
->geqs
[e
].color
= color
;
5168 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5169 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5170 pb
->eqs
[e
].coef
[k
] = 1;
5171 pb
->eqs
[e
].color
= color
;
5174 omega_unprotect_variable (pb
, var
);
5175 return omega_simplify_problem (pb
);
5178 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5181 omega_constrain_variable_value (omega_pb pb
, enum omega_eqn_color color
,
5185 int k
= pb
->forwarding_address
[var
];
5191 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5192 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5193 pb
->eqs
[e
].coef
[0] -= value
;
5198 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5199 pb
->eqs
[e
].coef
[k
] = 1;
5200 pb
->eqs
[e
].coef
[0] = -value
;
5203 pb
->eqs
[e
].color
= color
;
5206 /* Return false when the upper and lower bounds are not coupled.
5207 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5211 omega_query_variable (omega_pb pb
, int i
, int *lower_bound
, int *upper_bound
)
5213 int n_vars
= pb
->num_vars
;
5216 bool coupled
= false;
5218 *lower_bound
= neg_infinity
;
5219 *upper_bound
= pos_infinity
;
5220 i
= pb
->forwarding_address
[i
];
5226 for (j
= 1; j
<= n_vars
; j
++)
5227 if (pb
->subs
[i
].coef
[j
] != 0)
5230 *upper_bound
= *lower_bound
= pb
->subs
[i
].coef
[0];
5234 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5235 if (pb
->subs
[e
].coef
[i
] != 0)
5241 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5242 if (pb
->eqs
[e
].coef
[i
] != 0)
5246 for (j
= 1; j
<= n_vars
; j
++)
5247 if (i
!= j
&& pb
->eqs
[e
].coef
[j
] != 0)
5258 *lower_bound
= *upper_bound
=
5259 -pb
->eqs
[e
].coef
[i
] * pb
->eqs
[e
].coef
[0];
5264 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5265 if (pb
->geqs
[e
].coef
[i
] != 0)
5267 if (pb
->geqs
[e
].key
== i
)
5268 *lower_bound
= MAX (*lower_bound
, -pb
->geqs
[e
].coef
[0]);
5270 else if (pb
->geqs
[e
].key
== -i
)
5271 *upper_bound
= MIN (*upper_bound
, pb
->geqs
[e
].coef
[0]);
5280 /* Sets the lower bound L and upper bound U for the values of variable
5281 I, and sets COULD_BE_ZERO to true if variable I might take value
5282 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5286 query_coupled_variable (omega_pb pb
, int i
, int *l
, int *u
,
5287 bool *could_be_zero
, int lower_bound
, int upper_bound
)
5294 /* Preconditions. */
5295 gcc_assert (abs (pb
->forwarding_address
[i
]) == 1
5296 && pb
->num_vars
+ pb
->num_subs
== 2
5297 && pb
->num_eqs
+ pb
->num_subs
== 1);
5299 /* Define variable I in terms of variable V. */
5300 if (pb
->forwarding_address
[i
] == -1)
5309 sign
= -eqn
->coef
[1];
5313 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5314 if (pb
->geqs
[e
].coef
[v
] != 0)
5316 if (pb
->geqs
[e
].coef
[v
] == 1)
5317 lower_bound
= MAX (lower_bound
, -pb
->geqs
[e
].coef
[0]);
5320 upper_bound
= MIN (upper_bound
, pb
->geqs
[e
].coef
[0]);
5323 if (lower_bound
> upper_bound
)
5331 if (lower_bound
== neg_infinity
)
5333 if (eqn
->coef
[v
] > 0)
5334 b1
= sign
* neg_infinity
;
5337 b1
= -sign
* neg_infinity
;
5340 b1
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * lower_bound
);
5342 if (upper_bound
== pos_infinity
)
5344 if (eqn
->coef
[v
] > 0)
5345 b2
= sign
* pos_infinity
;
5348 b2
= -sign
* pos_infinity
;
5351 b2
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * upper_bound
);
5353 *l
= MAX (*l
, b1
<= b2
? b1
: b2
);
5354 *u
= MIN (*u
, b1
<= b2
? b2
: b1
);
5356 *could_be_zero
= (*l
<= 0 && 0 <= *u
5357 && int_mod (eqn
->coef
[0], abs (eqn
->coef
[v
])) == 0);
5360 /* Return false when a lower bound L and an upper bound U for variable
5361 I in problem PB have been initialized. */
5364 omega_query_variable_bounds (omega_pb pb
, int i
, int *l
, int *u
)
5369 if (!omega_query_variable (pb
, i
, l
, u
)
5370 || (pb
->num_vars
== 1 && pb
->forwarding_address
[i
] == 1))
5373 if (abs (pb
->forwarding_address
[i
]) == 1
5374 && pb
->num_vars
+ pb
->num_subs
== 2
5375 && pb
->num_eqs
+ pb
->num_subs
== 1)
5378 query_coupled_variable (pb
, i
, l
, u
, &could_be_zero
, neg_infinity
,
5386 /* For problem PB, return an integer that represents the classic data
5387 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5388 masks that are added to the result. When DIST_KNOWN is true, DIST
5389 is set to the classic data dependence distance. LOWER_BOUND and
5390 UPPER_BOUND are bounds on the value of variable I, for example, it
5391 is possible to narrow the iteration domain with safe approximations
5392 of loop counts, and thus discard some data dependences that cannot
5396 omega_query_variable_signs (omega_pb pb
, int i
, int dd_lt
,
5397 int dd_eq
, int dd_gt
, int lower_bound
,
5398 int upper_bound
, bool *dist_known
, int *dist
)
5407 omega_query_variable (pb
, i
, &l
, &u
);
5408 query_coupled_variable (pb
, i
, &l
, &u
, &could_be_zero
, lower_bound
,
5427 *dist_known
= false;
5432 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5433 safe variables. Safe variables are not eliminated during the
5434 Fourier-Motzkin elimination. Safe variables are all those
5435 variables that are placed at the beginning of the array of
5436 variables: P->var[0, ..., NPROT - 1]. */
5439 omega_alloc_problem (int nvars
, int nprot
)
5443 gcc_assert (nvars
<= OMEGA_MAX_VARS
);
5444 omega_initialize ();
5446 /* Allocate and initialize PB. */
5447 pb
= XCNEW (struct omega_pb_d
);
5448 pb
->var
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5449 pb
->forwarding_address
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5450 pb
->geqs
= omega_alloc_eqns (0, OMEGA_MAX_GEQS
);
5451 pb
->eqs
= omega_alloc_eqns (0, OMEGA_MAX_EQS
);
5452 pb
->subs
= omega_alloc_eqns (0, OMEGA_MAX_VARS
+ 1);
5454 pb
->hash_version
= hash_version
;
5455 pb
->num_vars
= nvars
;
5456 pb
->safe_vars
= nprot
;
5457 pb
->variables_initialized
= false;
5458 pb
->variables_freed
= false;
5465 /* Keeps the state of the initialization. */
5466 static bool omega_initialized
= false;
5468 /* Initialization of the Omega solver. */
5471 omega_initialize (void)
5475 if (omega_initialized
)
5479 next_key
= OMEGA_MAX_VARS
+ 1;
5480 packing
= XCNEWVEC (int, OMEGA_MAX_VARS
);
5481 fast_lookup
= XCNEWVEC (int, MAX_KEYS
* 2);
5482 fast_lookup_red
= XCNEWVEC (int, MAX_KEYS
* 2);
5483 hash_master
= omega_alloc_eqns (0, HASH_TABLE_SIZE
);
5485 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
5486 hash_master
[i
].touched
= -1;
5488 sprintf (wild_name
[0], "1");
5489 sprintf (wild_name
[1], "a");
5490 sprintf (wild_name
[2], "b");
5491 sprintf (wild_name
[3], "c");
5492 sprintf (wild_name
[4], "d");
5493 sprintf (wild_name
[5], "e");
5494 sprintf (wild_name
[6], "f");
5495 sprintf (wild_name
[7], "g");
5496 sprintf (wild_name
[8], "h");
5497 sprintf (wild_name
[9], "i");
5498 sprintf (wild_name
[10], "j");
5499 sprintf (wild_name
[11], "k");
5500 sprintf (wild_name
[12], "l");
5501 sprintf (wild_name
[13], "m");
5502 sprintf (wild_name
[14], "n");
5503 sprintf (wild_name
[15], "o");
5504 sprintf (wild_name
[16], "p");
5505 sprintf (wild_name
[17], "q");
5506 sprintf (wild_name
[18], "r");
5507 sprintf (wild_name
[19], "s");
5508 sprintf (wild_name
[20], "t");
5509 sprintf (wild_name
[40 - 1], "alpha");
5510 sprintf (wild_name
[40 - 2], "beta");
5511 sprintf (wild_name
[40 - 3], "gamma");
5512 sprintf (wild_name
[40 - 4], "delta");
5513 sprintf (wild_name
[40 - 5], "tau");
5514 sprintf (wild_name
[40 - 6], "sigma");
5515 sprintf (wild_name
[40 - 7], "chi");
5516 sprintf (wild_name
[40 - 8], "omega");
5517 sprintf (wild_name
[40 - 9], "pi");
5518 sprintf (wild_name
[40 - 10], "ni");
5519 sprintf (wild_name
[40 - 11], "Alpha");
5520 sprintf (wild_name
[40 - 12], "Beta");
5521 sprintf (wild_name
[40 - 13], "Gamma");
5522 sprintf (wild_name
[40 - 14], "Delta");
5523 sprintf (wild_name
[40 - 15], "Tau");
5524 sprintf (wild_name
[40 - 16], "Sigma");
5525 sprintf (wild_name
[40 - 17], "Chi");
5526 sprintf (wild_name
[40 - 18], "Omega");
5527 sprintf (wild_name
[40 - 19], "xxx");
5529 omega_initialized
= true;