1 /* Source code for an implementation of the Omega test, an integer
2 programming algorithm for dependence analysis, by William Pugh,
3 appeared in Supercomputing '91 and CACM Aug 92.
5 This code has no license restrictions, and is considered public
8 Changes copyright (C) 2005, 2006 Free Software Foundation, Inc.
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 2, or (at your option) any later
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
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 ELIMINATE_REDUNDANT_CONSTRAINTS
36 - use expensive methods to eliminate all redundant constraints
39 - only produce a single simplified result.
42 - approximate inexact reductions omega_verify_simplification (runtime),
43 - if TRUE, omega_simplify_problem checks for problem with no
44 solutions omega_reduce_with_subs (runtime),
45 - if FALSE, convert substitutions back to EQs.
50 #include "coretypes.h"
55 #include "diagnostic.h"
57 #include "tree-pass.h"
60 bool omega_reduce_with_subs
= true;
61 bool omega_verify_simplification
= false;
70 #define return_single_result 1
72 static int return_single_result
= 0;
75 static int may_be_red
= 0;
76 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
77 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
79 static eqn hash_master
;
80 static bool non_convex
= false;
81 static bool do_it_again
;
82 static int conservative
= 0;
84 static char wild_name
[200][40];
85 static int next_wild_card
= 0;
86 static enum omega_result omega_found_reduction
;
88 static bool in_approximate_mode
= 0;
89 static bool create_color
= false;
90 static int please_no_equalities_in_simplified_problems
= 0;
91 static int hash_version
= 0;
93 omega_pb no_problem
= (omega_pb
) 0;
94 omega_pb original_problem
= (omega_pb
) 0;
96 /* Return the integer A divided by B. */
99 int_div (int a
, int b
)
104 return -((-a
+ b
- 1)/b
);
107 /* Return the integer A modulo B. */
110 int_mod (int a
, int b
)
112 return a
- b
* int_div (a
, b
);
115 /* For X and Y positive integers, return X multiplied by Y and check
116 that the result does not overflow. */
119 check_pos_mul (int x
, int y
)
122 gcc_assert ((INT_MAX
) / x
> y
);
127 /* Return X multiplied by Y and check that the result does not
131 check_mul (int x
, int y
)
136 return check_pos_mul (x
, y
);
138 return -check_pos_mul (x
, -y
);
141 return -check_pos_mul (-x
, y
);
143 return check_pos_mul (-x
, -y
);
146 /* Set *M to the maximum of *M and X. */
149 set_max (int *m
, int x
)
155 /* Set *M to the minimum of *M and X. */
158 set_min (int *m
, int x
)
164 /* Test whether equation E is red. */
167 omega_eqn_is_red (eqn e
, int desired_res
)
169 return (desired_res
== omega_simplify
&& e
->color
== omega_red
);
172 /* Return a string for VARIABLE. */
175 omega_var_to_str (int variable
)
177 if (0 <= variable
&& variable
<= 20)
178 return wild_name
[variable
];
180 if (-20 < variable
&& variable
< 0)
181 return wild_name
[40 + variable
];
183 /* Collapse all the entries that would have overflowed. */
184 return wild_name
[21];
187 /* Return a string for variable I in problem PB. */
190 omega_variable_to_str (omega_pb pb
, int i
)
192 return omega_var_to_str (pb
->var
[i
]);
195 /* Do nothing function: used for default initializations. */
198 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED
)
202 void (*omega_when_reduced
) (omega_pb
) = omega_no_procedure
;
204 /* Compute the greatest common divisor of A and B. */
222 /* Don't use this; instead, use omega_alloc_problem. This initializes
223 static vars for problem PB. FIXME: remove those static vars. */
226 omega_initialize_statics (omega_pb pb
)
228 pb
->hash_version
= hash_version
;
231 /* Print to FILE from PB equation E with all its coefficients
235 omega_print_term (FILE *file
, omega_pb pb
, eqn e
, int c
)
239 int n
= pb
->num_vars
;
242 for (i
= 1; i
<= n
; i
++)
243 if (c
* e
->coef
[i
] > 0)
248 if (c
* e
->coef
[i
] == 1)
249 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
251 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
252 omega_variable_to_str (pb
, i
));
256 for (i
= 1; i
<= n
; i
++)
257 if (i
!= went_first
&& c
* e
->coef
[i
] != 0)
259 if (!first
&& c
* e
->coef
[i
] > 0)
260 fprintf (file
, " + ");
264 if (c
* e
->coef
[i
] == 1)
265 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
266 else if (c
* e
->coef
[i
] == -1)
267 fprintf (file
, " - %s", omega_variable_to_str (pb
, i
));
269 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
270 omega_variable_to_str (pb
, i
));
273 if (!first
&& c
* e
->coef
[0] > 0)
274 fprintf (file
, " + ");
276 if (first
|| c
* e
->coef
[0] != 0)
277 fprintf (file
, "%d", c
* e
->coef
[0]);
280 /* Print to FILE the equation E of problem PB. */
283 omega_print_eqn (FILE *file
, omega_pb pb
, eqn e
, bool test
, int extra
)
286 int n
= pb
->num_vars
+ extra
;
287 bool is_lt
= test
&& e
->coef
[0] == -1;
295 else if (e
->key
!= 0)
296 fprintf (file
, "%d: ", e
->key
);
299 if (e
->color
== omega_red
)
304 for (i
= is_lt
? 1 : 0; i
<= n
; i
++)
308 fprintf (file
, " + ");
313 fprintf (file
, "%d", -e
->coef
[i
]);
314 else if (e
->coef
[i
] == -1)
315 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
317 fprintf (file
, "%d * %s", -e
->coef
[i
],
318 omega_variable_to_str (pb
, i
));
333 fprintf (file
, " = ");
335 fprintf (file
, " < ");
337 fprintf (file
, " <= ");
341 for (i
= 0; i
<= n
; i
++)
345 fprintf (file
, " + ");
350 fprintf (file
, "%d", e
->coef
[i
]);
351 else if (e
->coef
[i
] == 1)
352 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
354 fprintf (file
, "%d * %s", e
->coef
[i
],
355 omega_variable_to_str (pb
, i
));
361 if (e
->color
== omega_red
)
365 /* Print to FILE all the variables of problem PB. */
368 omega_print_vars (FILE *file
, omega_pb pb
)
372 fprintf (file
, "variables = ");
374 if (pb
->safe_vars
> 0)
375 fprintf (file
, "protected (");
377 for (i
= 1; i
<= pb
->num_vars
; i
++)
379 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
381 if (i
== pb
->safe_vars
)
384 if (i
< pb
->num_vars
)
385 fprintf (file
, ", ");
388 fprintf (file
, "\n");
391 /* Debug problem PB. */
394 debug_omega_problem (omega_pb pb
)
396 omega_print_problem (stderr
, pb
);
399 /* Print to FILE problem PB. */
402 omega_print_problem (FILE *file
, omega_pb pb
)
406 if (!pb
->variables_initialized
)
407 omega_initialize_variables (pb
);
409 omega_print_vars (file
, pb
);
411 for (e
= 0; e
< pb
->num_eqs
; e
++)
413 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
414 fprintf (file
, "\n");
417 fprintf (file
, "Done with EQ\n");
419 for (e
= 0; e
< pb
->num_geqs
; e
++)
421 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
422 fprintf (file
, "\n");
425 fprintf (file
, "Done with GEQ\n");
427 for (e
= 0; e
< pb
->num_subs
; e
++)
429 eqn eq
= &pb
->subs
[e
];
431 if (eq
->color
== omega_red
)
435 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
437 fprintf (file
, "#%d := ", eq
->key
);
439 omega_print_term (file
, pb
, eq
, 1);
441 if (eq
->color
== omega_red
)
444 fprintf (file
, "\n");
448 /* Return the number of equations in PB tagged omega_red. */
451 omega_count_red_equations (omega_pb pb
)
456 for (e
= 0; e
< pb
->num_eqs
; e
++)
457 if (pb
->eqs
[e
].color
== omega_red
)
459 for (i
= pb
->num_vars
; i
> 0; i
--)
460 if (pb
->geqs
[e
].coef
[i
])
463 if (i
== 0 && pb
->geqs
[e
].coef
[0] == 1)
469 for (e
= 0; e
< pb
->num_geqs
; e
++)
470 if (pb
->geqs
[e
].color
== omega_red
)
473 for (e
= 0; e
< pb
->num_subs
; e
++)
474 if (pb
->subs
[e
].color
== omega_red
)
480 /* Print to FILE all the equations in PB that are tagged omega_red. */
483 omega_print_red_equations (FILE *file
, omega_pb pb
)
487 if (!pb
->variables_initialized
)
488 omega_initialize_variables (pb
);
490 omega_print_vars (file
, pb
);
492 for (e
= 0; e
< pb
->num_eqs
; e
++)
493 if (pb
->eqs
[e
].color
== omega_red
)
495 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
496 fprintf (file
, "\n");
499 for (e
= 0; e
< pb
->num_geqs
; e
++)
500 if (pb
->geqs
[e
].color
== omega_red
)
502 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
503 fprintf (file
, "\n");
506 for (e
= 0; e
< pb
->num_subs
; e
++)
507 if (pb
->subs
[e
].color
== omega_red
)
509 eqn eq
= &pb
->subs
[e
];
513 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
515 fprintf (file
, "#%d := ", eq
->key
);
517 omega_print_term (file
, pb
, eq
, 1);
518 fprintf (file
, "]\n");
522 /* Pretty print PB to FILE. */
525 omega_pretty_print_problem (FILE *file
, omega_pb pb
)
527 int e
, v
, v1
, v2
, v3
, t
;
528 bool *live
= (bool *) (xmalloc (OMEGA_MAX_GEQS
* sizeof (bool)));
529 int stuffPrinted
= 0;
534 } partial_order_type
;
536 partial_order_type
**po
= (partial_order_type
**)
537 xmalloc (OMEGA_MAX_VARS
* OMEGA_MAX_VARS
* sizeof (partial_order_type
));
538 int **po_eq
= (int **) xmalloc (OMEGA_MAX_VARS
* OMEGA_MAX_VARS
* sizeof (int));
539 int *last_links
= (int *) xmalloc (OMEGA_MAX_VARS
* sizeof (int));
540 int *first_links
= (int *) xmalloc (OMEGA_MAX_VARS
* sizeof (int));
541 int *chain_length
= (int *) xmalloc (OMEGA_MAX_VARS
* sizeof (int));
542 int *chain
= (int *) xmalloc (OMEGA_MAX_VARS
* sizeof (int));
546 if (!pb
->variables_initialized
)
547 omega_initialize_variables (pb
);
549 if (pb
->num_vars
> 0)
551 omega_eliminate_redundant (pb
, 0);
553 for (e
= 0; e
< pb
->num_eqs
; e
++)
556 fprintf (file
, "; ");
559 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
562 for (e
= 0; e
< pb
->num_geqs
; e
++)
567 for (v
= 1; v
<= pb
->num_vars
; v
++)
569 last_links
[v
] = first_links
[v
] = 0;
572 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
576 for (e
= 0; e
< pb
->num_geqs
; e
++)
579 for (v
= 1; v
<= pb
->num_vars
; v
++)
580 if (pb
->geqs
[e
].coef
[v
] == 1)
582 else if (pb
->geqs
[e
].coef
[v
] == -1)
587 while (v1
> 0 && pb
->geqs
[e
].coef
[v1
] == 0)
592 while (v2
> 0 && pb
->geqs
[e
].coef
[v2
] == 0)
597 while (v3
> 0 && pb
->geqs
[e
].coef
[v3
] == 0)
600 if (pb
->geqs
[e
].coef
[0] > 0 || pb
->geqs
[e
].coef
[0] < -1
602 || pb
->geqs
[e
].coef
[v1
] * pb
->geqs
[e
].coef
[v2
] != -1)
604 /* Not a partial order relation. */
608 if (pb
->geqs
[e
].coef
[v1
] == 1)
615 /* Relation is v1 <= v2 or v1 < v2. */
616 po
[v1
][v2
] = ((pb
->geqs
[e
].coef
[0] == 0) ? le
: lt
);
620 for (v
= 1; v
<= pb
->num_vars
; v
++)
621 chain_length
[v
] = last_links
[v
];
623 /* Just in case pb->num_vars <= 0. */
625 for (t
= 0; t
< pb
->num_vars
; t
++)
629 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
630 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
631 if (po
[v1
][v2
] != none
&&
632 chain_length
[v1
] <= chain_length
[v2
])
634 chain_length
[v1
] = chain_length
[v2
] + 1;
639 /* Caught in cycle. */
640 gcc_assert (!change
);
642 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
643 if (chain_length
[v1
] == 0)
648 for (v1
= 2; v1
<= pb
->num_vars
; v1
++)
649 if (chain_length
[v1
] + first_links
[v1
] >
650 chain_length
[v
] + first_links
[v
])
653 if (chain_length
[v
] + first_links
[v
] == 0)
657 fprintf (file
, "; ");
661 /* Chain starts at v. */
666 for (e
= 0; e
< pb
->num_geqs
; e
++)
667 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == 1)
670 fprintf (file
, ", ");
672 tmp
= pb
->geqs
[e
].coef
[v
];
673 pb
->geqs
[e
].coef
[v
] = 0;
674 omega_print_term (file
, pb
, &pb
->geqs
[e
], -1);
675 pb
->geqs
[e
].coef
[v
] = tmp
;
681 fprintf (file
, " <= ");
690 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
691 if (po
[v
][v2
] && chain_length
[v
] == 1 + chain_length
[v2
])
694 if (v2
> pb
->num_vars
)
701 fprintf (file
, "%s", omega_variable_to_str (pb
, chain
[0]));
703 for (multiprint
= false, i
= 1; i
< m
; i
++)
709 fprintf (file
, " <= ");
711 fprintf (file
, " < ");
713 fprintf (file
, "%s", omega_variable_to_str (pb
, v2
));
714 live
[po_eq
[v
][v2
]] = false;
716 if (!multiprint
&& i
< m
- 1)
717 for (v3
= 1; v3
<= pb
->num_vars
; v3
++)
719 if (v
== v3
|| v2
== v3
720 || po
[v
][v2
] != po
[v
][v3
]
721 || po
[v2
][chain
[i
+ 1]] != po
[v3
][chain
[i
+ 1]])
724 fprintf (file
, ",%s", omega_variable_to_str (pb
, v3
));
725 live
[po_eq
[v
][v3
]] = false;
726 live
[po_eq
[v3
][chain
[i
+ 1]]] = false;
734 /* Print last_links. */
739 for (e
= 0; e
< pb
->num_geqs
; e
++)
740 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == -1)
743 fprintf (file
, ", ");
745 fprintf (file
, " <= ");
747 tmp
= pb
->geqs
[e
].coef
[v
];
748 pb
->geqs
[e
].coef
[v
] = 0;
749 omega_print_term (file
, pb
, &pb
->geqs
[e
], 1);
750 pb
->geqs
[e
].coef
[v
] = tmp
;
757 for (e
= 0; e
< pb
->num_geqs
; e
++)
761 fprintf (file
, "; ");
763 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
766 for (e
= 0; e
< pb
->num_subs
; e
++)
768 eqn eq
= &pb
->subs
[e
];
771 fprintf (file
, "; ");
776 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
778 fprintf (file
, "#%d := ", eq
->key
);
780 omega_print_term (file
, pb
, eq
, 1);
793 /* Assign to variable I in PB the next wildcard name. The name of a
794 wildcard is a negative number. */
797 omega_name_wild_card (omega_pb pb
, int i
)
800 if (next_wild_card
< -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS
))
802 pb
->var
[i
] = next_wild_card
;
805 /* Return the index of the last protected (or safe) variable in PB,
806 after having added a new wildcard variable. */
809 omega_add_new_wild_card (omega_pb pb
)
812 int i
= ++pb
->safe_vars
;
815 /* Make a free place in the protected (safe) variables, by moving
816 the non protected variable pointed by "I" at the end, ie. at
817 offset pb->num_vars. */
818 if (pb
->num_vars
!= i
)
820 /* Move "I" for all the inequalities. */
821 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
823 if (pb
->geqs
[e
].coef
[i
])
824 pb
->geqs
[e
].touched
= 1;
826 pb
->geqs
[e
].coef
[pb
->num_vars
] = pb
->geqs
[e
].coef
[i
];
829 /* Move "I" for all the equalities. */
830 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
831 pb
->eqs
[e
].coef
[pb
->num_vars
] = pb
->eqs
[e
].coef
[i
];
833 /* Move "I" for all the substitutions. */
834 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
835 pb
->subs
[e
].coef
[pb
->num_vars
] = pb
->subs
[e
].coef
[i
];
837 /* Move the identifier. */
838 pb
->var
[pb
->num_vars
] = pb
->var
[i
];
841 /* Initialize at zero all the coefficients */
842 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
843 pb
->geqs
[e
].coef
[i
] = 0;
845 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
846 pb
->eqs
[e
].coef
[i
] = 0;
848 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
849 pb
->subs
[e
].coef
[i
] = 0;
851 /* And give it a name. */
852 omega_name_wild_card (pb
, i
);
856 /* Delete inequality E from problem PB that has N_VARS variables. */
859 omega_delete_geq (omega_pb pb
, int e
, int nv
)
861 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
863 fprintf (dump_file
, "Deleting %d (last:%d): ", e
, pb
->num_geqs
- 1);
864 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
865 fprintf (dump_file
, "\n");
868 if (e
< pb
->num_geqs
- 1)
869 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], nv
);
874 /* Delete extra inequality E from problem PB that has N_VARS variables. */
877 omega_delete_geq_extra (omega_pb pb
, int e
, int n_vars
)
879 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
881 fprintf (dump_file
, "Deleting %d: ",e
);
882 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
883 fprintf (dump_file
, "\n");
886 if (e
< pb
->num_geqs
- 1)
887 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
893 /* Remove variable I from problem PB. */
896 omega_delete_variable (omega_pb pb
, int i
)
898 int n_vars
= pb
->num_vars
;
901 if (omega_safe_var_p (pb
, i
))
903 int j
= pb
->safe_vars
;
905 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
907 pb
->geqs
[e
].touched
= 1;
908 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[j
];
909 pb
->geqs
[e
].coef
[j
] = pb
->geqs
[e
].coef
[n_vars
];
912 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
914 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[j
];
915 pb
->eqs
[e
].coef
[j
] = pb
->eqs
[e
].coef
[n_vars
];
918 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
920 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[j
];
921 pb
->subs
[e
].coef
[j
] = pb
->subs
[e
].coef
[n_vars
];
924 pb
->var
[i
] = pb
->var
[j
];
925 pb
->var
[j
] = pb
->var
[n_vars
];
929 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
930 if (pb
->geqs
[e
].coef
[n_vars
])
932 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[n_vars
];
933 pb
->geqs
[e
].touched
= 1;
936 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
937 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[n_vars
];
939 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
940 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[n_vars
];
942 pb
->var
[i
] = pb
->var
[n_vars
];
945 if (omega_safe_var_p (pb
, i
))
951 /* Helper function. */
954 setup_packing (eqn eqn
, int num_vars
)
957 int *p
= &packing
[0];
959 for (k
= num_vars
; k
>= 0; k
--)
963 return (p
- &packing
[0]) - 1;
967 /* Helper function. */
970 omega_substitute_red_1 (eqn eq
, eqn sub
, int var
, int c
, bool *found_black
,
973 int j
, k
= eq
->coef
[var
];
977 if (eq
->color
== omega_black
)
982 for (j
= top_var
; j
>= 0; j
--)
983 eq
->coef
[packing
[j
]] -= sub
->coef
[packing
[j
]] * k
* c
;
988 /* Substitute in PB variable VAR with "C * SUB". */
991 omega_substitute_red (omega_pb pb
, eqn sub
, int var
, int c
, bool *found_black
)
993 int e
, top_var
= setup_packing (sub
, pb
->num_vars
);
995 *found_black
= false;
997 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
999 if (sub
->color
== omega_red
)
1000 fprintf (dump_file
, "[");
1002 fprintf (dump_file
, "substituting using %s := ",
1003 omega_variable_to_str (pb
, var
));
1004 omega_print_term (dump_file
, pb
, sub
, -c
);
1006 if (sub
->color
== omega_red
)
1007 fprintf (dump_file
, "]");
1009 fprintf (dump_file
, "\n");
1010 omega_print_vars (dump_file
, pb
);
1013 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1015 eqn eqn
= &(pb
->eqs
[e
]);
1017 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
1019 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1021 omega_print_eq (dump_file
, pb
, eqn
);
1022 fprintf (dump_file
, "\n");
1026 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1028 eqn eqn
= &(pb
->geqs
[e
]);
1030 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
1032 if (eqn
->coef
[var
] && eqn
->color
== omega_red
)
1035 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1037 omega_print_geq (dump_file
, pb
, eqn
);
1038 fprintf (dump_file
, "\n");
1042 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1044 eqn eqn
= &(pb
->subs
[e
]);
1046 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
1048 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1050 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1051 omega_print_term (dump_file
, pb
, eqn
, 1);
1052 fprintf (dump_file
, "\n");
1056 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1057 fprintf (dump_file
, "---\n\n");
1059 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1060 *found_black
= true;
1063 /* Substitute in PB variable VAR with "C * SUB". */
1066 omega_substitute (omega_pb pb
, eqn sub
, int var
, int c
)
1069 int top_var
= setup_packing (sub
, pb
->num_vars
);
1071 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1073 fprintf (dump_file
, "substituting using %s := ",
1074 omega_variable_to_str (pb
, var
));
1075 omega_print_term (dump_file
, pb
, sub
, -c
);
1076 fprintf (dump_file
, "\n");
1077 omega_print_vars (dump_file
, pb
);
1082 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1083 pb
->eqs
[e
].coef
[var
] = 0;
1085 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1086 if (pb
->geqs
[e
].coef
[var
] != 0)
1088 pb
->geqs
[e
].touched
= 1;
1089 pb
->geqs
[e
].coef
[var
] = 0;
1092 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1093 pb
->subs
[e
].coef
[var
] = 0;
1095 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1098 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1100 for (k
= pb
->num_vars
; k
>= 0; k
--)
1103 eqn
->key
= pb
->var
[var
];
1104 eqn
->color
= omega_black
;
1107 else if (top_var
== 0 && packing
[0] == 0)
1109 c
= -sub
->coef
[0] * c
;
1111 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1113 pb
->eqs
[e
].coef
[0] += pb
->eqs
[e
].coef
[var
] * c
;
1114 pb
->eqs
[e
].coef
[var
] = 0;
1117 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1118 if (pb
->geqs
[e
].coef
[var
] != 0)
1120 pb
->geqs
[e
].coef
[0] += pb
->geqs
[e
].coef
[var
] * c
;
1121 pb
->geqs
[e
].coef
[var
] = 0;
1122 pb
->geqs
[e
].touched
= 1;
1125 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1127 pb
->subs
[e
].coef
[0] += pb
->subs
[e
].coef
[var
] * c
;
1128 pb
->subs
[e
].coef
[var
] = 0;
1131 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1134 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1136 for (k
= pb
->num_vars
; k
>= 1; k
--)
1140 eqn
->key
= pb
->var
[var
];
1141 eqn
->color
= omega_black
;
1144 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1146 fprintf (dump_file
, "---\n\n");
1147 omega_print_problem (dump_file
, pb
);
1148 fprintf (dump_file
, "===\n\n");
1153 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1155 eqn eqn
= &(pb
->eqs
[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 omega_print_eq (dump_file
, pb
, eqn
);
1173 fprintf (dump_file
, "\n");
1177 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1179 eqn eqn
= &(pb
->geqs
[e
]);
1180 int k
= eqn
->coef
[var
];
1188 for (j
= top_var
; j
>= 0; j
--)
1191 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1195 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1197 omega_print_geq (dump_file
, pb
, eqn
);
1198 fprintf (dump_file
, "\n");
1202 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1204 eqn eqn
= &(pb
->subs
[e
]);
1205 int k
= eqn
->coef
[var
];
1212 for (j
= top_var
; j
>= 0; j
--)
1215 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1219 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1221 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1222 omega_print_term (dump_file
, pb
, eqn
, 1);
1223 fprintf (dump_file
, "\n");
1227 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1229 fprintf (dump_file
, "---\n\n");
1230 omega_print_problem (dump_file
, pb
);
1231 fprintf (dump_file
, "===\n\n");
1234 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1237 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1240 for (k
= pb
->num_vars
; k
>= 0; k
--)
1241 eqn
->coef
[k
] = c
* (sub
->coef
[k
]);
1243 eqn
->key
= pb
->var
[var
];
1244 eqn
->color
= sub
->color
;
1249 /* Solve e = factor alpha for x_j and substitute. */
1252 omega_do_mod (omega_pb pb
, int factor
, int e
, int j
)
1255 eqn eq
= omega_alloc_eqns (0, 1);
1257 bool kill_j
= false;
1259 omega_copy_eqn (eq
, &pb
->eqs
[e
], pb
->num_vars
);
1261 for (k
= pb
->num_vars
; k
>= 0; k
--)
1263 eq
->coef
[k
] = int_mod (eq
->coef
[k
], factor
);
1265 if (2 * eq
->coef
[k
] >= factor
)
1266 eq
->coef
[k
] -= factor
;
1269 nfactor
= eq
->coef
[j
];
1271 if (omega_safe_var_p (pb
, j
) && !omega_wildcard_p (pb
, j
))
1273 i
= omega_add_new_wild_card (pb
);
1274 eq
->coef
[pb
->num_vars
] = eq
->coef
[i
];
1276 eq
->coef
[i
] = -factor
;
1281 eq
->coef
[j
] = -factor
;
1282 if (!omega_wildcard_p (pb
, j
))
1283 omega_name_wild_card (pb
, j
);
1286 omega_substitute (pb
, eq
, j
, nfactor
);
1288 for (k
= pb
->num_vars
; k
>= 0; k
--)
1289 pb
->eqs
[e
].coef
[k
] = pb
->eqs
[e
].coef
[k
] / factor
;
1292 omega_delete_variable (pb
, j
);
1294 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1296 fprintf (dump_file
, "Mod-ing and normalizing produces:\n");
1297 omega_print_problem (dump_file
, pb
);
1300 omega_free_eqns (eq
, 1);
1303 /* Multiplies by -1 inequality E. */
1306 omega_negate_geq (omega_pb pb
, int e
)
1310 for (i
= pb
->num_vars
; i
>= 0; i
--)
1311 pb
->geqs
[e
].coef
[i
] *= -1;
1313 pb
->geqs
[e
].coef
[0]--;
1314 pb
->geqs
[e
].touched
= 1;
1317 /* Returns OMEGA_TRUE when problem PB has a solution. */
1319 static enum omega_result
1320 verify_omega_pb (omega_pb pb
)
1322 enum omega_result result
;
1324 bool any_color
= false;
1325 omega_pb tmp_problem
= (omega_pb
) xmalloc (sizeof (struct omega_pb
));
1327 omega_copy_problem (tmp_problem
, pb
);
1328 tmp_problem
->safe_vars
= 0;
1329 tmp_problem
->num_subs
= 0;
1331 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1332 if (pb
->geqs
[e
].color
== omega_red
)
1338 if (please_no_equalities_in_simplified_problems
)
1342 original_problem
= no_problem
;
1344 original_problem
= pb
;
1346 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1348 fprintf (dump_file
, "verifying problem");
1351 fprintf (dump_file
, " (color mode)");
1353 fprintf (dump_file
, " :\n");
1354 omega_print_problem (dump_file
, pb
);
1357 result
= omega_solve_problem (tmp_problem
, omega_unknown
);
1358 original_problem
= no_problem
;
1361 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1363 if (result
!= omega_false
)
1364 fprintf (dump_file
, "verified problem\n");
1366 fprintf (dump_file
, "disproved problem\n");
1367 omega_print_problem (dump_file
, pb
);
1373 /* Add a new equality to problem PB at last position E. */
1376 adding_equality_constraint (omega_pb pb
, int e
)
1380 if (original_problem
!= no_problem
&& original_problem
!= pb
1383 e2
= original_problem
->num_eqs
++;
1385 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1387 "adding equality constraint %d to outer problem\n", e2
);
1388 omega_init_eqn_zero (&original_problem
->eqs
[e2
],
1389 original_problem
->num_vars
);
1391 for (i
= pb
->num_vars
; i
>= 1; i
--)
1393 for (j
= original_problem
->num_vars
; j
>= 1; j
--)
1394 if (original_problem
->var
[j
] == pb
->var
[i
])
1399 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1400 fprintf (dump_file
, "retracting\n");
1401 original_problem
->num_eqs
--;
1404 original_problem
->eqs
[e2
].coef
[j
] = pb
->eqs
[e
].coef
[i
];
1407 original_problem
->eqs
[e2
].coef
[0] = pb
->eqs
[e
].coef
[0];
1409 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1410 omega_print_problem (dump_file
, original_problem
);
1414 static int *fast_lookup
;
1415 static int *fast_lookup_red
;
1419 normalize_uncoupled
,
1421 } normalize_return_type
;
1423 /* Normalizes PB by removing redundant constraints. Returns
1424 normalize_false when the constraints system has no solution,
1425 otherwise returns normalize_coupled or normalize_uncoupled. */
1427 static normalize_return_type
1428 normalize_omega_problem (omega_pb pb
)
1430 int e
, i
, j
, k
, n_vars
;
1431 int coupled_subscripts
= 0;
1433 n_vars
= pb
->num_vars
;
1435 for (e
= 0; e
< pb
->num_geqs
; e
++)
1437 if (!pb
->geqs
[e
].touched
)
1439 if (!single_var_geq (&pb
->geqs
[e
], n_vars
))
1440 coupled_subscripts
= 1;
1444 int g
, top_var
, i0
, hashCode
;
1445 int *p
= &packing
[0];
1447 for (k
= 1; k
<= n_vars
; k
++)
1448 if (pb
->geqs
[e
].coef
[k
])
1451 top_var
= (p
- &packing
[0]) - 1;
1455 if (pb
->geqs
[e
].coef
[0] < 0)
1457 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1459 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1460 fprintf (dump_file
, "\nequations have no solution \n");
1462 return normalize_false
;
1465 omega_delete_geq (pb
, e
, n_vars
);
1469 else if (top_var
== 0)
1471 int singlevar
= packing
[0];
1473 g
= pb
->geqs
[e
].coef
[singlevar
];
1477 pb
->geqs
[e
].coef
[singlevar
] = 1;
1478 pb
->geqs
[e
].key
= singlevar
;
1483 pb
->geqs
[e
].coef
[singlevar
] = -1;
1484 pb
->geqs
[e
].key
= -singlevar
;
1488 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1494 coupled_subscripts
= 1;
1497 g
= pb
->geqs
[e
].coef
[i
];
1498 hashCode
= g
* (i
+ 3);
1503 for (; i0
>= 0; i0
--)
1508 x
= pb
->geqs
[e
].coef
[i
];
1509 hashCode
= hashCode
* KEY_MULT
* (i
+ 3) + x
;
1524 for (; i0
>= 0; i0
--)
1528 x
= pb
->geqs
[e
].coef
[i
];
1529 hashCode
= hashCode
* KEY_MULT
* (i
+ 3) + x
;
1534 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1537 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1538 hashCode
= pb
->geqs
[e
].coef
[i
] * (i
+ 3);
1540 for (; i0
>= 0; i0
--)
1543 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1545 hashCode
* KEY_MULT
* (i
+ 3) + pb
->geqs
[e
].coef
[i
];
1549 g2
= abs (hashCode
);
1551 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1553 fprintf (dump_file
, "Hash code = %d, eqn = ", hashCode
);
1554 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1555 fprintf (dump_file
, "\n");
1558 j
= g2
% HASH_TABLE_SIZE
;
1561 eqn proto
= &(hash_master
[j
]);
1563 if (proto
->touched
== g2
)
1565 if (proto
->coef
[0] == top_var
)
1568 for (i0
= top_var
; i0
>= 0; i0
--)
1572 if (pb
->geqs
[e
].coef
[i
] != proto
->coef
[i
])
1576 for (i0
= top_var
; i0
>= 0; i0
--)
1580 if (pb
->geqs
[e
].coef
[i
] != -proto
->coef
[i
])
1587 pb
->geqs
[e
].key
= proto
->key
;
1589 pb
->geqs
[e
].key
= -proto
->key
;
1594 else if (proto
->touched
< 0)
1596 omega_init_eqn_zero (proto
, pb
->num_vars
);
1598 for (i0
= top_var
; i0
>= 0; i0
--)
1601 proto
->coef
[i
] = pb
->geqs
[e
].coef
[i
];
1604 for (i0
= top_var
; i0
>= 0; i0
--)
1607 proto
->coef
[i
] = -pb
->geqs
[e
].coef
[i
];
1610 proto
->coef
[0] = top_var
;
1611 proto
->touched
= g2
;
1613 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1614 fprintf (dump_file
, " constraint key = %d\n",
1617 proto
->key
= next_key
++;
1619 /* Too many hash keys generated. */
1620 gcc_assert (proto
->key
<= MAX_KEYS
);
1623 pb
->geqs
[e
].key
= proto
->key
;
1625 pb
->geqs
[e
].key
= -proto
->key
;
1630 j
= (j
+ 1) % HASH_TABLE_SIZE
;
1634 pb
->geqs
[e
].touched
= 0;
1638 int eKey
= pb
->geqs
[e
].key
;
1642 int cTerm
= pb
->geqs
[e
].coef
[0];
1643 e2
= fast_lookup
[MAX_KEYS
- eKey
];
1645 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1646 && pb
->geqs
[e2
].color
== omega_black
)
1648 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1650 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1652 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1653 fprintf (dump_file
, "\n");
1654 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1656 "\nequations have no solution \n");
1658 return normalize_false
;
1661 if (pb
->geqs
[e2
].coef
[0] == -cTerm
1663 || pb
->geqs
[e
].color
== omega_black
))
1665 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1667 if (pb
->geqs
[e
].color
== omega_black
)
1668 adding_equality_constraint (pb
, pb
->num_eqs
);
1670 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1674 e2
= fast_lookup_red
[MAX_KEYS
- eKey
];
1676 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1677 && pb
->geqs
[e2
].color
== omega_red
)
1679 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1681 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1683 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1684 fprintf (dump_file
, "\n");
1685 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1687 "\nequations have no solution \n");
1689 return normalize_false
;
1692 if (pb
->geqs
[e2
].coef
[0] == -cTerm
&& create_color
)
1694 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1696 pb
->eqs
[pb
->num_eqs
].color
= omega_red
;
1698 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1702 e2
= fast_lookup
[MAX_KEYS
+ eKey
];
1704 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1705 && pb
->geqs
[e2
].color
== omega_black
)
1707 if (pb
->geqs
[e2
].coef
[0] > cTerm
)
1709 if (pb
->geqs
[e
].color
== omega_black
)
1711 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1714 "Removing Redudant Equation: ");
1715 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1716 fprintf (dump_file
, "\n");
1718 "[a] Made Redundant by: ");
1719 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1720 fprintf (dump_file
, "\n");
1722 pb
->geqs
[e2
].coef
[0] = cTerm
;
1723 omega_delete_geq (pb
, e
, n_vars
);
1730 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1732 fprintf (dump_file
, "Removing Redudant Equation: ");
1733 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1734 fprintf (dump_file
, "\n");
1735 fprintf (dump_file
, "[b] Made Redundant by: ");
1736 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1737 fprintf (dump_file
, "\n");
1739 omega_delete_geq (pb
, e
, n_vars
);
1745 e2
= fast_lookup_red
[MAX_KEYS
+ eKey
];
1747 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1748 && pb
->geqs
[e2
].color
== omega_red
)
1750 if (pb
->geqs
[e2
].coef
[0] >= cTerm
)
1752 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1754 fprintf (dump_file
, "Removing Redudant Equation: ");
1755 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1756 fprintf (dump_file
, "\n");
1757 fprintf (dump_file
, "[c] Made Redundant by: ");
1758 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1759 fprintf (dump_file
, "\n");
1761 pb
->geqs
[e2
].coef
[0] = cTerm
;
1762 pb
->geqs
[e2
].color
= pb
->geqs
[e
].color
;
1764 else if (pb
->geqs
[e
].color
== omega_red
)
1766 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1768 fprintf (dump_file
, "Removing Redudant Equation: ");
1769 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1770 fprintf (dump_file
, "\n");
1771 fprintf (dump_file
, "[d] Made Redundant by: ");
1772 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1773 fprintf (dump_file
, "\n");
1776 omega_delete_geq (pb
, e
, n_vars
);
1783 if (pb
->geqs
[e
].color
== omega_red
)
1784 fast_lookup_red
[MAX_KEYS
+ eKey
] = e
;
1786 fast_lookup
[MAX_KEYS
+ eKey
] = e
;
1790 create_color
= false;
1791 return coupled_subscripts
? normalize_coupled
: normalize_uncoupled
;
1794 /* Divide the coefficients of EQN by their gcd. */
1797 divide_eqn_by_gcd (eqn eqn
, int n_vars
)
1801 for (var
= n_vars
; var
>= 0; var
--)
1802 g
= gcd (abs (eqn
->coef
[var
]), g
);
1805 for (var
= n_vars
; var
>= 0; var
--)
1806 eqn
->coef
[var
] = eqn
->coef
[var
] / g
;
1809 /* Rewrite some non-safe variables in function of protected
1810 wildcard variables. */
1813 cleanout_wildcards (omega_pb pb
)
1816 int n_vars
= pb
->num_vars
;
1817 bool renormalize
= false;
1819 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1820 for (i
= n_vars
; !omega_safe_var_p (pb
, i
); i
--)
1821 if (pb
->eqs
[e
].coef
[i
] != 0)
1823 /* i is the last non-zero non-safe variable. */
1825 for (j
= i
- 1; !omega_safe_var_p (pb
, j
); j
--)
1826 if (pb
->eqs
[e
].coef
[j
] != 0)
1829 /* j is the next non-zero non-safe variable, or points
1830 to a safe variable: it is then a wildcard variable. */
1833 if (omega_safe_var_p (pb
, j
))
1835 eqn sub
= &(pb
->eqs
[e
]);
1836 int c
= pb
->eqs
[e
].coef
[i
];
1840 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1843 "Found a single wild card equality: ");
1844 omega_print_eq (dump_file
, pb
, &pb
->eqs
[e
]);
1845 fprintf (dump_file
, "\n");
1846 omega_print_problem (dump_file
, pb
);
1849 for (e2
= pb
->num_eqs
- 1; e2
>= 0; e2
--)
1850 if (e
!= e2
&& pb
->eqs
[e2
].coef
[i
]
1851 && (pb
->eqs
[e2
].color
== omega_red
1852 || (pb
->eqs
[e2
].color
== omega_black
1853 && pb
->eqs
[e
].color
== omega_black
)))
1855 eqn eqn
= &(pb
->eqs
[e2
]);
1858 for (var
= n_vars
; var
>= 0; var
--)
1859 eqn
->coef
[var
] *= a
;
1863 for (var
= n_vars
; var
>= 0; var
--)
1864 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1867 divide_eqn_by_gcd (eqn
, n_vars
);
1870 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
1871 if (pb
->geqs
[e2
].coef
[i
]
1872 && (pb
->geqs
[e2
].color
== omega_red
1873 || (pb
->eqs
[e
].color
== omega_black
1874 && pb
->geqs
[e2
].color
== omega_black
)))
1876 eqn eqn
= &(pb
->geqs
[e2
]);
1879 for (var
= n_vars
; var
>= 0; var
--)
1880 eqn
->coef
[var
] *= a
;
1884 for (var
= n_vars
; var
>= 0; var
--)
1885 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1892 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
1893 if (pb
->subs
[e2
].coef
[i
]
1894 && (pb
->subs
[e2
].color
== omega_red
1895 || (pb
->subs
[e2
].color
== omega_black
1896 && pb
->eqs
[e
].color
== omega_black
)))
1898 eqn eqn
= &(pb
->subs
[e2
]);
1901 for (var
= n_vars
; var
>= 0; var
--)
1902 eqn
->coef
[var
] *= a
;
1906 for (var
= n_vars
; var
>= 0; var
--)
1907 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1910 divide_eqn_by_gcd (eqn
, n_vars
);
1913 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1915 fprintf (dump_file
, "cleaned-out wildcard: ");
1916 omega_print_problem (dump_file
, pb
);
1923 normalize_omega_problem (pb
);
1926 /* Swap values contained in I and J. */
1929 swap (int *i
, int *j
)
1937 /* Swap values contained in I and J. */
1940 bswap (bool *i
, bool *j
)
1948 /* Helper function. UNPROTECT might be NULL. */
1951 omega_unprotect_1 (omega_pb pb
, int *idx
, bool *unprotect
)
1953 if (*idx
< pb
->safe_vars
)
1955 int e
, j
= pb
->safe_vars
;
1957 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1959 pb
->geqs
[e
].touched
= 1;
1960 swap (&pb
->geqs
[e
].coef
[*idx
], &pb
->geqs
[e
].coef
[j
]);
1963 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1964 swap (&pb
->eqs
[e
].coef
[*idx
], &pb
->eqs
[e
].coef
[j
]);
1966 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1967 swap (&pb
->subs
[e
].coef
[*idx
], &pb
->subs
[e
].coef
[j
]);
1970 bswap (&unprotect
[*idx
], &unprotect
[j
]);
1972 swap (&pb
->var
[*idx
], &pb
->var
[j
]);
1973 pb
->forwarding_address
[pb
->var
[*idx
]] = *idx
;
1974 pb
->forwarding_address
[pb
->var
[j
]] = j
;
1981 /* During the Fourier-Motzkin elimination some variables are
1982 substituted with other variables. This function resurrects the
1983 substituted variables. */
1986 resurrect_subs (omega_pb pb
)
1988 if (pb
->num_subs
> 0
1989 && please_no_equalities_in_simplified_problems
== 0)
1993 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1996 "problem reduced, bringing variables back to life\n");
1997 omega_print_problem (dump_file
, pb
);
2000 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2001 if (omega_wildcard_p (pb
, i
))
2002 omega_unprotect_1 (pb
, &i
, NULL
);
2005 n
= MAX (pb
->num_vars
, pb
->safe_vars
+ m
);
2007 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2008 if (single_var_geq (&pb
->geqs
[e
], pb
->num_vars
))
2010 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
2011 pb
->geqs
[e
].key
+= (pb
->geqs
[e
].key
> 0 ? m
: -m
);
2015 pb
->geqs
[e
].touched
= 1;
2016 pb
->geqs
[e
].key
= 0;
2019 for (i
= pb
->num_vars
; !omega_safe_var_p (pb
, i
); i
--)
2021 pb
->var
[i
+ m
] = pb
->var
[i
];
2023 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2024 pb
->geqs
[e
].coef
[i
+ m
] = pb
->geqs
[e
].coef
[i
];
2026 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
2027 pb
->eqs
[e
].coef
[i
+ m
] = pb
->eqs
[e
].coef
[i
];
2029 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2030 pb
->subs
[e
].coef
[i
+ m
] = pb
->subs
[e
].coef
[i
];
2033 for (i
= pb
->safe_vars
+ m
; !omega_safe_var_p (pb
, i
); i
--)
2035 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2036 pb
->geqs
[e
].coef
[i
] = 0;
2038 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
2039 pb
->eqs
[e
].coef
[i
] = 0;
2041 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2042 pb
->subs
[e
].coef
[i
] = 0;
2047 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2049 pb
->var
[pb
->safe_vars
+ 1 + e
] = pb
->subs
[e
].key
;
2050 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e
]),
2052 pb
->eqs
[pb
->num_eqs
].coef
[pb
->safe_vars
+ 1 + e
] = -1;
2053 pb
->eqs
[pb
->num_eqs
].color
= omega_black
;
2055 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2057 fprintf (dump_file
, "brought back: ");
2058 omega_print_eq (dump_file
, pb
, &pb
->eqs
[pb
->num_eqs
]);
2059 fprintf (dump_file
, "\n");
2063 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2069 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2071 fprintf (dump_file
, "variables brought back to life\n");
2072 omega_print_problem (dump_file
, pb
);
2075 cleanout_wildcards (pb
);
2080 implies (unsigned int a
, unsigned int b
)
2082 return (a
== (a
& b
));
2085 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2086 extra step is performed. Returns omega_false when there exist no
2087 solution, omega_true otherwise. */
2090 omega_eliminate_redundant (omega_pb pb
, bool expensive
)
2092 int c
, e
, e1
, e2
, e3
, p
, q
, i
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2093 bool *is_dead
= (bool *) xmalloc (OMEGA_MAX_GEQS
* sizeof (bool));
2094 omega_pb tmp_problem
;
2096 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2097 unsigned int *peqs
= (unsigned int *) xmalloc (OMEGA_MAX_GEQS
2098 * sizeof (unsigned int));
2099 unsigned int *zeqs
= (unsigned int *) xmalloc (OMEGA_MAX_GEQS
2100 * sizeof (unsigned int));
2101 unsigned int *neqs
= (unsigned int *) xmalloc (OMEGA_MAX_GEQS
2102 * sizeof (unsigned int));
2104 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2105 unsigned int pp
, pz
, pn
;
2107 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2109 fprintf (dump_file
, "in eliminate Redudant:\n");
2110 omega_print_problem (dump_file
, pb
);
2113 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2118 peqs
[e
] = zeqs
[e
] = neqs
[e
] = 0;
2120 for (i
= pb
->num_vars
; i
>= 1; i
--)
2122 if (pb
->geqs
[e
].coef
[i
] > 0)
2124 else if (pb
->geqs
[e
].coef
[i
] < 0)
2134 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2136 for (e2
= e1
- 1; e2
>= 0; e2
--)
2139 for (p
= pb
->num_vars
; p
> 1; p
--)
2140 for (q
= p
- 1; q
> 0; q
--)
2141 if ((alpha
= pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
]
2142 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]) != 0)
2148 pz
= ((zeqs
[e1
] & zeqs
[e2
]) | (peqs
[e1
] & neqs
[e2
])
2149 | (neqs
[e1
] & peqs
[e2
]));
2150 pp
= peqs
[e1
] | peqs
[e2
];
2151 pn
= neqs
[e1
] | neqs
[e2
];
2153 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2154 if (e3
!= e1
&& e3
!= e2
)
2156 if (!implies (zeqs
[e3
], pz
))
2159 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2160 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2161 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2162 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2165 if (alpha1
* alpha2
<= 0)
2177 /* Trying to prove e3 is redundant. */
2178 if (!implies (peqs
[e3
], pp
)
2179 || !implies (neqs
[e3
], pn
))
2182 if (pb
->geqs
[e3
].color
== omega_black
2183 && (pb
->geqs
[e1
].color
== omega_red
2184 || pb
->geqs
[e2
].color
== omega_red
))
2187 for (k
= pb
->num_vars
; k
>= 1; k
--)
2188 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2189 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2190 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2193 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2194 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2196 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2198 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2201 "found redundant inequality\n");
2203 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2204 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=> ");
2210 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2211 fprintf (dump_file
, "\n\n");
2219 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2220 or trying to prove e3 < 0, and therefore the
2221 problem has no solutions. */
2222 if (!implies (peqs
[e3
], pn
)
2223 || !implies (neqs
[e3
], pp
))
2226 if (pb
->geqs
[e1
].color
== omega_red
2227 || pb
->geqs
[e2
].color
== omega_red
2228 || pb
->geqs
[e3
].color
== omega_red
)
2232 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2233 for (k
= pb
->num_vars
; k
>= 1; k
--)
2234 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2235 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2236 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2239 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2240 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2242 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0]))
2244 /* We just proved e3 < 0, so no solutions exist. */
2245 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2248 "found implied over tight inequality\n");
2250 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2251 alpha1
, alpha2
, -alpha3
);
2252 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2253 fprintf (dump_file
, "\n");
2254 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2255 fprintf (dump_file
, "\n=> not ");
2256 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2257 fprintf (dump_file
, "\n\n");
2261 else if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] - 1))
2263 /* We just proved that e3 <=0, so e3 = 0. */
2264 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2267 "found implied tight inequality\n");
2269 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2270 alpha1
, alpha2
, -alpha3
);
2271 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2272 fprintf (dump_file
, "\n");
2273 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2274 fprintf (dump_file
, "\n=> inverse ");
2275 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2276 fprintf (dump_file
, "\n\n");
2279 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++],
2280 &pb
->geqs
[e3
], pb
->num_vars
);
2281 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2282 adding_equality_constraint (pb
, pb
->num_eqs
- 1);
2290 /* Delete the inequalities that were marked as dead. */
2291 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2293 omega_delete_geq (pb
, e
, pb
->num_vars
);
2296 goto eliminate_redundant_done
;
2298 tmp_problem
= (omega_pb
) xmalloc (sizeof (struct omega_pb
));
2301 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2303 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2306 "checking equation %d to see if it is redundant: ", e
);
2307 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2308 fprintf (dump_file
, "\n");
2311 omega_copy_problem (tmp_problem
, pb
);
2312 omega_negate_geq (tmp_problem
, e
);
2313 tmp_problem
->safe_vars
= 0;
2314 tmp_problem
->variables_freed
= false;
2316 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2317 omega_delete_geq (pb
, e
, pb
->num_vars
);
2323 if (!omega_reduce_with_subs
)
2325 resurrect_subs (pb
);
2326 gcc_assert (please_no_equalities_in_simplified_problems
2327 || pb
->num_subs
== 0);
2330 eliminate_redundant_done
:
2338 /* For each inequality that has coefficients bigger than 20, try to
2339 create a new constraint that cannot be derived from the original
2340 constraint and that has smaller coefficients. Add the new
2341 constraint at the end of geqs. Return the number of inequalities
2342 that have been added to PB. */
2345 smooth_weird_equations (omega_pb pb
)
2347 int e1
, e2
, e3
, p
, q
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2352 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2353 if (pb
->geqs
[e1
].color
== omega_black
)
2357 for (v
= pb
->num_vars
; v
>= 1; v
--)
2358 if (pb
->geqs
[e1
].coef
[v
] != 0 && abs (pb
->geqs
[e1
].coef
[v
]) < g
)
2359 g
= abs (pb
->geqs
[e1
].coef
[v
]);
2366 for (v
= pb
->num_vars
; v
>= 1; v
--)
2367 pb
->geqs
[e3
].coef
[v
] = int_div (6 * pb
->geqs
[e1
].coef
[v
] + g
/ 2,
2370 pb
->geqs
[e3
].color
= omega_black
;
2371 pb
->geqs
[e3
].touched
= 1;
2373 pb
->geqs
[e3
].coef
[0] = 9997;
2375 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2377 fprintf (dump_file
, "Checking to see if we can derive: ");
2378 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2379 fprintf (dump_file
, "\n from: ");
2380 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e1
]);
2381 fprintf (dump_file
, "\n");
2384 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
2385 if (e1
!= e2
&& pb
->geqs
[e2
].color
== omega_black
)
2387 for (p
= pb
->num_vars
; p
> 1; p
--)
2389 for (q
= p
- 1; q
> 0; q
--)
2392 (pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
] -
2393 pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]);
2402 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2403 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2404 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2405 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2408 if (alpha1
* alpha2
<= 0)
2420 /* Try to prove e3 is redundant: verify
2421 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2422 for (k
= pb
->num_vars
; k
>= 1; k
--)
2423 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2424 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2425 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2428 c
= alpha1
* pb
->geqs
[e1
].coef
[0]
2429 + alpha2
* pb
->geqs
[e2
].coef
[0];
2431 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2432 pb
->geqs
[e3
].coef
[0] = int_div (c
, alpha3
);
2437 if (pb
->geqs
[e3
].coef
[0] < 9997)
2442 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2445 "Smoothing wierd equations; adding:\n");
2446 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2447 fprintf (dump_file
, "\nto:\n");
2448 omega_print_problem (dump_file
, pb
);
2449 fprintf (dump_file
, "\n\n");
2457 /* Replace tuples of inequalities, that define upper and lower half
2458 spaces, with an equation. */
2461 coalesce (omega_pb pb
)
2465 bool *is_dead
= (bool *) xmalloc (OMEGA_MAX_GEQS
* sizeof (bool));
2466 int found_something
= 0;
2468 for (e
= 0; e
< pb
->num_geqs
; e
++)
2469 if (pb
->geqs
[e
].color
== omega_red
)
2475 for (e
= 0; e
< pb
->num_geqs
; e
++)
2478 for (e
= 0; e
< pb
->num_geqs
; e
++)
2479 if (pb
->geqs
[e
].color
== omega_red
2480 && !pb
->geqs
[e
].touched
)
2481 for (e2
= e
+ 1; e2
< pb
->num_geqs
; e2
++)
2482 if (!pb
->geqs
[e2
].touched
2483 && pb
->geqs
[e
].key
== -pb
->geqs
[e2
].key
2484 && pb
->geqs
[e
].coef
[0] == -pb
->geqs
[e2
].coef
[0]
2485 && pb
->geqs
[e2
].color
== omega_red
)
2487 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++], &pb
->geqs
[e
],
2489 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2495 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2497 omega_delete_geq (pb
, e
, pb
->num_vars
);
2499 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && found_something
)
2501 fprintf (dump_file
, "Coalesced pb->geqs into %d EQ's:\n",
2503 omega_print_problem (dump_file
, pb
);
2509 /* Eliminate redundant inequalities from PB. When ELIMINATE_ALL is
2510 true, continue to eliminate all redundant inequalities. */
2513 omega_eliminate_red (omega_pb pb
, bool eliminate_all
)
2515 int e
, e2
, e3
, i
, j
, k
, a
, alpha1
, alpha2
;
2517 bool *is_dead
= (bool *) xmalloc (OMEGA_MAX_GEQS
* sizeof (bool));
2520 omega_pb tmp_problem
;
2522 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2524 fprintf (dump_file
, "in eliminate RED:\n");
2525 omega_print_problem (dump_file
, pb
);
2528 if (pb
->num_eqs
> 0)
2529 omega_simplify_problem (pb
);
2531 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2534 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2535 if (pb
->geqs
[e
].color
== omega_black
&& !is_dead
[e
])
2536 for (e2
= e
- 1; e2
>= 0; e2
--)
2537 if (pb
->geqs
[e2
].color
== omega_black
2542 for (i
= pb
->num_vars
; i
> 1; i
--)
2543 for (j
= i
- 1; j
> 0; j
--)
2544 if ((a
= (pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e2
].coef
[j
]
2545 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e
].coef
[j
])) != 0)
2551 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2554 "found two equations to combine, i = %s, ",
2555 omega_variable_to_str (pb
, i
));
2556 fprintf (dump_file
, "j = %s, alpha = %d\n",
2557 omega_variable_to_str (pb
, j
), a
);
2558 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2559 fprintf (dump_file
, "\n");
2560 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2561 fprintf (dump_file
, "\n");
2564 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2565 if (pb
->geqs
[e3
].color
== omega_red
)
2567 alpha1
= (pb
->geqs
[e2
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2568 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2569 alpha2
= -(pb
->geqs
[e
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2570 - pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2572 if ((a
> 0 && alpha1
> 0 && alpha2
> 0)
2573 || (a
< 0 && alpha1
< 0 && alpha2
< 0))
2575 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2578 "alpha1 = %d, alpha2 = %d;"
2579 "comparing against: ",
2581 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2582 fprintf (dump_file
, "\n");
2585 for (k
= pb
->num_vars
; k
>= 0; k
--)
2587 c
= (alpha1
* pb
->geqs
[e
].coef
[k
]
2588 + alpha2
* pb
->geqs
[e2
].coef
[k
]);
2590 if (c
!= a
* pb
->geqs
[e3
].coef
[k
])
2593 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && k
> 0)
2594 fprintf (dump_file
, " %s: %d, %d\n",
2595 omega_variable_to_str (pb
, k
), c
,
2596 a
* pb
->geqs
[e3
].coef
[k
]);
2601 ((a
> 0 && c
< a
* pb
->geqs
[e3
].coef
[k
])
2602 || (a
< 0 && c
> a
* pb
->geqs
[e3
].coef
[k
]))))
2604 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2608 "red equation#%d is dead "
2609 "(%d dead so far, %d remain)\n",
2611 pb
->num_geqs
- dead_count
);
2612 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2613 fprintf (dump_file
, "\n");
2614 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2615 fprintf (dump_file
, "\n");
2616 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2617 fprintf (dump_file
, "\n");
2625 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2627 omega_delete_geq (pb
, e
, pb
->num_vars
);
2631 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2633 fprintf (dump_file
, "in eliminate RED, easy tests done:\n");
2634 omega_print_problem (dump_file
, pb
);
2637 for (red_found
= 0, e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2638 if (pb
->geqs
[e
].color
== omega_red
)
2643 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2644 fprintf (dump_file
, "fast checks worked\n");
2646 if (!omega_reduce_with_subs
)
2647 gcc_assert (please_no_equalities_in_simplified_problems
2648 || pb
->num_subs
== 0);
2653 if (!omega_verify_simplification
)
2655 if (!verify_omega_pb (pb
))
2660 tmp_problem
= (omega_pb
) xmalloc (sizeof (struct omega_pb
));
2662 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2663 if (pb
->geqs
[e
].color
== omega_red
)
2665 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2668 "checking equation %d to see if it is redundant: ", e
);
2669 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2670 fprintf (dump_file
, "\n");
2673 omega_copy_problem (tmp_problem
, pb
);
2674 omega_negate_geq (tmp_problem
, e
);
2675 tmp_problem
->safe_vars
= 0;
2676 tmp_problem
->variables_freed
= false;
2677 tmp_problem
->num_subs
= 0;
2679 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2681 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2682 fprintf (dump_file
, "it is redundant\n");
2683 omega_delete_geq (pb
, e
, pb
->num_vars
);
2687 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2688 fprintf (dump_file
, "it is not redundant\n");
2692 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2693 fprintf (dump_file
, "no need to check other red equations\n");
2701 /* omega_simplify_problem (pb); */
2703 if (!omega_reduce_with_subs
)
2704 gcc_assert (please_no_equalities_in_simplified_problems
2705 || pb
->num_subs
== 0);
2708 /* Transform some wildcard variables to non-safe variables. */
2711 chain_unprotect (omega_pb pb
)
2714 bool *unprotect
= (bool *) xmalloc (OMEGA_MAX_VARS
* sizeof (bool));
2716 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2718 unprotect
[i
] = omega_wildcard_p (pb
, i
);
2720 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2721 if (pb
->subs
[e
].coef
[i
])
2722 unprotect
[i
] = false;
2725 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2727 fprintf (dump_file
, "Doing chain reaction unprotection\n");
2728 omega_print_problem (dump_file
, pb
);
2730 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2732 fprintf (dump_file
, "unprotecting %s\n",
2733 omega_variable_to_str (pb
, i
));
2736 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2738 omega_unprotect_1 (pb
, &i
, unprotect
);
2740 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2742 fprintf (dump_file
, "After chain reactions\n");
2743 omega_print_problem (dump_file
, pb
);
2749 /* Reduce problem PB. */
2752 omega_problem_reduced (omega_pb pb
)
2754 if (omega_verify_simplification
)
2757 if (in_approximate_mode
)
2760 result
= verify_omega_pb (pb
);
2763 if (pb
->num_eqs
> 0)
2768 #ifdef ELIMINATE_REDUNDANT_CONSTRAINTS
2769 if (!omega_eliminate_redundant (pb, 1))
2774 omega_found_reduction
= omega_true
;
2776 if (!please_no_equalities_in_simplified_problems
)
2779 if (omega_reduce_with_subs
|| please_no_equalities_in_simplified_problems
)
2780 chain_unprotect (pb
);
2782 resurrect_subs (pb
);
2784 if (!return_single_result
)
2788 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2789 pb
->forwarding_address
[pb
->var
[i
]] = i
;
2791 for (i
= 0; i
< pb
->num_subs
; i
++)
2792 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
2794 (*omega_when_reduced
) (pb
);
2797 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2799 fprintf (dump_file
, "-------------------------------------------\n");
2800 fprintf (dump_file
, "problem reduced:\n");
2801 omega_print_problem (dump_file
, pb
);
2802 fprintf (dump_file
, "-------------------------------------------\n");
2806 /* Eliminates all the free variables for problem PB, that is all the
2807 variables from FV to PB->NUM_VARS. */
2810 omega_free_eliminations (omega_pb pb
, int fv
)
2812 bool try_again
= true;
2814 int n_vars
= pb
->num_vars
;
2820 for (i
= n_vars
; i
> fv
; i
--)
2822 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2823 if (pb
->geqs
[e
].coef
[i
])
2828 else if (pb
->geqs
[e
].coef
[i
] > 0)
2830 for (e2
= e
- 1; e2
>= 0; e2
--)
2831 if (pb
->geqs
[e2
].coef
[i
] < 0)
2836 for (e2
= e
- 1; e2
>= 0; e2
--)
2837 if (pb
->geqs
[e2
].coef
[i
] > 0)
2844 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2845 if (pb
->subs
[e3
].coef
[i
])
2851 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2852 if (pb
->eqs
[e3
].coef
[i
])
2858 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2859 fprintf (dump_file
, "a free elimination of %s\n",
2860 omega_variable_to_str (pb
, i
));
2864 omega_delete_geq (pb
, e
, n_vars
);
2866 for (e
--; e
>= 0; e
--)
2867 if (pb
->geqs
[e
].coef
[i
])
2868 omega_delete_geq (pb
, e
, n_vars
);
2870 try_again
= (i
< n_vars
);
2873 omega_delete_variable (pb
, i
);
2874 n_vars
= pb
->num_vars
;
2879 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2881 fprintf (dump_file
, "\nafter free eliminations:\n");
2882 omega_print_problem (dump_file
, pb
);
2883 fprintf (dump_file
, "\n");
2887 /* Do free red eliminations. */
2890 free_red_eliminations (omega_pb pb
)
2892 bool try_again
= true;
2894 int n_vars
= pb
->num_vars
;
2895 bool *is_red_var
= (bool *) xmalloc (OMEGA_MAX_VARS
* sizeof (bool));
2896 bool *is_dead_var
= (bool *) xmalloc (OMEGA_MAX_VARS
* sizeof (bool));
2897 bool *is_dead_geq
= (bool *) xmalloc (OMEGA_MAX_GEQS
* sizeof (bool));
2899 for (i
= n_vars
; i
> 0; i
--)
2901 is_red_var
[i
] = false;
2902 is_dead_var
[i
] = false;
2905 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2907 is_dead_geq
[e
] = false;
2909 if (pb
->geqs
[e
].color
== omega_red
)
2910 for (i
= n_vars
; i
> 0; i
--)
2911 if (pb
->geqs
[e
].coef
[i
] != 0)
2912 is_red_var
[i
] = true;
2918 for (i
= n_vars
; i
> 0; i
--)
2919 if (!is_red_var
[i
] && !is_dead_var
[i
])
2921 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2922 if (!is_dead_geq
[e
] && pb
->geqs
[e
].coef
[i
])
2927 else if (pb
->geqs
[e
].coef
[i
] > 0)
2929 for (e2
= e
- 1; e2
>= 0; e2
--)
2930 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] < 0)
2935 for (e2
= e
- 1; e2
>= 0; e2
--)
2936 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] > 0)
2943 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2944 if (pb
->subs
[e3
].coef
[i
])
2950 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2951 if (pb
->eqs
[e3
].coef
[i
])
2957 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2958 fprintf (dump_file
, "a free red elimination of %s\n",
2959 omega_variable_to_str (pb
, i
));
2962 if (pb
->geqs
[e
].coef
[i
])
2963 is_dead_geq
[e
] = true;
2966 is_dead_var
[i
] = true;
2971 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2973 omega_delete_geq (pb
, e
, n_vars
);
2975 for (i
= n_vars
; i
> 0; i
--)
2977 omega_delete_variable (pb
, i
);
2979 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2981 fprintf (dump_file
, "\nafter free red eliminations:\n");
2982 omega_print_problem (dump_file
, pb
);
2983 fprintf (dump_file
, "\n");
2991 /* For equation EQ of the form "0 = EQN", insert in PB two
2992 inequalities "0 <= EQN" and "0 <= -EQN". */
2995 omega_convert_eq_to_geqs (omega_pb pb
, int eq
)
2999 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3000 fprintf (dump_file
, "Converting Eq to Geqs\n");
3002 /* Insert "0 <= EQN". */
3003 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
3004 pb
->geqs
[pb
->num_geqs
].touched
= 1;
3007 /* Insert "0 <= -EQN". */
3008 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
3009 pb
->geqs
[pb
->num_geqs
].touched
= 1;
3011 for (i
= 0; i
<= pb
->num_vars
; i
++)
3012 pb
->geqs
[pb
->num_geqs
].coef
[i
] *= -1;
3016 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3017 omega_print_problem (dump_file
, pb
);
3020 /* Eliminates variable I from PB. */
3023 omega_do_elimination (omega_pb pb
, int e
, int i
)
3025 eqn sub
= omega_alloc_eqns (0, 1);
3027 int n_vars
= pb
->num_vars
;
3029 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3030 fprintf (dump_file
, "eliminating variable %s\n",
3031 omega_variable_to_str (pb
, i
));
3033 omega_copy_eqn (sub
, &pb
->eqs
[e
], pb
->num_vars
);
3036 if (c
== 1 || c
== -1)
3038 if (pb
->eqs
[e
].color
== omega_red
)
3041 omega_substitute_red (pb
, sub
, i
, c
, &fB
);
3043 omega_convert_eq_to_geqs (pb
, e
);
3045 omega_delete_variable (pb
, i
);
3049 omega_substitute (pb
, sub
, i
, c
);
3050 omega_delete_variable (pb
, i
);
3058 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3059 fprintf (dump_file
, "performing non-exact elimination, c = %d\n", c
);
3061 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
3062 if (pb
->eqs
[e
].coef
[i
])
3064 eqn eqn
= &(pb
->eqs
[e
]);
3066 for (j
= n_vars
; j
>= 0; j
--)
3070 eqn
->color
|= sub
->color
;
3071 for (j
= n_vars
; j
>= 0; j
--)
3072 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3075 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3076 if (pb
->geqs
[e
].coef
[i
])
3078 eqn eqn
= &(pb
->geqs
[e
]);
3081 if (sub
->color
== omega_red
)
3082 eqn
->color
= omega_red
;
3084 for (j
= n_vars
; j
>= 0; j
--)
3091 for (j
= n_vars
; j
>= 0; j
--)
3092 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3096 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3097 if (pb
->subs
[e
].coef
[i
])
3099 eqn eqn
= &(pb
->subs
[e
]);
3102 gcc_assert (sub
->color
== omega_black
);
3103 for (j
= n_vars
; j
>= 0; j
--)
3107 for (j
= n_vars
; j
>= 0; j
--)
3108 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3111 if (in_approximate_mode
)
3112 omega_delete_variable (pb
, i
);
3114 omega_convert_eq_to_geqs (pb
, e2
);
3117 omega_free_eqns (sub
, 1);
3120 /* Helper function for printing "sorry, no solution". */
3122 static inline enum omega_result
3123 omega_problem_has_no_solution (void)
3125 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3126 fprintf (dump_file
, "\nequations have no solution \n");
3131 /* Helper function: solve equations one at a time. */
3133 static enum omega_result
3134 omega_solve_eq (omega_pb pb
, enum omega_result desired_res
)
3141 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && pb
->num_eqs
> 0)
3143 fprintf (dump_file
, "\nomega_solve_eq (%d, %d)\n",
3144 desired_res
, may_be_red
);
3145 omega_print_problem (dump_file
, pb
);
3146 fprintf (dump_file
, "\n");
3152 j
= pb
->num_eqs
- 1;
3158 while (i
<= j
&& pb
->eqs
[i
].color
== omega_red
)
3161 while (i
<= j
&& pb
->eqs
[j
].color
== omega_black
)
3167 eq
= omega_alloc_eqns (0, 1);
3168 omega_copy_eqn (eq
, &pb
->eqs
[i
], pb
->num_vars
);
3169 omega_copy_eqn (&pb
->eqs
[i
], &pb
->eqs
[j
], pb
->num_vars
);
3170 omega_copy_eqn (&pb
->eqs
[j
], eq
, pb
->num_vars
);
3171 omega_free_eqns (eq
, 1);
3177 /* Eliminate all EQ equations */
3178 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
3180 eqn eqn
= &(pb
->eqs
[e
]);
3183 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3184 fprintf (dump_file
, "----\n");
3186 for (i
= pb
->num_vars
; i
> 0; i
--)
3192 for (j
= i
- 1; j
> 0; j
--)
3196 /* i is the position of last non-zero coefficient,
3197 g is the coefficient of i,
3198 j is the position of next non-zero coefficient. */
3202 if (eqn
->coef
[0] % g
!= 0)
3203 return omega_problem_has_no_solution ();
3205 eqn
->coef
[0] = eqn
->coef
[0] / g
;
3208 omega_do_elimination (pb
, e
, i
);
3214 if (eqn
->coef
[0] != 0)
3215 return omega_problem_has_no_solution ();
3227 omega_do_elimination (pb
, e
, i
);
3233 bool promotion_possible
=
3234 (omega_safe_var_p (pb
, j
)
3235 && pb
->safe_vars
+ 1 == i
3236 && !omega_eqn_is_red (eqn
, desired_res
)
3237 && !in_approximate_mode
);
3239 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && promotion_possible
)
3240 fprintf (dump_file
, " Promotion possible\n");
3243 if (!omega_safe_var_p (pb
, j
))
3245 for (; g
!= 1 && !omega_safe_var_p (pb
, j
); j
--)
3246 g
= gcd (abs (eqn
->coef
[j
]), g
);
3249 else if (!omega_safe_var_p (pb
, i
))
3254 for (; g
!= 1 && j
> 0; j
--)
3255 g
= gcd (abs (eqn
->coef
[j
]), g
);
3259 if (eqn
->coef
[0] % g
!= 0)
3260 return omega_problem_has_no_solution ();
3262 for (j
= 0; j
<= pb
->num_vars
; j
++)
3272 for (e2
= e
- 1; e2
>= 0; e2
--)
3273 if (pb
->eqs
[e2
].coef
[i
])
3277 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
3278 if (pb
->geqs
[e2
].coef
[i
])
3282 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
3283 if (pb
->subs
[e2
].coef
[i
])
3288 bool change
= false;
3290 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3292 fprintf (dump_file
, "Ha! We own it! \n");
3293 omega_print_eq (dump_file
, pb
, eqn
);
3294 fprintf (dump_file
, " \n");
3300 for (j
= i
- 1; j
>= 0; j
--)
3302 int t
= int_mod (eqn
->coef
[j
], g
);
3307 if (t
!= eqn
->coef
[j
])
3316 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3317 fprintf (dump_file
, "So what?\n");
3322 omega_name_wild_card (pb
, i
);
3324 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3326 omega_print_eq (dump_file
, pb
, eqn
);
3327 fprintf (dump_file
, " \n");
3336 if (promotion_possible
)
3338 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3340 fprintf (dump_file
, "promoting %s to safety\n",
3341 omega_variable_to_str (pb
, i
));
3342 omega_print_vars (dump_file
, pb
);
3347 if (!omega_wildcard_p (pb
, i
))
3348 omega_name_wild_card (pb
, i
);
3350 promotion_possible
= false;
3355 if (g2
> 1 && !in_approximate_mode
)
3357 if (pb
->eqs
[e
].color
== omega_red
)
3359 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3360 fprintf (dump_file
, "handling red equality\n");
3363 omega_do_elimination (pb
, e
, i
);
3367 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3370 "adding equation to handle safe variable \n");
3371 omega_print_eq (dump_file
, pb
, eqn
);
3372 fprintf (dump_file
, "\n----\n");
3373 omega_print_problem (dump_file
, pb
);
3374 fprintf (dump_file
, "\n----\n");
3375 fprintf (dump_file
, "\n----\n");
3378 i
= omega_add_new_wild_card (pb
);
3380 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
3381 omega_init_eqn_zero (&pb
->eqs
[e
+ 1], pb
->num_vars
);
3382 omega_copy_eqn (&pb
->eqs
[e
+ 1], eqn
, pb
->safe_vars
);
3384 for (j
= pb
->num_vars
; j
>= 0; j
--)
3386 pb
->eqs
[e
+ 1].coef
[j
] = int_mod (pb
->eqs
[e
+ 1].coef
[j
], g2
);
3388 if (2 * pb
->eqs
[e
+ 1].coef
[j
] >= g2
)
3389 pb
->eqs
[e
+ 1].coef
[j
] -= g2
;
3392 pb
->eqs
[e
+ 1].coef
[i
] = g2
;
3395 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3396 omega_print_problem (dump_file
, pb
);
3405 /* Find variable to eliminate. */
3408 gcc_assert (in_approximate_mode
);
3410 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3412 fprintf (dump_file
, "non-exact elimination: ");
3413 omega_print_eq (dump_file
, pb
, eqn
);
3414 fprintf (dump_file
, "\n");
3415 omega_print_problem (dump_file
, pb
);
3418 for (i
= pb
->num_vars
; i
> sv
; i
--)
3419 if (pb
->eqs
[e
].coef
[i
] != 0)
3423 for (i
= pb
->num_vars
; i
> sv
; i
--)
3424 if (pb
->eqs
[e
].coef
[i
] == 1 || pb
->eqs
[e
].coef
[i
] == -1)
3430 omega_do_elimination (pb
, e
, i
);
3432 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && g2
> 1)
3434 fprintf (dump_file
, "result of non-exact elimination:\n");
3435 omega_print_problem (dump_file
, pb
);
3440 int factor
= (INT_MAX
);
3443 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3444 fprintf (dump_file
, "doing moding\n");
3446 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3447 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3452 for (; i
!= sv
; i
--)
3453 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3459 if (j
!= 0 && i
== sv
)
3461 omega_do_mod (pb
, 2, e
, j
);
3467 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3468 if (pb
->eqs
[e
].coef
[i
] != 0
3469 && factor
> abs (pb
->eqs
[e
].coef
[i
]) + 1)
3471 factor
= abs (pb
->eqs
[e
].coef
[i
]) + 1;
3477 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3478 fprintf (dump_file
, "should not have happened\n");
3482 omega_do_mod (pb
, factor
, e
, j
);
3483 /* Go back and try this equation again. */
3490 return omega_unknown
;
3495 static enum omega_result
3496 parallel_splinter (omega_pb pb
, int e
, int diff
,
3497 enum omega_result desired_res
)
3499 omega_pb tmp_problem
;
3502 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3504 fprintf (dump_file
, "Using parallel splintering\n");
3505 omega_print_problem (dump_file
, pb
);
3508 tmp_problem
= (omega_pb
) xmalloc (sizeof (struct omega_pb
));
3509 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
], pb
->num_vars
);
3512 for (i
= 0; i
<= diff
; i
++)
3514 omega_copy_problem (tmp_problem
, pb
);
3516 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3518 fprintf (dump_file
, "Splinter # %i\n", i
);
3519 omega_print_problem (dump_file
, pb
);
3522 if (omega_solve_problem (tmp_problem
, desired_res
) == omega_true
)
3528 pb
->eqs
[0].coef
[0]--;
3535 /* Helper function: solve equations one at a time. */
3537 static enum omega_result
3538 omega_solve_geq (omega_pb pb
, enum omega_result desired_res
)
3542 enum omega_result result
;
3543 bool coupled_subscripts
= false;
3544 bool smoothed
= false;
3545 bool eliminate_again
;
3546 bool tried_eliminating_redundant
= false;
3548 if (desired_res
!= omega_simplify
)
3556 gcc_assert (desired_res
== omega_simplify
|| pb
->num_subs
== 0);
3558 /* Verify that there are not too many inequalities. */
3559 gcc_assert (pb
->num_geqs
<= OMEGA_MAX_GEQS
);
3561 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3563 fprintf (dump_file
, "\nomega_solve_geq (%d,%d):\n",
3564 desired_res
, please_no_equalities_in_simplified_problems
);
3565 omega_print_problem (dump_file
, pb
);
3566 fprintf (dump_file
, "\n");
3569 n_vars
= pb
->num_vars
;
3573 enum omega_eqn_color u_color
= omega_black
;
3574 enum omega_eqn_color l_color
= omega_black
;
3575 int upper_bound
= pos_infinity
;
3576 int lower_bound
= neg_infinity
;
3578 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3580 int a
= pb
->geqs
[e
].coef
[1];
3581 int c
= pb
->geqs
[e
].coef
[0];
3583 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3587 return omega_problem_has_no_solution ();
3594 if (lower_bound
< -c
3595 || (lower_bound
== -c
3596 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3599 l_color
= pb
->geqs
[e
].color
;
3605 c
= int_div (c
, -a
);
3608 || (upper_bound
== c
3609 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3612 u_color
= pb
->geqs
[e
].color
;
3617 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3619 fprintf (dump_file
, "upper bound = %d\n", upper_bound
);
3620 fprintf (dump_file
, "lower bound = %d\n", lower_bound
);
3623 if (lower_bound
> upper_bound
)
3624 return omega_problem_has_no_solution ();
3626 if (desired_res
== omega_simplify
)
3629 if (pb
->safe_vars
== 1)
3632 if (lower_bound
== upper_bound
3633 && u_color
== omega_black
3634 && l_color
== omega_black
)
3636 pb
->eqs
[0].coef
[0] = -lower_bound
;
3637 pb
->eqs
[0].coef
[1] = 1;
3638 pb
->eqs
[0].color
= omega_black
;
3640 return omega_solve_problem (pb
, desired_res
);
3644 if (lower_bound
> neg_infinity
)
3646 pb
->geqs
[0].coef
[0] = -lower_bound
;
3647 pb
->geqs
[0].coef
[1] = 1;
3648 pb
->geqs
[0].key
= 1;
3649 pb
->geqs
[0].color
= l_color
;
3650 pb
->geqs
[0].touched
= 0;
3654 if (upper_bound
< pos_infinity
)
3656 pb
->geqs
[pb
->num_geqs
].coef
[0] = upper_bound
;
3657 pb
->geqs
[pb
->num_geqs
].coef
[1] = -1;
3658 pb
->geqs
[pb
->num_geqs
].key
= -1;
3659 pb
->geqs
[pb
->num_geqs
].color
= u_color
;
3660 pb
->geqs
[pb
->num_geqs
].touched
= 0;
3668 omega_problem_reduced (pb
);
3672 if (original_problem
!= no_problem
3673 && l_color
== omega_black
3674 && u_color
== omega_black
3676 && lower_bound
== upper_bound
)
3678 pb
->eqs
[0].coef
[0] = -lower_bound
;
3679 pb
->eqs
[0].coef
[1] = 1;
3681 adding_equality_constraint (pb
, 0);
3687 if (!pb
->variables_freed
)
3689 pb
->variables_freed
= true;
3691 if (desired_res
!= omega_simplify
)
3692 omega_free_eliminations (pb
, 0);
3694 omega_free_eliminations (pb
, pb
->safe_vars
);
3696 n_vars
= pb
->num_vars
;
3702 switch (normalize_omega_problem (pb
))
3704 case normalize_false
:
3708 case normalize_coupled
:
3709 coupled_subscripts
= true;
3712 case normalize_uncoupled
:
3713 coupled_subscripts
= false;
3720 n_vars
= pb
->num_vars
;
3722 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3724 fprintf (dump_file
, "\nafter normalization:\n");
3725 omega_print_problem (dump_file
, pb
);
3726 fprintf (dump_file
, "\n");
3727 fprintf (dump_file
, "eliminating variable using Fourier-Motzkin.\n");
3731 int parallel_difference
= INT_MAX
;
3732 int best_parallel_eqn
= -1;
3733 int minC
, maxC
, minCj
= 0;
3734 int lower_bound_count
= 0;
3736 bool possible_easy_int_solution
;
3737 int max_splinters
= 1;
3739 bool lucky_exact
= false;
3741 int best
= (INT_MAX
);
3742 int j
= 0, jLe
= 0, jLowerBoundCount
= 0;
3745 eliminate_again
= false;
3747 if (pb
->num_eqs
> 0)
3748 return omega_solve_problem (pb
, desired_res
);
3750 if (!coupled_subscripts
)
3752 if (pb
->safe_vars
== 0)
3755 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3756 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
3757 omega_delete_geq (pb
, e
, n_vars
);
3759 pb
->num_vars
= pb
->safe_vars
;
3761 if (desired_res
== omega_simplify
)
3763 omega_problem_reduced (pb
);
3770 if (desired_res
!= omega_simplify
)
3775 if (pb
->num_geqs
== 0)
3777 if (desired_res
== omega_simplify
)
3779 pb
->num_vars
= pb
->safe_vars
;
3780 omega_problem_reduced (pb
);
3786 if (desired_res
== omega_simplify
&& n_vars
== pb
->safe_vars
)
3788 omega_problem_reduced (pb
);
3792 if (pb
->num_geqs
> OMEGA_MAX_GEQS
- 30
3793 || pb
->num_geqs
> 2 * n_vars
* n_vars
+ 4 * n_vars
+ 10)
3795 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3797 "TOO MANY EQUATIONS; "
3798 "%d equations, %d variables, "
3799 "ELIMINATING REDUNDANT ONES\n",
3800 pb
->num_geqs
, n_vars
);
3802 if (!omega_eliminate_redundant (pb
, 0))
3805 n_vars
= pb
->num_vars
;
3807 if (pb
->num_eqs
> 0)
3808 return omega_solve_problem (pb
, desired_res
);
3810 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3811 fprintf (dump_file
, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3814 if (desired_res
!= omega_simplify
)
3819 for (i
= n_vars
; i
!= fv
; i
--)
3825 int upper_bound_count
= 0;
3827 lower_bound_count
= 0;
3830 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3831 if (pb
->geqs
[e
].coef
[i
] < 0)
3833 set_min (&minC
, pb
->geqs
[e
].coef
[i
]);
3834 upper_bound_count
++;
3835 if (pb
->geqs
[e
].coef
[i
] < -1)
3843 else if (pb
->geqs
[e
].coef
[i
] > 0)
3845 set_max (&maxC
, pb
->geqs
[e
].coef
[i
]);
3846 lower_bound_count
++;
3848 if (pb
->geqs
[e
].coef
[i
] > 1)
3857 if (lower_bound_count
== 0 || upper_bound_count
== 0)
3859 lower_bound_count
= 0;
3863 if (ub
>= 0 && lb
>= 0
3864 && pb
->geqs
[lb
].key
== -pb
->geqs
[ub
].key
)
3866 int Lc
= pb
->geqs
[lb
].coef
[i
];
3867 int Uc
= -pb
->geqs
[ub
].coef
[i
];
3869 Lc
* pb
->geqs
[ub
].coef
[0] + Uc
* pb
->geqs
[lb
].coef
[0];
3870 lucky
= (diff
>= (Uc
- 1) * (Lc
- 1));
3873 if (maxC
== 1 || minC
== -1 || lucky
|| APROX
3874 || in_approximate_mode
)
3876 neweqns
= score
= upper_bound_count
* lower_bound_count
;
3878 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3880 "For %s, exact, score = %d*%d, range = %d ... %d, \nlucky = %d, APROX = %d, in_approximate_mode=%d \n",
3881 omega_variable_to_str (pb
, i
),
3883 lower_bound_count
, minC
, maxC
, lucky
, APROX
,
3884 in_approximate_mode
);
3886 if (!exact
|| score
< best
)
3893 jLowerBoundCount
= lower_bound_count
;
3895 lucky_exact
= lucky
;
3902 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3904 "For %s, non-exact, score = %d*%d, range = %d ... %d \n",
3905 omega_variable_to_str (pb
, i
),
3907 lower_bound_count
, minC
, maxC
);
3909 neweqns
= upper_bound_count
* lower_bound_count
;
3910 score
= maxC
- minC
;
3918 jLowerBoundCount
= lower_bound_count
;
3923 if (lower_bound_count
== 0)
3925 omega_free_eliminations (pb
, pb
->safe_vars
);
3926 n_vars
= pb
->num_vars
;
3927 eliminate_again
= true;
3934 lower_bound_count
= jLowerBoundCount
;
3936 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3937 if (pb
->geqs
[e
].coef
[i
] > 0)
3939 if (pb
->geqs
[e
].coef
[i
] == -minC
)
3940 max_splinters
+= -minC
- 1;
3943 check_pos_mul ((pb
->geqs
[e
].coef
[i
] - 1),
3944 (-minC
- 1)) / (-minC
) + 1;
3948 /* Trying to produce exact elimination by finding redundant
3950 if (!exact
&& !tried_eliminating_redundant
)
3952 omega_eliminate_redundant (pb
, 0);
3953 tried_eliminating_redundant
= true;
3954 eliminate_again
= true;
3957 tried_eliminating_redundant
= false;
3960 if (return_single_result
&& desired_res
== omega_simplify
&& !exact
)
3963 omega_problem_reduced (pb
);
3967 /* #ifndef Omega3 */
3968 /* Trying to produce exact elimination by finding redundant
3970 if (!exact
&& !tried_eliminating_redundant
)
3972 omega_eliminate_redundant (pb
, 0);
3973 tried_eliminating_redundant
= true;
3976 tried_eliminating_redundant
= false;
3983 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
3984 if (pb
->geqs
[e1
].color
== omega_black
)
3985 for (e2
= e1
- 1; e2
>= 0; e2
--)
3986 if (pb
->geqs
[e2
].color
== omega_black
3987 && pb
->geqs
[e1
].key
== -pb
->geqs
[e2
].key
3988 && ((pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3989 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3990 / 2 < parallel_difference
))
3992 parallel_difference
=
3993 (pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3994 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3996 best_parallel_eqn
= e1
;
3999 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
4000 && best_parallel_eqn
>= 0)
4003 "Possible parallel projection, diff = %d, in ",
4004 parallel_difference
);
4005 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[best_parallel_eqn
]));
4006 fprintf (dump_file
, "\n");
4007 omega_print_problem (dump_file
, pb
);
4011 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4013 fprintf (dump_file
, "going to eliminate %s, (%d,%d,%d)\n",
4014 omega_variable_to_str (pb
, i
), i
, minC
,
4016 omega_print_problem (dump_file
, pb
);
4019 fprintf (dump_file
, "(a lucky exact elimination)\n");
4022 fprintf (dump_file
, "(an exact elimination)\n");
4024 fprintf (dump_file
, "Max # of splinters = %d\n", max_splinters
);
4027 gcc_assert (max_splinters
>= 1);
4029 if (!exact
&& desired_res
== omega_simplify
&& best_parallel_eqn
>= 0
4030 && parallel_difference
<= max_splinters
)
4031 return parallel_splinter (pb
, best_parallel_eqn
, parallel_difference
,
4039 int j
= pb
->num_vars
;
4041 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4043 fprintf (dump_file
, "Swapping %d and %d\n", i
, j
);
4044 omega_print_problem (dump_file
, pb
);
4047 swap (&pb
->var
[i
], &pb
->var
[j
]);
4049 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4050 if (pb
->geqs
[e
].coef
[i
] != pb
->geqs
[e
].coef
[j
])
4052 pb
->geqs
[e
].touched
= 1;
4053 t
= pb
->geqs
[e
].coef
[i
];
4054 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[j
];
4055 pb
->geqs
[e
].coef
[j
] = t
;
4058 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
4059 if (pb
->subs
[e
].coef
[i
] != pb
->subs
[e
].coef
[j
])
4061 t
= pb
->subs
[e
].coef
[i
];
4062 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[j
];
4063 pb
->subs
[e
].coef
[j
] = t
;
4066 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4068 fprintf (dump_file
, "Swapping complete \n");
4069 omega_print_problem (dump_file
, pb
);
4070 fprintf (dump_file
, "\n");
4076 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4078 fprintf (dump_file
, "No swap needed\n");
4079 omega_print_problem (dump_file
, pb
);
4083 n_vars
= pb
->num_vars
;
4089 int upper_bound
= pos_infinity
;
4090 int lower_bound
= neg_infinity
;
4091 enum omega_eqn_color ub_color
= omega_black
;
4092 enum omega_eqn_color lb_color
= omega_black
;
4093 int topeqn
= pb
->num_geqs
- 1;
4094 int Lc
= pb
->geqs
[Le
].coef
[i
];
4096 for (Le
= topeqn
; Le
>= 0; Le
--)
4097 if ((Lc
= pb
->geqs
[Le
].coef
[i
]) == 0)
4099 if (pb
->geqs
[Le
].coef
[1] == 1)
4101 int constantTerm
= -pb
->geqs
[Le
].coef
[0];
4103 if (constantTerm
> lower_bound
||
4104 (constantTerm
== lower_bound
&&
4105 !omega_eqn_is_red (&pb
->geqs
[Le
], desired_res
)))
4107 lower_bound
= constantTerm
;
4108 lb_color
= pb
->geqs
[Le
].color
;
4111 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4113 if (pb
->geqs
[Le
].color
== omega_black
)
4114 fprintf (dump_file
, " :::=> %s >= %d\n",
4115 omega_variable_to_str (pb
, 1),
4119 " :::=> [%s >= %d]\n",
4120 omega_variable_to_str (pb
, 1),
4126 int constantTerm
= pb
->geqs
[Le
].coef
[0];
4127 if (constantTerm
< upper_bound
||
4128 (constantTerm
== upper_bound
4129 && !omega_eqn_is_red (&pb
->geqs
[Le
],
4132 upper_bound
= constantTerm
;
4133 ub_color
= pb
->geqs
[Le
].color
;
4136 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4138 if (pb
->geqs
[Le
].color
== omega_black
)
4139 fprintf (dump_file
, " :::=> %s <= %d\n",
4140 omega_variable_to_str (pb
, 1),
4144 " :::=> [%s <= %d]\n",
4145 omega_variable_to_str (pb
, 1),
4151 for (Ue
= topeqn
; Ue
>= 0; Ue
--)
4152 if (pb
->geqs
[Ue
].coef
[i
] < 0
4153 && pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4155 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4156 int coefficient
= pb
->geqs
[Ue
].coef
[1] * Lc
4157 + pb
->geqs
[Le
].coef
[1] * Uc
;
4158 int constantTerm
= pb
->geqs
[Ue
].coef
[0] * Lc
4159 + pb
->geqs
[Le
].coef
[0] * Uc
;
4161 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4163 omega_print_geq_extra (dump_file
, pb
,
4165 fprintf (dump_file
, "\n");
4166 omega_print_geq_extra (dump_file
, pb
,
4168 fprintf (dump_file
, "\n");
4171 if (coefficient
> 0)
4173 constantTerm
= -int_div (constantTerm
, coefficient
);
4175 if (constantTerm
> lower_bound
4176 || (constantTerm
== lower_bound
4177 && (desired_res
!= omega_simplify
4178 || (pb
->geqs
[Ue
].color
== omega_black
4179 && pb
->geqs
[Le
].color
== omega_black
))))
4181 lower_bound
= constantTerm
;
4182 lb_color
= (pb
->geqs
[Ue
].color
== omega_red
4183 || pb
->geqs
[Le
].color
== omega_red
)
4184 ? omega_red
: omega_black
;
4187 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4189 if (pb
->geqs
[Ue
].color
== omega_red
4190 || pb
->geqs
[Le
].color
== omega_red
)
4192 " ::=> [%s >= %d]\n",
4193 omega_variable_to_str (pb
, 1),
4198 omega_variable_to_str (pb
, 1),
4204 constantTerm
= int_div (constantTerm
, -coefficient
);
4205 if (constantTerm
< upper_bound
4206 || (constantTerm
== upper_bound
4207 && pb
->geqs
[Ue
].color
== omega_black
4208 && pb
->geqs
[Le
].color
== omega_black
))
4210 upper_bound
= constantTerm
;
4211 ub_color
= (pb
->geqs
[Ue
].color
== omega_red
4212 || pb
->geqs
[Le
].color
== omega_red
)
4213 ? omega_red
: omega_black
;
4217 && (dump_flags
& TDF_DETAILS
))
4219 if (pb
->geqs
[Ue
].color
== omega_red
4220 || pb
->geqs
[Le
].color
== omega_red
)
4222 " ::=> [%s <= %d]\n",
4223 omega_variable_to_str (pb
, 1),
4228 omega_variable_to_str (pb
, 1),
4236 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4238 " therefore, %c%d <= %c%s%c <= %d%c\n",
4239 lb_color
== omega_red
? '[' : ' ', lower_bound
,
4240 (lb_color
== omega_red
&& ub_color
== omega_black
)
4242 omega_variable_to_str (pb
, 1),
4243 (lb_color
== omega_black
&& ub_color
== omega_red
)
4245 upper_bound
, ub_color
== omega_red
? ']' : ' ');
4247 if (lower_bound
> upper_bound
)
4250 if (pb
->safe_vars
== 1)
4252 if (upper_bound
== lower_bound
4253 && !(ub_color
== omega_red
|| lb_color
== omega_red
)
4254 && !please_no_equalities_in_simplified_problems
)
4257 pb
->eqs
[0].coef
[1] = -1;
4258 pb
->eqs
[0].coef
[0] = upper_bound
;
4260 if (ub_color
== omega_red
4261 || lb_color
== omega_red
)
4262 pb
->eqs
[0].color
= omega_red
;
4264 if (desired_res
== omega_simplify
4265 && pb
->eqs
[0].color
== omega_black
)
4266 return omega_solve_problem (pb
, desired_res
);
4269 if (upper_bound
!= pos_infinity
)
4271 pb
->geqs
[0].coef
[1] = -1;
4272 pb
->geqs
[0].coef
[0] = upper_bound
;
4273 pb
->geqs
[0].color
= ub_color
;
4274 pb
->geqs
[0].key
= -1;
4275 pb
->geqs
[0].touched
= 0;
4279 if (lower_bound
!= neg_infinity
)
4281 pb
->geqs
[pb
->num_geqs
].coef
[1] = 1;
4282 pb
->geqs
[pb
->num_geqs
].coef
[0] = -lower_bound
;
4283 pb
->geqs
[pb
->num_geqs
].color
= lb_color
;
4284 pb
->geqs
[pb
->num_geqs
].key
= 1;
4285 pb
->geqs
[pb
->num_geqs
].touched
= 0;
4290 if (desired_res
== omega_simplify
)
4292 omega_problem_reduced (pb
);
4297 if (!conservative
&&
4298 (desired_res
!= omega_simplify
||
4299 (lb_color
== omega_black
&& ub_color
== omega_black
))
4300 && original_problem
!= no_problem
4301 && lower_bound
== upper_bound
)
4303 for (i
= original_problem
->num_vars
; i
>= 0; i
--)
4304 if (original_problem
->var
[i
] == pb
->var
[1])
4310 e
= original_problem
->num_eqs
++;
4311 omega_init_eqn_zero (&original_problem
->eqs
[e
],
4312 original_problem
->num_vars
);
4313 original_problem
->eqs
[e
].coef
[i
] = -1;
4314 original_problem
->eqs
[e
].coef
[0] = upper_bound
;
4316 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4319 "adding equality %d to outer problem\n",
4321 omega_print_problem (dump_file
, original_problem
);
4328 eliminate_again
= true;
4330 if (lower_bound_count
== 1)
4332 eqn lbeqn
= omega_alloc_eqns (0, 1);
4333 int Lc
= pb
->geqs
[Le
].coef
[i
];
4335 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4336 fprintf (dump_file
, "an inplace elimination\n");
4338 omega_copy_eqn (lbeqn
, &pb
->geqs
[Le
], (n_vars
+ 1));
4339 omega_delete_geq_extra (pb
, Le
, n_vars
+ 1);
4341 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4342 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4344 if (lbeqn
->key
== -pb
->geqs
[Ue
].key
)
4345 omega_delete_geq_extra (pb
, Ue
, n_vars
+ 1);
4349 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4350 pb
->geqs
[Ue
].touched
= 1;
4351 eliminate_again
= false;
4353 if (lbeqn
->color
== omega_red
)
4354 pb
->geqs
[Ue
].color
= omega_red
;
4356 for (k
= 0; k
<= n_vars
; k
++)
4357 pb
->geqs
[Ue
].coef
[k
] =
4358 check_mul (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4359 check_mul (lbeqn
->coef
[k
], Uc
);
4361 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4363 omega_print_geq (dump_file
, pb
,
4365 fprintf (dump_file
, "\n");
4370 omega_free_eqns (lbeqn
, 1);
4375 int *dead_eqns
= (int *) xmalloc (OMEGA_MAX_GEQS
* sizeof (int));
4376 bool *is_dead
= (bool *) xmalloc (OMEGA_MAX_GEQS
* sizeof (int));
4378 int top_eqn
= pb
->num_geqs
- 1;
4379 lower_bound_count
--;
4381 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4382 fprintf (dump_file
, "lower bound count = %d\n",
4385 for (Le
= top_eqn
; Le
>= 0; Le
--)
4386 if (pb
->geqs
[Le
].coef
[i
] > 0)
4388 int Lc
= pb
->geqs
[Le
].coef
[i
];
4389 for (Ue
= top_eqn
; Ue
>= 0; Ue
--)
4390 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4392 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4395 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4398 e2
= pb
->num_geqs
++;
4400 e2
= dead_eqns
[--num_dead
];
4402 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4404 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4407 "Le = %d, Ue = %d, gen = %d\n",
4409 omega_print_geq_extra (dump_file
, pb
,
4411 fprintf (dump_file
, "\n");
4412 omega_print_geq_extra (dump_file
, pb
,
4414 fprintf (dump_file
, "\n");
4417 eliminate_again
= false;
4419 for (k
= n_vars
; k
>= 0; k
--)
4420 pb
->geqs
[e2
].coef
[k
] =
4421 check_mul (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4422 check_mul (pb
->geqs
[Le
].coef
[k
], Uc
);
4424 pb
->geqs
[e2
].coef
[n_vars
+ 1] = 0;
4425 pb
->geqs
[e2
].touched
= 1;
4427 if (pb
->geqs
[Ue
].color
== omega_red
4428 || pb
->geqs
[Le
].color
== omega_red
)
4429 pb
->geqs
[e2
].color
= omega_red
;
4431 pb
->geqs
[e2
].color
= omega_black
;
4433 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4435 omega_print_geq (dump_file
, pb
,
4437 fprintf (dump_file
, "\n");
4441 if (lower_bound_count
== 0)
4443 dead_eqns
[num_dead
++] = Ue
;
4445 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4446 fprintf (dump_file
, "Killed %d\n", Ue
);
4450 lower_bound_count
--;
4451 dead_eqns
[num_dead
++] = Le
;
4453 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4454 fprintf (dump_file
, "Killed %d\n", Le
);
4457 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4460 while (num_dead
> 0)
4461 is_dead
[dead_eqns
[--num_dead
]] = true;
4463 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4465 omega_delete_geq_extra (pb
, e
, n_vars
+ 1);
4476 rS
= omega_alloc_problem (0, 0);
4477 iS
= omega_alloc_problem (0, 0);
4479 possible_easy_int_solution
= true;
4481 for (e
= 0; e
< pb
->num_geqs
; e
++)
4482 if (pb
->geqs
[e
].coef
[i
] == 0)
4484 omega_copy_eqn (&(rS
->geqs
[e2
]), &pb
->geqs
[e
],
4486 omega_copy_eqn (&(iS
->geqs
[e2
]), &pb
->geqs
[e
],
4489 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4492 fprintf (dump_file
, "Copying (%d, %d): ", i
,
4493 pb
->geqs
[e
].coef
[i
]);
4494 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
4495 fprintf (dump_file
, "\n");
4496 for (t
= 0; t
<= n_vars
+ 1; t
++)
4497 fprintf (dump_file
, "%d ", pb
->geqs
[e
].coef
[t
]);
4498 fprintf (dump_file
, "\n");
4502 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4505 for (Le
= pb
->num_geqs
- 1; Le
>= 0; Le
--)
4506 if (pb
->geqs
[Le
].coef
[i
] > 0)
4507 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4508 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4511 int Lc
= pb
->geqs
[Le
].coef
[i
];
4512 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4514 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4517 rS
->geqs
[e2
].touched
= iS
->geqs
[e2
].touched
= 1;
4519 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4521 fprintf (dump_file
, "---\n");
4523 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4524 Le
, Lc
, Ue
, Uc
, e2
);
4525 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Le
]);
4526 fprintf (dump_file
, "\n");
4527 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Ue
]);
4528 fprintf (dump_file
, "\n");
4533 for (k
= n_vars
; k
>= 0; k
--)
4534 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4535 pb
->geqs
[Ue
].coef
[k
] + pb
->geqs
[Le
].coef
[k
];
4537 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1);
4541 for (k
= n_vars
; k
>= 0; k
--)
4542 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4543 check_mul (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4544 check_mul (pb
->geqs
[Le
].coef
[k
], Uc
);
4546 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1) * (Lc
- 1);
4549 if (pb
->geqs
[Ue
].color
== omega_red
4550 || pb
->geqs
[Le
].color
== omega_red
)
4551 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_red
;
4553 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_black
;
4555 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4557 omega_print_geq (dump_file
, pb
, &(rS
->geqs
[e2
]));
4558 fprintf (dump_file
, "\n");
4562 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4564 else if (pb
->geqs
[Ue
].coef
[0] * Lc
+
4565 pb
->geqs
[Le
].coef
[0] * Uc
-
4566 (Uc
- 1) * (Lc
- 1) < 0)
4567 possible_easy_int_solution
= false;
4570 iS
->variables_initialized
= rS
->variables_initialized
= true;
4571 iS
->num_vars
= rS
->num_vars
= pb
->num_vars
;
4572 iS
->num_geqs
= rS
->num_geqs
= e2
;
4573 iS
->num_eqs
= rS
->num_eqs
= 0;
4574 iS
->num_subs
= rS
->num_subs
= pb
->num_subs
;
4575 iS
->safe_vars
= rS
->safe_vars
= pb
->safe_vars
;
4577 for (e
= n_vars
; e
>= 0; e
--)
4578 rS
->var
[e
] = pb
->var
[e
];
4580 for (e
= n_vars
; e
>= 0; e
--)
4581 iS
->var
[e
] = pb
->var
[e
];
4583 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
4585 omega_copy_eqn (&(rS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4586 omega_copy_eqn (&(iS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4590 n_vars
= pb
->num_vars
;
4592 if (desired_res
!= omega_true
)
4594 if (original_problem
== no_problem
)
4596 original_problem
= pb
;
4597 result
= omega_solve_geq (rS
, omega_false
);
4598 original_problem
= no_problem
;
4601 result
= omega_solve_geq (rS
, omega_false
);
4603 if (result
== omega_false
)
4610 if (pb
->num_eqs
> 0)
4612 /* An equality constraint must have been found */
4615 return omega_solve_problem (pb
, desired_res
);
4619 if (desired_res
!= omega_false
)
4622 int lower_bounds
= 0;
4623 int *lower_bound
= (int *) xmalloc (OMEGA_MAX_GEQS
* sizeof (int));
4625 if (possible_easy_int_solution
)
4628 result
= omega_solve_geq (iS
, desired_res
);
4631 if (result
!= omega_false
)
4640 if (!exact
&& best_parallel_eqn
>= 0
4641 && parallel_difference
<= max_splinters
)
4646 return parallel_splinter (pb
, best_parallel_eqn
,
4647 parallel_difference
,
4651 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4652 fprintf (dump_file
, "have to do exact analysis\n");
4656 for (e
= 0; e
< pb
->num_geqs
; e
++)
4657 if (pb
->geqs
[e
].coef
[i
] > 1)
4658 lower_bound
[lower_bounds
++] = e
;
4660 /* Sort array LOWER_BOUND. */
4661 for (j
= 0; j
< lower_bounds
; j
++)
4663 int k
, smallest
= j
;
4665 for (k
= j
+ 1; k
< lower_bounds
; k
++)
4666 if (pb
->geqs
[lower_bound
[smallest
]].coef
[i
] >
4667 pb
->geqs
[lower_bound
[k
]].coef
[i
])
4670 k
= lower_bound
[smallest
];
4671 lower_bound
[smallest
] = lower_bound
[j
];
4675 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4677 fprintf (dump_file
, "lower bound coeeficients = ");
4679 for (j
= 0; j
< lower_bounds
; j
++)
4680 fprintf (dump_file
, " %d",
4681 pb
->geqs
[lower_bound
[j
]].coef
[i
]);
4683 fprintf (dump_file
, "\n");
4686 for (j
= 0; j
< lower_bounds
; j
++)
4690 int worst_lower_bound_constant
= -minC
;
4693 max_incr
= (((pb
->geqs
[e
].coef
[i
] - 1) *
4694 (worst_lower_bound_constant
- 1) - 1)
4695 / worst_lower_bound_constant
);
4696 /* max_incr += 2; */
4698 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4700 fprintf (dump_file
, "for equation ");
4701 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
4703 "\ntry decrements from 0 to %d\n",
4705 omega_print_problem (dump_file
, pb
);
4708 if (max_incr
> 50 && !smoothed
4709 && smooth_weird_equations (pb
))
4715 goto solve_geq_start
;
4718 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
],
4720 pb
->eqs
[0].color
= omega_black
;
4721 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
4722 pb
->geqs
[e
].touched
= 1;
4725 for (c
= max_incr
; c
>= 0; c
--)
4727 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4730 "trying next decrement of %d\n",
4732 omega_print_problem (dump_file
, pb
);
4735 omega_copy_problem (rS
, pb
);
4737 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4738 omega_print_problem (dump_file
, rS
);
4740 result
= omega_solve_problem (rS
, desired_res
);
4742 if (result
== omega_true
)
4751 pb
->eqs
[0].coef
[0]--;
4754 if (j
+ 1 < lower_bounds
)
4757 omega_copy_eqn (&pb
->geqs
[e
], &pb
->eqs
[0],
4759 pb
->geqs
[e
].touched
= 1;
4760 pb
->geqs
[e
].color
= omega_black
;
4761 omega_copy_problem (rS
, pb
);
4763 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4765 "exhausted lower bound, "
4766 "checking if still feasible ");
4768 result
= omega_solve_problem (rS
, omega_false
);
4770 if (result
== omega_false
)
4775 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4776 fprintf (dump_file
, "fall-off the end\n");
4788 return omega_unknown
;
4789 } while (eliminate_again
);
4793 /* Because the omega solver is recursive, this counter limits the
4795 static int omega_solve_depth
= 0;
4797 /* Return omega_true when the problem PB has a solution following the
4801 omega_solve_problem (omega_pb pb
, enum omega_result desired_res
)
4803 enum omega_result result
;
4805 gcc_assert (pb
->num_vars
>= pb
->safe_vars
);
4806 omega_solve_depth
++;
4808 if (desired_res
!= omega_simplify
)
4811 if (omega_solve_depth
> 50)
4813 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4815 fprintf (dump_file
, "Solve depth = %d, inApprox = %d, aborting\n",
4816 omega_solve_depth
, in_approximate_mode
);
4817 omega_print_problem (dump_file
, pb
);
4824 do_it_again
= false;
4826 if (omega_solve_eq (pb
, desired_res
) == omega_false
)
4828 omega_solve_depth
--;
4832 if (in_approximate_mode
&& !pb
->num_geqs
)
4834 result
= omega_true
;
4835 pb
->num_vars
= pb
->safe_vars
;
4836 omega_problem_reduced (pb
);
4840 result
= omega_solve_geq (pb
, desired_res
);
4841 } while (do_it_again
&& desired_res
== omega_simplify
);
4843 omega_solve_depth
--;
4845 if (!omega_reduce_with_subs
)
4847 resurrect_subs (pb
);
4848 gcc_assert (please_no_equalities_in_simplified_problems
4849 || !result
|| pb
->num_subs
== 0);
4855 /* Return true if red equations constrain the set of possible solutions.
4856 We assume that there are solutions to the black equations by
4857 themselves, so if there is no solution to the combined problem, we
4861 omega_problem_has_red_equations (omega_pb pb
)
4867 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4869 fprintf (dump_file
, "Checking for red equations:\n");
4870 omega_print_problem (dump_file
, pb
);
4873 please_no_equalities_in_simplified_problems
++;
4876 #ifndef SINGLE_RESULT
4877 return_single_result
++;
4880 create_color
= true;
4881 result
= (omega_simplify_problem (pb
) == omega_false
);
4883 #ifndef SINGLE_RESULT
4884 return_single_result
--;
4888 please_no_equalities_in_simplified_problems
--;
4892 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4893 fprintf (dump_file
, "Gist is FALSE\n");
4898 pb
->eqs
[0].color
= omega_red
;
4900 for (i
= pb
->num_vars
; i
> 0; i
--)
4901 pb
->eqs
[0].coef
[i
] = 0;
4903 pb
->eqs
[0].coef
[0] = 1;
4907 free_red_eliminations (pb
);
4908 gcc_assert (pb
->num_eqs
== 0);
4910 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4911 if (pb
->geqs
[e
].color
== omega_red
)
4917 for (i
= pb
->safe_vars
; i
>= 1; i
--)
4922 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4924 if (pb
->geqs
[e
].coef
[i
])
4926 if (pb
->geqs
[e
].coef
[i
] > 0)
4927 lb
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4930 ub
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4934 if (ub
== 2 || lb
== 2)
4937 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4938 fprintf (dump_file
, "checks for upper/lower bounds worked!\n");
4940 if (!omega_reduce_with_subs
)
4942 resurrect_subs (pb
);
4943 gcc_assert (pb
->num_subs
== 0);
4951 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4953 "*** Doing potentially expensive elimination tests "
4954 "for red equations\n");
4956 please_no_equalities_in_simplified_problems
++;
4957 omega_eliminate_red (pb
, 1);
4958 please_no_equalities_in_simplified_problems
--;
4961 gcc_assert (pb
->num_eqs
== 0);
4963 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4964 if (pb
->geqs
[e
].color
== omega_red
)
4967 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4971 "******************** Redudant Red Equations eliminated!!\n");
4974 "******************** Red Equations remain\n");
4976 omega_print_problem (dump_file
, pb
);
4979 if (!omega_reduce_with_subs
)
4981 normalize_return_type r
;
4983 resurrect_subs (pb
);
4984 r
= normalize_omega_problem (pb
);
4985 gcc_assert (r
!= normalize_false
);
4988 cleanout_wildcards (pb
);
4989 gcc_assert (pb
->num_subs
== 0);
4995 /* Calls omega_simplify_problem in approximate mode. */
4998 omega_simplify_approximate (omega_pb pb
)
5000 enum omega_result result
;
5002 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5003 fprintf (dump_file
, "(Entering approximate mode\n");
5005 in_approximate_mode
= true;
5006 result
= omega_simplify_problem (pb
);
5007 in_approximate_mode
= false;
5009 gcc_assert (pb
->num_vars
== pb
->safe_vars
);
5010 if (!omega_reduce_with_subs
)
5011 gcc_assert (pb
->num_subs
== 0);
5013 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5014 fprintf (dump_file
, "Leaving approximate mode)\n");
5019 /* Simplifies problem PB by eliminating redundant constraints and
5020 reducing the constraints system to a minimal form. Returns
5021 omega_true when the problem was successfully reduced, omega_unknown
5022 when the solver is unable to determine an answer. */
5025 omega_simplify_problem (omega_pb pb
)
5028 omega_found_reduction
= omega_false
;
5030 if (!pb
->variables_initialized
)
5031 omega_initialize_variables (pb
);
5034 #ifdef clearForwardingPointers
5035 for (i = 1; i <= pb->num_vars; i++)
5036 if (!omega_wildcard_p (pb, i))
5037 pb->forwarding_address[pb->var[i]] = 0;
5041 if (next_key
* 3 > MAX_KEYS
)
5046 next_key
= OMEGA_MAX_VARS
+ 1;
5048 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5049 pb
->geqs
[e
].touched
= 1;
5051 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
5052 hash_master
[i
].touched
= -1;
5054 pb
->hash_version
= hash_version
;
5057 else if (pb
->hash_version
!= hash_version
)
5061 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5062 pb
->geqs
[e
].touched
= 1;
5064 pb
->hash_version
= hash_version
;
5069 if (pb
->num_vars
> pb
->num_eqs
+ 3 * pb
->safe_vars
)
5070 omega_free_eliminations (pb
, pb
->safe_vars
);
5072 if (!may_be_red
&& pb
->num_subs
== 0 && pb
->safe_vars
== 0)
5074 omega_found_reduction
= omega_solve_problem (pb
, omega_unknown
);
5076 if (omega_found_reduction
!= omega_false
5077 && !return_single_result
)
5081 (*omega_when_reduced
) (pb
);
5084 return omega_found_reduction
;
5087 omega_solve_problem (pb
, omega_simplify
);
5089 if (omega_found_reduction
!= omega_false
)
5091 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
5092 pb
->forwarding_address
[pb
->var
[i
]] = i
;
5094 for (i
= 0; i
< pb
->num_subs
; i
++)
5095 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
5098 if (!omega_reduce_with_subs
)
5099 gcc_assert (please_no_equalities_in_simplified_problems
5100 || omega_found_reduction
== omega_false
5101 || pb
->num_subs
== 0);
5103 return omega_found_reduction
;
5106 /* Make variable VAR unprotected: it then can be eliminated. */
5109 omega_unprotect_variable (omega_pb pb
, int var
)
5112 idx
= pb
->forwarding_address
[var
];
5119 if (idx
< pb
->num_subs
)
5121 omega_copy_eqn (&pb
->subs
[idx
], &pb
->subs
[pb
->num_subs
],
5123 pb
->forwarding_address
[pb
->subs
[idx
].key
] = -idx
- 1;
5128 int *bring_to_life
= (int *) xmalloc (OMEGA_MAX_VARS
* sizeof (int));
5131 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5132 bring_to_life
[e
] = (pb
->subs
[e
].coef
[idx
] != 0);
5134 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
5135 if (bring_to_life
[e2
])
5140 if (pb
->safe_vars
< pb
->num_vars
)
5142 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5144 pb
->geqs
[e
].coef
[pb
->num_vars
] =
5145 pb
->geqs
[e
].coef
[pb
->safe_vars
];
5147 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5150 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5152 pb
->eqs
[e
].coef
[pb
->num_vars
] =
5153 pb
->eqs
[e
].coef
[pb
->safe_vars
];
5155 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5158 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5160 pb
->subs
[e
].coef
[pb
->num_vars
] =
5161 pb
->subs
[e
].coef
[pb
->safe_vars
];
5163 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5166 pb
->var
[pb
->num_vars
] = pb
->var
[pb
->safe_vars
];
5167 pb
->forwarding_address
[pb
->var
[pb
->num_vars
]] =
5172 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5173 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5175 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5176 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5178 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5179 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5182 pb
->var
[pb
->safe_vars
] = pb
->subs
[e2
].key
;
5183 pb
->forwarding_address
[pb
->subs
[e2
].key
] = pb
->safe_vars
;
5185 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e2
]),
5187 pb
->eqs
[pb
->num_eqs
++].coef
[pb
->safe_vars
] = -1;
5188 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5190 if (e2
< pb
->num_subs
- 1)
5191 omega_copy_eqn (&(pb
->subs
[e2
]), &(pb
->subs
[pb
->num_subs
- 1]),
5197 omega_unprotect_1 (pb
, &idx
, NULL
);
5198 free (bring_to_life
);
5201 chain_unprotect (pb
);
5204 /* Unprotects VAR and simplifies PB. */
5207 omega_constrain_variable_sign (omega_pb pb
, enum omega_eqn_color color
,
5210 int n_vars
= pb
->num_vars
;
5213 k
= pb
->forwarding_address
[var
];
5221 omega_copy_eqn (&pb
->geqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5223 for (j
= 0; j
<= n_vars
; j
++)
5224 pb
->geqs
[e
].coef
[j
] *= sign
;
5226 pb
->geqs
[e
].coef
[0]--;
5227 pb
->geqs
[e
].touched
= 1;
5228 pb
->geqs
[e
].color
= color
;
5233 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5234 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5235 pb
->eqs
[e
].color
= color
;
5241 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
5242 pb
->geqs
[e
].coef
[k
] = sign
;
5243 pb
->geqs
[e
].coef
[0] = -1;
5244 pb
->geqs
[e
].touched
= 1;
5245 pb
->geqs
[e
].color
= color
;
5250 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5251 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5252 pb
->eqs
[e
].coef
[k
] = 1;
5253 pb
->eqs
[e
].color
= color
;
5256 omega_unprotect_variable (pb
, var
);
5257 return omega_simplify_problem (pb
);
5260 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5263 omega_constrain_variable_value (omega_pb pb
, enum omega_eqn_color color
,
5267 int k
= pb
->forwarding_address
[var
];
5273 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5274 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5275 pb
->eqs
[e
].coef
[0] -= value
;
5280 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5281 pb
->eqs
[e
].coef
[k
] = 1;
5282 pb
->eqs
[e
].coef
[0] = -value
;
5285 pb
->eqs
[e
].color
= color
;
5288 /* Return true when the . Initialize the bounds LOWER_BOUND and UPPER_BOUND for
5289 the values of variable I. */
5292 omega_query_variable (omega_pb pb
, int i
, int *lower_bound
, int *upper_bound
)
5294 int n_vars
= pb
->num_vars
;
5297 bool coupled
= false;
5299 *lower_bound
= neg_infinity
;
5300 *upper_bound
= pos_infinity
;
5301 i
= pb
->forwarding_address
[i
];
5307 for (j
= 1; j
<= n_vars
; j
++)
5308 if (pb
->subs
[i
].coef
[j
] != 0)
5311 *upper_bound
= *lower_bound
= pb
->subs
[i
].coef
[0];
5315 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5316 if (pb
->subs
[e
].coef
[i
] != 0)
5319 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5320 if (pb
->eqs
[e
].coef
[i
] != 0)
5324 for (j
= 1; j
<= n_vars
; j
++)
5325 if (i
!= j
&& pb
->eqs
[e
].coef
[j
] != 0)
5336 *lower_bound
= *upper_bound
=
5337 -pb
->eqs
[e
].coef
[i
] * pb
->eqs
[e
].coef
[0];
5342 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5343 if (pb
->geqs
[e
].coef
[i
] != 0)
5345 if (pb
->geqs
[e
].key
== i
)
5346 set_max (lower_bound
, -pb
->geqs
[e
].coef
[0]);
5348 else if (pb
->geqs
[e
].key
== -i
)
5349 set_min (upper_bound
, pb
->geqs
[e
].coef
[0]);
5358 /* Sets the lower bound L and upper bound U for the values of variable
5359 I, and sets COULD_BE_ZERO to true if variable I might take value
5360 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5364 query_coupled_variable (omega_pb pb
, int i
, int *l
, int *u
,
5365 bool *could_be_zero
, int lower_bound
, int upper_bound
)
5372 /* Preconditions. */
5373 gcc_assert (abs (pb
->forwarding_address
[i
]) == 1
5374 && pb
->num_vars
+ pb
->num_subs
== 2
5375 && pb
->num_eqs
+ pb
->num_subs
== 1);
5377 /* Define variable I in terms of variable V. */
5378 if (pb
->forwarding_address
[i
] == -1)
5387 sign
= -eqn
->coef
[1];
5391 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5392 if (pb
->geqs
[e
].coef
[v
] != 0)
5394 if (pb
->geqs
[e
].coef
[v
] == 1)
5395 set_max (&lower_bound
, -pb
->geqs
[e
].coef
[0]);
5398 set_min (&upper_bound
, pb
->geqs
[e
].coef
[0]);
5401 if (lower_bound
> upper_bound
)
5409 if (lower_bound
== neg_infinity
)
5411 if (eqn
->coef
[v
] > 0)
5412 b1
= sign
* neg_infinity
;
5415 b1
= -sign
* neg_infinity
;
5418 b1
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * lower_bound
);
5420 if (upper_bound
== pos_infinity
)
5422 if (eqn
->coef
[v
] > 0)
5423 b2
= sign
* pos_infinity
;
5426 b2
= -sign
* pos_infinity
;
5429 b2
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * upper_bound
);
5431 set_max (l
, b1
<= b2
? b1
: b2
);
5432 set_min (u
, b1
<= b2
? b2
: b1
);
5434 *could_be_zero
= (*l
<= 0 && 0 <= *u
5435 && int_mod (eqn
->coef
[0], abs (eqn
->coef
[v
])) == 0);
5438 /* Return false when a lower bound L and an upper bound U for variable
5439 I in problem PB have been initialized. */
5442 omega_query_variable_bounds (omega_pb pb
, int i
, int *l
, int *u
)
5447 if (!omega_query_variable (pb
, i
, l
, u
)
5448 || (pb
->num_vars
== 1 && pb
->forwarding_address
[i
] == 1))
5451 if (abs (pb
->forwarding_address
[i
]) == 1
5452 && pb
->num_vars
+ pb
->num_subs
== 2
5453 && pb
->num_eqs
+ pb
->num_subs
== 1)
5456 query_coupled_variable (pb
, i
, l
, u
, &could_be_zero
, neg_infinity
,
5464 /* For problem PB, return an integer that represents the classic data
5465 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5466 masks that are added to the result. When DIST_KNOWN is true, DIST
5467 is set to the classic data dependence distance. LOWER_BOUND and
5468 UPPER_BOUND are bounds on the value of variable I, for example, it
5469 is possible to narrow the iteration domain with safe approximations
5470 of loop counts, and thus discard some data dependences that cannot
5474 omega_query_variable_signs (omega_pb pb
, int i
, int dd_lt
,
5475 int dd_eq
, int dd_gt
, int lower_bound
,
5476 int upper_bound
, bool *dist_known
, int *dist
)
5485 omega_query_variable (pb
, i
, &l
, &u
);
5486 query_coupled_variable (pb
, i
, &l
, &u
, &could_be_zero
, lower_bound
,
5505 *dist_known
= false;
5510 /* Keeps the state of the initialization. */
5511 static bool omega_initialized
= false;
5513 /* Initialization of the Omega solver. */
5516 omega_initialize (void)
5520 if (omega_initialized
)
5524 next_key
= OMEGA_MAX_VARS
+ 1;
5525 packing
= (int *) (xcalloc (OMEGA_MAX_VARS
, sizeof (int)));
5526 fast_lookup
= (int *) (xcalloc (MAX_KEYS
* 2, sizeof (int)));
5527 fast_lookup_red
= (int *) (xcalloc (MAX_KEYS
* 2, sizeof (int)));
5528 hash_master
= omega_alloc_eqns (0, HASH_TABLE_SIZE
);
5530 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
5531 hash_master
[i
].touched
= -1;
5533 sprintf (wild_name
[0], "1");
5534 sprintf (wild_name
[1], "a");
5535 sprintf (wild_name
[2], "b");
5536 sprintf (wild_name
[3], "c");
5537 sprintf (wild_name
[4], "d");
5538 sprintf (wild_name
[5], "e");
5539 sprintf (wild_name
[6], "f");
5540 sprintf (wild_name
[7], "g");
5541 sprintf (wild_name
[8], "h");
5542 sprintf (wild_name
[9], "i");
5543 sprintf (wild_name
[10], "j");
5544 sprintf (wild_name
[11], "k");
5545 sprintf (wild_name
[12], "l");
5546 sprintf (wild_name
[13], "m");
5547 sprintf (wild_name
[14], "n");
5548 sprintf (wild_name
[15], "o");
5549 sprintf (wild_name
[16], "p");
5550 sprintf (wild_name
[17], "q");
5551 sprintf (wild_name
[18], "r");
5552 sprintf (wild_name
[19], "s");
5553 sprintf (wild_name
[20], "t");
5554 sprintf (wild_name
[40 - 1], "alpha");
5555 sprintf (wild_name
[40 - 2], "beta");
5556 sprintf (wild_name
[40 - 3], "gamma");
5557 sprintf (wild_name
[40 - 4], "delta");
5558 sprintf (wild_name
[40 - 5], "tau");
5559 sprintf (wild_name
[40 - 6], "sigma");
5560 sprintf (wild_name
[40 - 7], "chi");
5561 sprintf (wild_name
[40 - 8], "omega");
5562 sprintf (wild_name
[40 - 9], "pi");
5563 sprintf (wild_name
[40 - 10], "ni");
5564 sprintf (wild_name
[40 - 11], "Alpha");
5565 sprintf (wild_name
[40 - 12], "Beta");
5566 sprintf (wild_name
[40 - 13], "Gamma");
5567 sprintf (wild_name
[40 - 14], "Delta");
5568 sprintf (wild_name
[40 - 15], "Tau");
5569 sprintf (wild_name
[40 - 16], "Sigma");
5570 sprintf (wild_name
[40 - 17], "Chi");
5571 sprintf (wild_name
[40 - 18], "Omega");
5572 sprintf (wild_name
[40 - 19], "xxx");
5574 omega_initialized
= true;