1 /* Source code for an implementation of the Omega test, an integer
2 programming algorithm for dependence analysis, by William Pugh,
3 appeared in Supercomputing '91 and CACM Aug 92.
5 This code has no license restrictions, and is considered public
8 Changes copyright (C) 2005-2015 Free Software Foundation, Inc.
9 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
11 This file is part of GCC.
13 GCC is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free
15 Software Foundation; either version 3, or (at your option) any later
18 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
19 WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 You should have received a copy of the GNU General Public License
24 along with GCC; see the file COPYING3. If not see
25 <http://www.gnu.org/licenses/>. */
27 /* For a detailed description, see "Constraint-Based Array Dependence
28 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
30 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
35 #include "coretypes.h"
39 #include "diagnostic-core.h"
43 /* When set to true, keep substitution variables. When set to false,
44 resurrect substitution variables (convert substitutions back to EQs). */
45 static bool omega_reduce_with_subs
= true;
47 /* When set to true, omega_simplify_problem checks for problem with no
48 solutions, calling verify_omega_pb. */
49 static bool omega_verify_simplification
= false;
51 /* When set to true, only produce a single simplified result. */
52 static bool omega_single_result
= false;
54 /* Set return_single_result to 1 when omega_single_result is true. */
55 static int return_single_result
= 0;
57 /* Hash table for equations generated by the solver. */
58 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
59 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
60 static eqn hash_master
;
62 static int hash_version
= 0;
64 /* Set to true for making the solver enter in approximation mode. */
65 static bool in_approximate_mode
= false;
67 /* When set to zero, the solver is allowed to add new equalities to
68 the problem to be solved. */
69 static int conservative
= 0;
71 /* Set to omega_true when the problem was successfully reduced, set to
72 omega_unknown when the solver is unable to determine an answer. */
73 static enum omega_result omega_found_reduction
;
75 /* Set to true when the solver is allowed to add omega_red equations. */
76 static bool create_color
= false;
78 /* Set to nonzero when the problem to be solved can be reduced. */
79 static int may_be_red
= 0;
81 /* When false, there should be no substitution equations in the
82 simplified problem. */
83 static int please_no_equalities_in_simplified_problems
= 0;
85 /* Variables names for pretty printing. */
86 static char wild_name
[200][40];
88 /* Pointer to the void problem. */
89 static omega_pb no_problem
= (omega_pb
) 0;
91 /* Pointer to the problem to be solved. */
92 static omega_pb original_problem
= (omega_pb
) 0;
95 /* Return the integer A divided by B. */
98 int_div (int a
, int b
)
103 return -((-a
+ b
- 1)/b
);
106 /* Return the integer A modulo B. */
109 int_mod (int a
, int b
)
111 return a
- b
* int_div (a
, b
);
114 /* Test whether equation E is red. */
117 omega_eqn_is_red (eqn e
, int desired_res
)
119 return (desired_res
== omega_simplify
&& e
->color
== omega_red
);
122 /* Return a string for VARIABLE. */
125 omega_var_to_str (int variable
)
127 if (0 <= variable
&& variable
<= 20)
128 return wild_name
[variable
];
130 if (-20 < variable
&& variable
< 0)
131 return wild_name
[40 + variable
];
133 /* Collapse all the entries that would have overflowed. */
134 return wild_name
[21];
137 /* Return a string for variable I in problem PB. */
140 omega_variable_to_str (omega_pb pb
, int i
)
142 return omega_var_to_str (pb
->var
[i
]);
145 /* Do nothing function: used for default initializations. */
148 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED
)
152 void (*omega_when_reduced
) (omega_pb
) = omega_no_procedure
;
154 /* Print to FILE from PB equation E with all its coefficients
158 omega_print_term (FILE *file
, omega_pb pb
, eqn e
, int c
)
162 int n
= pb
->num_vars
;
165 for (i
= 1; i
<= n
; i
++)
166 if (c
* e
->coef
[i
] > 0)
171 if (c
* e
->coef
[i
] == 1)
172 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
174 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
175 omega_variable_to_str (pb
, i
));
179 for (i
= 1; i
<= n
; i
++)
180 if (i
!= went_first
&& c
* e
->coef
[i
] != 0)
182 if (!first
&& c
* e
->coef
[i
] > 0)
183 fprintf (file
, " + ");
187 if (c
* e
->coef
[i
] == 1)
188 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
189 else if (c
* e
->coef
[i
] == -1)
190 fprintf (file
, " - %s", omega_variable_to_str (pb
, i
));
192 fprintf (file
, "%d * %s", c
* e
->coef
[i
],
193 omega_variable_to_str (pb
, i
));
196 if (!first
&& c
* e
->coef
[0] > 0)
197 fprintf (file
, " + ");
199 if (first
|| c
* e
->coef
[0] != 0)
200 fprintf (file
, "%d", c
* e
->coef
[0]);
203 /* Print to FILE the equation E of problem PB. */
206 omega_print_eqn (FILE *file
, omega_pb pb
, eqn e
, bool test
, int extra
)
209 int n
= pb
->num_vars
+ extra
;
210 bool is_lt
= test
&& e
->coef
[0] == -1;
218 else if (e
->key
!= 0)
219 fprintf (file
, "%d: ", e
->key
);
222 if (e
->color
== omega_red
)
227 for (i
= is_lt
? 1 : 0; i
<= n
; i
++)
231 fprintf (file
, " + ");
236 fprintf (file
, "%d", -e
->coef
[i
]);
237 else if (e
->coef
[i
] == -1)
238 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
240 fprintf (file
, "%d * %s", -e
->coef
[i
],
241 omega_variable_to_str (pb
, i
));
256 fprintf (file
, " = ");
258 fprintf (file
, " < ");
260 fprintf (file
, " <= ");
264 for (i
= 0; i
<= n
; i
++)
268 fprintf (file
, " + ");
273 fprintf (file
, "%d", e
->coef
[i
]);
274 else if (e
->coef
[i
] == 1)
275 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
277 fprintf (file
, "%d * %s", e
->coef
[i
],
278 omega_variable_to_str (pb
, i
));
284 if (e
->color
== omega_red
)
288 /* Print to FILE all the variables of problem PB. */
291 omega_print_vars (FILE *file
, omega_pb pb
)
295 fprintf (file
, "variables = ");
297 if (pb
->safe_vars
> 0)
298 fprintf (file
, "protected (");
300 for (i
= 1; i
<= pb
->num_vars
; i
++)
302 fprintf (file
, "%s", omega_variable_to_str (pb
, i
));
304 if (i
== pb
->safe_vars
)
307 if (i
< pb
->num_vars
)
308 fprintf (file
, ", ");
311 fprintf (file
, "\n");
314 /* Dump problem PB. */
317 debug (omega_pb_d
&ref
)
319 omega_print_problem (stderr
, &ref
);
323 debug (omega_pb_d
*ptr
)
328 fprintf (stderr
, "<nil>\n");
331 /* Debug problem PB. */
334 debug_omega_problem (omega_pb pb
)
336 omega_print_problem (stderr
, pb
);
339 /* Print to FILE problem PB. */
342 omega_print_problem (FILE *file
, omega_pb pb
)
346 if (!pb
->variables_initialized
)
347 omega_initialize_variables (pb
);
349 omega_print_vars (file
, pb
);
351 for (e
= 0; e
< pb
->num_eqs
; e
++)
353 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
354 fprintf (file
, "\n");
357 fprintf (file
, "Done with EQ\n");
359 for (e
= 0; e
< pb
->num_geqs
; e
++)
361 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
362 fprintf (file
, "\n");
365 fprintf (file
, "Done with GEQ\n");
367 for (e
= 0; e
< pb
->num_subs
; e
++)
369 eqn eq
= &pb
->subs
[e
];
371 if (eq
->color
== omega_red
)
375 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
377 fprintf (file
, "#%d := ", eq
->key
);
379 omega_print_term (file
, pb
, eq
, 1);
381 if (eq
->color
== omega_red
)
384 fprintf (file
, "\n");
388 /* Return the number of equations in PB tagged omega_red. */
391 omega_count_red_equations (omega_pb pb
)
396 for (e
= 0; e
< pb
->num_eqs
; e
++)
397 if (pb
->eqs
[e
].color
== omega_red
)
399 for (i
= pb
->num_vars
; i
> 0; i
--)
400 if (pb
->geqs
[e
].coef
[i
])
403 if (i
== 0 && pb
->geqs
[e
].coef
[0] == 1)
409 for (e
= 0; e
< pb
->num_geqs
; e
++)
410 if (pb
->geqs
[e
].color
== omega_red
)
413 for (e
= 0; e
< pb
->num_subs
; e
++)
414 if (pb
->subs
[e
].color
== omega_red
)
420 /* Print to FILE all the equations in PB that are tagged omega_red. */
423 omega_print_red_equations (FILE *file
, omega_pb pb
)
427 if (!pb
->variables_initialized
)
428 omega_initialize_variables (pb
);
430 omega_print_vars (file
, pb
);
432 for (e
= 0; e
< pb
->num_eqs
; e
++)
433 if (pb
->eqs
[e
].color
== omega_red
)
435 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
436 fprintf (file
, "\n");
439 for (e
= 0; e
< pb
->num_geqs
; e
++)
440 if (pb
->geqs
[e
].color
== omega_red
)
442 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
443 fprintf (file
, "\n");
446 for (e
= 0; e
< pb
->num_subs
; e
++)
447 if (pb
->subs
[e
].color
== omega_red
)
449 eqn eq
= &pb
->subs
[e
];
453 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
455 fprintf (file
, "#%d := ", eq
->key
);
457 omega_print_term (file
, pb
, eq
, 1);
458 fprintf (file
, "]\n");
462 /* Pretty print PB to FILE. */
465 omega_pretty_print_problem (FILE *file
, omega_pb pb
)
467 int e
, v
, v1
, v2
, v3
, t
;
468 bool *live
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
469 int stuffPrinted
= 0;
474 } partial_order_type
;
476 partial_order_type
**po
= XNEWVEC (partial_order_type
*,
477 OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
478 int **po_eq
= XNEWVEC (int *, OMEGA_MAX_VARS
* OMEGA_MAX_VARS
);
479 int *last_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
480 int *first_links
= XNEWVEC (int, OMEGA_MAX_VARS
);
481 int *chain_length
= XNEWVEC (int, OMEGA_MAX_VARS
);
482 int *chain
= XNEWVEC (int, OMEGA_MAX_VARS
);
486 if (!pb
->variables_initialized
)
487 omega_initialize_variables (pb
);
489 if (pb
->num_vars
> 0)
491 omega_eliminate_redundant (pb
, false);
493 for (e
= 0; e
< pb
->num_eqs
; e
++)
496 fprintf (file
, "; ");
499 omega_print_eq (file
, pb
, &pb
->eqs
[e
]);
502 for (e
= 0; e
< pb
->num_geqs
; e
++)
507 for (v
= 1; v
<= pb
->num_vars
; v
++)
509 last_links
[v
] = first_links
[v
] = 0;
512 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
516 for (e
= 0; e
< pb
->num_geqs
; e
++)
519 for (v
= 1; v
<= pb
->num_vars
; v
++)
520 if (pb
->geqs
[e
].coef
[v
] == 1)
522 else if (pb
->geqs
[e
].coef
[v
] == -1)
527 while (v1
> 0 && pb
->geqs
[e
].coef
[v1
] == 0)
532 while (v2
> 0 && pb
->geqs
[e
].coef
[v2
] == 0)
537 while (v3
> 0 && pb
->geqs
[e
].coef
[v3
] == 0)
540 if (pb
->geqs
[e
].coef
[0] > 0 || pb
->geqs
[e
].coef
[0] < -1
542 || pb
->geqs
[e
].coef
[v1
] * pb
->geqs
[e
].coef
[v2
] != -1)
544 /* Not a partial order relation. */
548 if (pb
->geqs
[e
].coef
[v1
] == 1)
551 /* Relation is v1 <= v2 or v1 < v2. */
552 po
[v1
][v2
] = ((pb
->geqs
[e
].coef
[0] == 0) ? le
: lt
);
556 for (v
= 1; v
<= pb
->num_vars
; v
++)
557 chain_length
[v
] = last_links
[v
];
559 /* Just in case pb->num_vars <= 0. */
561 for (t
= 0; t
< pb
->num_vars
; t
++)
565 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
566 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
567 if (po
[v1
][v2
] != none
&&
568 chain_length
[v1
] <= chain_length
[v2
])
570 chain_length
[v1
] = chain_length
[v2
] + 1;
575 /* Caught in cycle. */
576 gcc_assert (!change
);
578 for (v1
= 1; v1
<= pb
->num_vars
; v1
++)
579 if (chain_length
[v1
] == 0)
584 for (v1
= 2; v1
<= pb
->num_vars
; v1
++)
585 if (chain_length
[v1
] + first_links
[v1
] >
586 chain_length
[v
] + first_links
[v
])
589 if (chain_length
[v
] + first_links
[v
] == 0)
593 fprintf (file
, "; ");
597 /* Chain starts at v. */
602 for (e
= 0; e
< pb
->num_geqs
; e
++)
603 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == 1)
606 fprintf (file
, ", ");
608 tmp
= pb
->geqs
[e
].coef
[v
];
609 pb
->geqs
[e
].coef
[v
] = 0;
610 omega_print_term (file
, pb
, &pb
->geqs
[e
], -1);
611 pb
->geqs
[e
].coef
[v
] = tmp
;
617 fprintf (file
, " <= ");
626 for (v2
= 1; v2
<= pb
->num_vars
; v2
++)
627 if (po
[v
][v2
] && chain_length
[v
] == 1 + chain_length
[v2
])
630 if (v2
> pb
->num_vars
)
637 fprintf (file
, "%s", omega_variable_to_str (pb
, chain
[0]));
639 for (multiprint
= false, i
= 1; i
< m
; i
++)
645 fprintf (file
, " <= ");
647 fprintf (file
, " < ");
649 fprintf (file
, "%s", omega_variable_to_str (pb
, v2
));
650 live
[po_eq
[v
][v2
]] = false;
652 if (!multiprint
&& i
< m
- 1)
653 for (v3
= 1; v3
<= pb
->num_vars
; v3
++)
655 if (v
== v3
|| v2
== v3
656 || po
[v
][v2
] != po
[v
][v3
]
657 || po
[v2
][chain
[i
+ 1]] != po
[v3
][chain
[i
+ 1]])
660 fprintf (file
, ",%s", omega_variable_to_str (pb
, v3
));
661 live
[po_eq
[v
][v3
]] = false;
662 live
[po_eq
[v3
][chain
[i
+ 1]]] = false;
670 /* Print last_links. */
675 for (e
= 0; e
< pb
->num_geqs
; e
++)
676 if (live
[e
] && pb
->geqs
[e
].coef
[v
] == -1)
679 fprintf (file
, ", ");
681 fprintf (file
, " <= ");
683 tmp
= pb
->geqs
[e
].coef
[v
];
684 pb
->geqs
[e
].coef
[v
] = 0;
685 omega_print_term (file
, pb
, &pb
->geqs
[e
], 1);
686 pb
->geqs
[e
].coef
[v
] = tmp
;
693 for (e
= 0; e
< pb
->num_geqs
; e
++)
697 fprintf (file
, "; ");
699 omega_print_geq (file
, pb
, &pb
->geqs
[e
]);
702 for (e
= 0; e
< pb
->num_subs
; e
++)
704 eqn eq
= &pb
->subs
[e
];
707 fprintf (file
, "; ");
712 fprintf (file
, "%s := ", omega_var_to_str (eq
->key
));
714 fprintf (file
, "#%d := ", eq
->key
);
716 omega_print_term (file
, pb
, eq
, 1);
729 /* Assign to variable I in PB the next wildcard name. The name of a
730 wildcard is a negative number. */
731 static int next_wild_card
= 0;
734 omega_name_wild_card (omega_pb pb
, int i
)
737 if (next_wild_card
< -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS
))
739 pb
->var
[i
] = next_wild_card
;
742 /* Return the index of the last protected (or safe) variable in PB,
743 after having added a new wildcard variable. */
746 omega_add_new_wild_card (omega_pb pb
)
749 int i
= ++pb
->safe_vars
;
752 /* Make a free place in the protected (safe) variables, by moving
753 the non protected variable pointed by "I" at the end, ie. at
754 offset pb->num_vars. */
755 if (pb
->num_vars
!= i
)
757 /* Move "I" for all the inequalities. */
758 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
760 if (pb
->geqs
[e
].coef
[i
])
761 pb
->geqs
[e
].touched
= 1;
763 pb
->geqs
[e
].coef
[pb
->num_vars
] = pb
->geqs
[e
].coef
[i
];
766 /* Move "I" for all the equalities. */
767 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
768 pb
->eqs
[e
].coef
[pb
->num_vars
] = pb
->eqs
[e
].coef
[i
];
770 /* Move "I" for all the substitutions. */
771 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
772 pb
->subs
[e
].coef
[pb
->num_vars
] = pb
->subs
[e
].coef
[i
];
774 /* Move the identifier. */
775 pb
->var
[pb
->num_vars
] = pb
->var
[i
];
778 /* Initialize at zero all the coefficients */
779 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
780 pb
->geqs
[e
].coef
[i
] = 0;
782 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
783 pb
->eqs
[e
].coef
[i
] = 0;
785 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
786 pb
->subs
[e
].coef
[i
] = 0;
788 /* And give it a name. */
789 omega_name_wild_card (pb
, i
);
793 /* Delete inequality E from problem PB that has N_VARS variables. */
796 omega_delete_geq (omega_pb pb
, int e
, int n_vars
)
798 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
800 fprintf (dump_file
, "Deleting %d (last:%d): ", e
, pb
->num_geqs
- 1);
801 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
802 fprintf (dump_file
, "\n");
805 if (e
< pb
->num_geqs
- 1)
806 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
811 /* Delete extra inequality E from problem PB that has N_VARS
815 omega_delete_geq_extra (omega_pb pb
, int e
, int n_vars
)
817 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
819 fprintf (dump_file
, "Deleting %d: ",e
);
820 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
821 fprintf (dump_file
, "\n");
824 if (e
< pb
->num_geqs
- 1)
825 omega_copy_eqn (&pb
->geqs
[e
], &pb
->geqs
[pb
->num_geqs
- 1], n_vars
);
831 /* Remove variable I from problem PB. */
834 omega_delete_variable (omega_pb pb
, int i
)
836 int n_vars
= pb
->num_vars
;
839 if (omega_safe_var_p (pb
, i
))
841 int j
= pb
->safe_vars
;
843 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
845 pb
->geqs
[e
].touched
= 1;
846 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[j
];
847 pb
->geqs
[e
].coef
[j
] = pb
->geqs
[e
].coef
[n_vars
];
850 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
852 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[j
];
853 pb
->eqs
[e
].coef
[j
] = pb
->eqs
[e
].coef
[n_vars
];
856 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
858 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[j
];
859 pb
->subs
[e
].coef
[j
] = pb
->subs
[e
].coef
[n_vars
];
862 pb
->var
[i
] = pb
->var
[j
];
863 pb
->var
[j
] = pb
->var
[n_vars
];
867 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
868 if (pb
->geqs
[e
].coef
[n_vars
])
870 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[n_vars
];
871 pb
->geqs
[e
].touched
= 1;
874 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
875 pb
->eqs
[e
].coef
[i
] = pb
->eqs
[e
].coef
[n_vars
];
877 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
878 pb
->subs
[e
].coef
[i
] = pb
->subs
[e
].coef
[n_vars
];
880 pb
->var
[i
] = pb
->var
[n_vars
];
883 if (omega_safe_var_p (pb
, i
))
889 /* Because the coefficients of an equation are sparse, PACKING records
890 indices for non null coefficients. */
893 /* Set up the coefficients of PACKING, following the coefficients of
894 equation EQN that has NUM_VARS variables. */
897 setup_packing (eqn eqn
, int num_vars
)
902 for (k
= num_vars
; k
>= 0; k
--)
909 /* Computes a linear combination of EQ and SUB at VAR with coefficient
910 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
911 non null indices of SUB stored in PACKING. */
914 omega_substitute_red_1 (eqn eq
, eqn sub
, int var
, int c
, bool *found_black
,
917 if (eq
->coef
[var
] != 0)
919 if (eq
->color
== omega_black
)
923 int j
, k
= eq
->coef
[var
];
927 for (j
= top_var
; j
>= 0; j
--)
928 eq
->coef
[packing
[j
]] -= sub
->coef
[packing
[j
]] * k
* c
;
933 /* Substitute in PB variable VAR with "C * SUB". */
936 omega_substitute_red (omega_pb pb
, eqn sub
, int var
, int c
, bool *found_black
)
938 int e
, top_var
= setup_packing (sub
, pb
->num_vars
);
940 *found_black
= false;
942 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
944 if (sub
->color
== omega_red
)
945 fprintf (dump_file
, "[");
947 fprintf (dump_file
, "substituting using %s := ",
948 omega_variable_to_str (pb
, var
));
949 omega_print_term (dump_file
, pb
, sub
, -c
);
951 if (sub
->color
== omega_red
)
952 fprintf (dump_file
, "]");
954 fprintf (dump_file
, "\n");
955 omega_print_vars (dump_file
, pb
);
958 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
960 eqn eqn
= &(pb
->eqs
[e
]);
962 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
964 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
966 omega_print_eq (dump_file
, pb
, eqn
);
967 fprintf (dump_file
, "\n");
971 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
973 eqn eqn
= &(pb
->geqs
[e
]);
975 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
977 if (eqn
->coef
[var
] && eqn
->color
== omega_red
)
980 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
982 omega_print_geq (dump_file
, pb
, eqn
);
983 fprintf (dump_file
, "\n");
987 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
989 eqn eqn
= &(pb
->subs
[e
]);
991 omega_substitute_red_1 (eqn
, sub
, var
, c
, found_black
, top_var
);
993 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
995 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
996 omega_print_term (dump_file
, pb
, eqn
, 1);
997 fprintf (dump_file
, "\n");
1001 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1002 fprintf (dump_file
, "---\n\n");
1004 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1005 *found_black
= true;
1008 /* Substitute in PB variable VAR with "C * SUB". */
1011 omega_substitute (omega_pb pb
, eqn sub
, int var
, int c
)
1014 int top_var
= setup_packing (sub
, pb
->num_vars
);
1016 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1018 fprintf (dump_file
, "substituting using %s := ",
1019 omega_variable_to_str (pb
, var
));
1020 omega_print_term (dump_file
, pb
, sub
, -c
);
1021 fprintf (dump_file
, "\n");
1022 omega_print_vars (dump_file
, pb
);
1027 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1028 pb
->eqs
[e
].coef
[var
] = 0;
1030 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1031 if (pb
->geqs
[e
].coef
[var
] != 0)
1033 pb
->geqs
[e
].touched
= 1;
1034 pb
->geqs
[e
].coef
[var
] = 0;
1037 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1038 pb
->subs
[e
].coef
[var
] = 0;
1040 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1043 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1045 for (k
= pb
->num_vars
; k
>= 0; k
--)
1048 eqn
->key
= pb
->var
[var
];
1049 eqn
->color
= omega_black
;
1052 else if (top_var
== 0 && packing
[0] == 0)
1054 c
= -sub
->coef
[0] * c
;
1056 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1058 pb
->eqs
[e
].coef
[0] += pb
->eqs
[e
].coef
[var
] * c
;
1059 pb
->eqs
[e
].coef
[var
] = 0;
1062 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1063 if (pb
->geqs
[e
].coef
[var
] != 0)
1065 pb
->geqs
[e
].coef
[0] += pb
->geqs
[e
].coef
[var
] * c
;
1066 pb
->geqs
[e
].coef
[var
] = 0;
1067 pb
->geqs
[e
].touched
= 1;
1070 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1072 pb
->subs
[e
].coef
[0] += pb
->subs
[e
].coef
[var
] * c
;
1073 pb
->subs
[e
].coef
[var
] = 0;
1076 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1079 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1081 for (k
= pb
->num_vars
; k
>= 1; k
--)
1085 eqn
->key
= pb
->var
[var
];
1086 eqn
->color
= omega_black
;
1089 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1091 fprintf (dump_file
, "---\n\n");
1092 omega_print_problem (dump_file
, pb
);
1093 fprintf (dump_file
, "===\n\n");
1098 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1100 eqn eqn
= &(pb
->eqs
[e
]);
1101 int k
= eqn
->coef
[var
];
1108 for (j
= top_var
; j
>= 0; j
--)
1111 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1115 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1117 omega_print_eq (dump_file
, pb
, eqn
);
1118 fprintf (dump_file
, "\n");
1122 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1124 eqn eqn
= &(pb
->geqs
[e
]);
1125 int k
= eqn
->coef
[var
];
1133 for (j
= top_var
; j
>= 0; j
--)
1136 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1140 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1142 omega_print_geq (dump_file
, pb
, eqn
);
1143 fprintf (dump_file
, "\n");
1147 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1149 eqn eqn
= &(pb
->subs
[e
]);
1150 int k
= eqn
->coef
[var
];
1157 for (j
= top_var
; j
>= 0; j
--)
1160 eqn
->coef
[j0
] -= sub
->coef
[j0
] * k
;
1164 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1166 fprintf (dump_file
, "%s := ", omega_var_to_str (eqn
->key
));
1167 omega_print_term (dump_file
, pb
, eqn
, 1);
1168 fprintf (dump_file
, "\n");
1172 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1174 fprintf (dump_file
, "---\n\n");
1175 omega_print_problem (dump_file
, pb
);
1176 fprintf (dump_file
, "===\n\n");
1179 if (omega_safe_var_p (pb
, var
) && !omega_wildcard_p (pb
, var
))
1182 eqn eqn
= &(pb
->subs
[pb
->num_subs
++]);
1185 for (k
= pb
->num_vars
; k
>= 0; k
--)
1186 eqn
->coef
[k
] = c
* (sub
->coef
[k
]);
1188 eqn
->key
= pb
->var
[var
];
1189 eqn
->color
= sub
->color
;
1194 /* Solve e = factor alpha for x_j and substitute. */
1197 omega_do_mod (omega_pb pb
, int factor
, int e
, int j
)
1200 eqn eq
= omega_alloc_eqns (0, 1);
1202 bool kill_j
= false;
1204 omega_copy_eqn (eq
, &pb
->eqs
[e
], pb
->num_vars
);
1206 for (k
= pb
->num_vars
; k
>= 0; k
--)
1208 eq
->coef
[k
] = int_mod (eq
->coef
[k
], factor
);
1210 if (2 * eq
->coef
[k
] >= factor
)
1211 eq
->coef
[k
] -= factor
;
1214 nfactor
= eq
->coef
[j
];
1216 if (omega_safe_var_p (pb
, j
) && !omega_wildcard_p (pb
, j
))
1218 i
= omega_add_new_wild_card (pb
);
1219 eq
->coef
[pb
->num_vars
] = eq
->coef
[i
];
1221 eq
->coef
[i
] = -factor
;
1226 eq
->coef
[j
] = -factor
;
1227 if (!omega_wildcard_p (pb
, j
))
1228 omega_name_wild_card (pb
, j
);
1231 omega_substitute (pb
, eq
, j
, nfactor
);
1233 for (k
= pb
->num_vars
; k
>= 0; k
--)
1234 pb
->eqs
[e
].coef
[k
] = pb
->eqs
[e
].coef
[k
] / factor
;
1237 omega_delete_variable (pb
, j
);
1239 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1241 fprintf (dump_file
, "Mod-ing and normalizing produces:\n");
1242 omega_print_problem (dump_file
, pb
);
1245 omega_free_eqns (eq
, 1);
1248 /* Multiplies by -1 inequality E. */
1251 omega_negate_geq (omega_pb pb
, int e
)
1255 for (i
= pb
->num_vars
; i
>= 0; i
--)
1256 pb
->geqs
[e
].coef
[i
] *= -1;
1258 pb
->geqs
[e
].coef
[0]--;
1259 pb
->geqs
[e
].touched
= 1;
1262 /* Returns OMEGA_TRUE when problem PB has a solution. */
1264 static enum omega_result
1265 verify_omega_pb (omega_pb pb
)
1267 enum omega_result result
;
1269 bool any_color
= false;
1270 omega_pb tmp_problem
= XNEW (struct omega_pb_d
);
1272 omega_copy_problem (tmp_problem
, pb
);
1273 tmp_problem
->safe_vars
= 0;
1274 tmp_problem
->num_subs
= 0;
1276 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1277 if (pb
->geqs
[e
].color
== omega_red
)
1283 if (please_no_equalities_in_simplified_problems
)
1287 original_problem
= no_problem
;
1289 original_problem
= pb
;
1291 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1293 fprintf (dump_file
, "verifying problem");
1296 fprintf (dump_file
, " (color mode)");
1298 fprintf (dump_file
, " :\n");
1299 omega_print_problem (dump_file
, pb
);
1302 result
= omega_solve_problem (tmp_problem
, omega_unknown
);
1303 original_problem
= no_problem
;
1306 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1308 if (result
!= omega_false
)
1309 fprintf (dump_file
, "verified problem\n");
1311 fprintf (dump_file
, "disproved problem\n");
1312 omega_print_problem (dump_file
, pb
);
1318 /* Add a new equality to problem PB at last position E. */
1321 adding_equality_constraint (omega_pb pb
, int e
)
1323 if (original_problem
!= no_problem
1324 && original_problem
!= pb
1328 int e2
= original_problem
->num_eqs
++;
1330 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1332 "adding equality constraint %d to outer problem\n", e2
);
1333 omega_init_eqn_zero (&original_problem
->eqs
[e2
],
1334 original_problem
->num_vars
);
1336 for (i
= pb
->num_vars
; i
>= 1; i
--)
1338 for (j
= original_problem
->num_vars
; j
>= 1; j
--)
1339 if (original_problem
->var
[j
] == pb
->var
[i
])
1344 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1345 fprintf (dump_file
, "retracting\n");
1346 original_problem
->num_eqs
--;
1349 original_problem
->eqs
[e2
].coef
[j
] = pb
->eqs
[e
].coef
[i
];
1352 original_problem
->eqs
[e2
].coef
[0] = pb
->eqs
[e
].coef
[0];
1354 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1355 omega_print_problem (dump_file
, original_problem
);
1359 static int *fast_lookup
;
1360 static int *fast_lookup_red
;
1364 normalize_uncoupled
,
1366 } normalize_return_type
;
1368 /* Normalizes PB by removing redundant constraints. Returns
1369 normalize_false when the constraints system has no solution,
1370 otherwise returns normalize_coupled or normalize_uncoupled. */
1372 static normalize_return_type
1373 normalize_omega_problem (omega_pb pb
)
1375 int e
, i
, j
, k
, n_vars
;
1376 int coupled_subscripts
= 0;
1378 n_vars
= pb
->num_vars
;
1380 for (e
= 0; e
< pb
->num_geqs
; e
++)
1382 if (!pb
->geqs
[e
].touched
)
1384 if (!single_var_geq (&pb
->geqs
[e
], n_vars
))
1385 coupled_subscripts
= 1;
1389 int g
, top_var
, i0
, hashCode
;
1390 int *p
= &packing
[0];
1392 for (k
= 1; k
<= n_vars
; k
++)
1393 if (pb
->geqs
[e
].coef
[k
])
1396 top_var
= (p
- &packing
[0]) - 1;
1400 if (pb
->geqs
[e
].coef
[0] < 0)
1402 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1404 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1405 fprintf (dump_file
, "\nequations have no solution \n");
1407 return normalize_false
;
1410 omega_delete_geq (pb
, e
, n_vars
);
1414 else if (top_var
== 0)
1416 int singlevar
= packing
[0];
1418 g
= pb
->geqs
[e
].coef
[singlevar
];
1422 pb
->geqs
[e
].coef
[singlevar
] = 1;
1423 pb
->geqs
[e
].key
= singlevar
;
1428 pb
->geqs
[e
].coef
[singlevar
] = -1;
1429 pb
->geqs
[e
].key
= -singlevar
;
1433 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1438 int hash_key_multiplier
= 31;
1440 coupled_subscripts
= 1;
1443 g
= pb
->geqs
[e
].coef
[i
];
1444 hashCode
= g
* (i
+ 3);
1449 for (; i0
>= 0; i0
--)
1454 x
= pb
->geqs
[e
].coef
[i
];
1455 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1470 for (; i0
>= 0; i0
--)
1474 x
= pb
->geqs
[e
].coef
[i
];
1475 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3) + x
;
1480 pb
->geqs
[e
].coef
[0] = int_div (pb
->geqs
[e
].coef
[0], g
);
1483 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1484 hashCode
= pb
->geqs
[e
].coef
[i
] * (i
+ 3);
1486 for (; i0
>= 0; i0
--)
1489 pb
->geqs
[e
].coef
[i
] = pb
->geqs
[e
].coef
[i
] / g
;
1490 hashCode
= hashCode
* hash_key_multiplier
* (i
+ 3)
1491 + pb
->geqs
[e
].coef
[i
];
1495 g2
= abs (hashCode
);
1497 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1499 fprintf (dump_file
, "Hash code = %d, eqn = ", hashCode
);
1500 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1501 fprintf (dump_file
, "\n");
1504 j
= g2
% HASH_TABLE_SIZE
;
1507 eqn proto
= &(hash_master
[j
]);
1509 if (proto
->touched
== g2
)
1511 if (proto
->coef
[0] == top_var
)
1514 for (i0
= top_var
; i0
>= 0; i0
--)
1518 if (pb
->geqs
[e
].coef
[i
] != proto
->coef
[i
])
1522 for (i0
= top_var
; i0
>= 0; i0
--)
1526 if (pb
->geqs
[e
].coef
[i
] != -proto
->coef
[i
])
1533 pb
->geqs
[e
].key
= proto
->key
;
1535 pb
->geqs
[e
].key
= -proto
->key
;
1540 else if (proto
->touched
< 0)
1542 omega_init_eqn_zero (proto
, pb
->num_vars
);
1544 for (i0
= top_var
; i0
>= 0; i0
--)
1547 proto
->coef
[i
] = pb
->geqs
[e
].coef
[i
];
1550 for (i0
= top_var
; i0
>= 0; i0
--)
1553 proto
->coef
[i
] = -pb
->geqs
[e
].coef
[i
];
1556 proto
->coef
[0] = top_var
;
1557 proto
->touched
= g2
;
1559 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1560 fprintf (dump_file
, " constraint key = %d\n",
1563 proto
->key
= next_key
++;
1565 /* Too many hash keys generated. */
1566 gcc_assert (proto
->key
<= MAX_KEYS
);
1569 pb
->geqs
[e
].key
= proto
->key
;
1571 pb
->geqs
[e
].key
= -proto
->key
;
1576 j
= (j
+ 1) % HASH_TABLE_SIZE
;
1580 pb
->geqs
[e
].touched
= 0;
1584 int eKey
= pb
->geqs
[e
].key
;
1588 int cTerm
= pb
->geqs
[e
].coef
[0];
1589 e2
= fast_lookup
[MAX_KEYS
- eKey
];
1591 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1592 && pb
->geqs
[e2
].color
== omega_black
)
1594 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1596 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1598 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1599 fprintf (dump_file
, "\n");
1600 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1602 "\nequations have no solution \n");
1604 return normalize_false
;
1607 if (pb
->geqs
[e2
].coef
[0] == -cTerm
1609 || pb
->geqs
[e
].color
== omega_black
))
1611 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1613 if (pb
->geqs
[e
].color
== omega_black
)
1614 adding_equality_constraint (pb
, pb
->num_eqs
);
1616 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1620 e2
= fast_lookup_red
[MAX_KEYS
- eKey
];
1622 if (e2
< e
&& pb
->geqs
[e2
].key
== -eKey
1623 && pb
->geqs
[e2
].color
== omega_red
)
1625 if (pb
->geqs
[e2
].coef
[0] < -cTerm
)
1627 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1629 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
1630 fprintf (dump_file
, "\n");
1631 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e2
]);
1633 "\nequations have no solution \n");
1635 return normalize_false
;
1638 if (pb
->geqs
[e2
].coef
[0] == -cTerm
&& create_color
)
1640 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
], &pb
->geqs
[e
],
1642 pb
->eqs
[pb
->num_eqs
].color
= omega_red
;
1644 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1648 e2
= fast_lookup
[MAX_KEYS
+ eKey
];
1650 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1651 && pb
->geqs
[e2
].color
== omega_black
)
1653 if (pb
->geqs
[e2
].coef
[0] > cTerm
)
1655 if (pb
->geqs
[e
].color
== omega_black
)
1657 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1660 "Removing Redundant Equation: ");
1661 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1662 fprintf (dump_file
, "\n");
1664 "[a] Made Redundant by: ");
1665 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1666 fprintf (dump_file
, "\n");
1668 pb
->geqs
[e2
].coef
[0] = cTerm
;
1669 omega_delete_geq (pb
, e
, n_vars
);
1676 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1678 fprintf (dump_file
, "Removing Redundant Equation: ");
1679 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1680 fprintf (dump_file
, "\n");
1681 fprintf (dump_file
, "[b] Made Redundant by: ");
1682 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1683 fprintf (dump_file
, "\n");
1685 omega_delete_geq (pb
, e
, n_vars
);
1691 e2
= fast_lookup_red
[MAX_KEYS
+ eKey
];
1693 if (e2
< e
&& pb
->geqs
[e2
].key
== eKey
1694 && pb
->geqs
[e2
].color
== omega_red
)
1696 if (pb
->geqs
[e2
].coef
[0] >= cTerm
)
1698 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1700 fprintf (dump_file
, "Removing Redundant Equation: ");
1701 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1702 fprintf (dump_file
, "\n");
1703 fprintf (dump_file
, "[c] Made Redundant by: ");
1704 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1705 fprintf (dump_file
, "\n");
1707 pb
->geqs
[e2
].coef
[0] = cTerm
;
1708 pb
->geqs
[e2
].color
= pb
->geqs
[e
].color
;
1710 else if (pb
->geqs
[e
].color
== omega_red
)
1712 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1714 fprintf (dump_file
, "Removing Redundant Equation: ");
1715 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
1716 fprintf (dump_file
, "\n");
1717 fprintf (dump_file
, "[d] Made Redundant by: ");
1718 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
1719 fprintf (dump_file
, "\n");
1722 omega_delete_geq (pb
, e
, n_vars
);
1729 if (pb
->geqs
[e
].color
== omega_red
)
1730 fast_lookup_red
[MAX_KEYS
+ eKey
] = e
;
1732 fast_lookup
[MAX_KEYS
+ eKey
] = e
;
1736 create_color
= false;
1737 return coupled_subscripts
? normalize_coupled
: normalize_uncoupled
;
1740 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1741 of variables in EQN. */
1744 divide_eqn_by_gcd (eqn eqn
, int n_vars
)
1748 for (var
= n_vars
; var
>= 0; var
--)
1749 g
= gcd (abs (eqn
->coef
[var
]), g
);
1752 for (var
= n_vars
; var
>= 0; var
--)
1753 eqn
->coef
[var
] = eqn
->coef
[var
] / g
;
1756 /* Rewrite some non-safe variables in function of protected
1757 wildcard variables. */
1760 cleanout_wildcards (omega_pb pb
)
1763 int n_vars
= pb
->num_vars
;
1764 bool renormalize
= false;
1766 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1767 for (i
= n_vars
; !omega_safe_var_p (pb
, i
); i
--)
1768 if (pb
->eqs
[e
].coef
[i
] != 0)
1770 /* i is the last nonzero non-safe variable. */
1772 for (j
= i
- 1; !omega_safe_var_p (pb
, j
); j
--)
1773 if (pb
->eqs
[e
].coef
[j
] != 0)
1776 /* j is the next nonzero non-safe variable, or points
1777 to a safe variable: it is then a wildcard variable. */
1780 if (omega_safe_var_p (pb
, j
))
1782 eqn sub
= &(pb
->eqs
[e
]);
1783 int c
= pb
->eqs
[e
].coef
[i
];
1787 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1790 "Found a single wild card equality: ");
1791 omega_print_eq (dump_file
, pb
, &pb
->eqs
[e
]);
1792 fprintf (dump_file
, "\n");
1793 omega_print_problem (dump_file
, pb
);
1796 for (e2
= pb
->num_eqs
- 1; e2
>= 0; e2
--)
1797 if (e
!= e2
&& pb
->eqs
[e2
].coef
[i
]
1798 && (pb
->eqs
[e2
].color
== omega_red
1799 || (pb
->eqs
[e2
].color
== omega_black
1800 && pb
->eqs
[e
].color
== omega_black
)))
1802 eqn eqn
= &(pb
->eqs
[e2
]);
1805 for (var
= n_vars
; var
>= 0; var
--)
1806 eqn
->coef
[var
] *= a
;
1810 for (var
= n_vars
; var
>= 0; var
--)
1811 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1814 divide_eqn_by_gcd (eqn
, n_vars
);
1817 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
1818 if (pb
->geqs
[e2
].coef
[i
]
1819 && (pb
->geqs
[e2
].color
== omega_red
1820 || (pb
->eqs
[e
].color
== omega_black
1821 && pb
->geqs
[e2
].color
== omega_black
)))
1823 eqn eqn
= &(pb
->geqs
[e2
]);
1826 for (var
= n_vars
; var
>= 0; var
--)
1827 eqn
->coef
[var
] *= a
;
1831 for (var
= n_vars
; var
>= 0; var
--)
1832 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1839 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
1840 if (pb
->subs
[e2
].coef
[i
]
1841 && (pb
->subs
[e2
].color
== omega_red
1842 || (pb
->subs
[e2
].color
== omega_black
1843 && pb
->eqs
[e
].color
== omega_black
)))
1845 eqn eqn
= &(pb
->subs
[e2
]);
1848 for (var
= n_vars
; var
>= 0; var
--)
1849 eqn
->coef
[var
] *= a
;
1853 for (var
= n_vars
; var
>= 0; var
--)
1854 eqn
->coef
[var
] -= sub
->coef
[var
] * k
/ c
;
1857 divide_eqn_by_gcd (eqn
, n_vars
);
1860 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1862 fprintf (dump_file
, "cleaned-out wildcard: ");
1863 omega_print_problem (dump_file
, pb
);
1870 normalize_omega_problem (pb
);
1873 /* Make variable IDX unprotected in PB, by swapping its index at the
1874 PB->safe_vars rank. */
1877 omega_unprotect_1 (omega_pb pb
, int *idx
, bool *unprotect
)
1879 /* If IDX is protected... */
1880 if (*idx
< pb
->safe_vars
)
1882 /* ... swap its index with the last non protected index. */
1883 int j
= pb
->safe_vars
;
1886 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1888 pb
->geqs
[e
].touched
= 1;
1889 std::swap (pb
->geqs
[e
].coef
[*idx
], pb
->geqs
[e
].coef
[j
]);
1892 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1893 std::swap (pb
->eqs
[e
].coef
[*idx
], pb
->eqs
[e
].coef
[j
]);
1895 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1896 std::swap (pb
->subs
[e
].coef
[*idx
], pb
->subs
[e
].coef
[j
]);
1899 std::swap (unprotect
[*idx
], unprotect
[j
]);
1901 std::swap (pb
->var
[*idx
], pb
->var
[j
]);
1902 pb
->forwarding_address
[pb
->var
[*idx
]] = *idx
;
1903 pb
->forwarding_address
[pb
->var
[j
]] = j
;
1907 /* The variable at pb->safe_vars is also unprotected now. */
1911 /* During the Fourier-Motzkin elimination some variables are
1912 substituted with other variables. This function resurrects the
1913 substituted variables in PB. */
1916 resurrect_subs (omega_pb pb
)
1918 if (pb
->num_subs
> 0
1919 && please_no_equalities_in_simplified_problems
== 0)
1923 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1926 "problem reduced, bringing variables back to life\n");
1927 omega_print_problem (dump_file
, pb
);
1930 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
1931 if (omega_wildcard_p (pb
, i
))
1932 omega_unprotect_1 (pb
, &i
, NULL
);
1936 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1937 if (single_var_geq (&pb
->geqs
[e
], pb
->num_vars
))
1939 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
1940 pb
->geqs
[e
].key
+= (pb
->geqs
[e
].key
> 0 ? m
: -m
);
1944 pb
->geqs
[e
].touched
= 1;
1945 pb
->geqs
[e
].key
= 0;
1948 for (i
= pb
->num_vars
; !omega_safe_var_p (pb
, i
); i
--)
1950 pb
->var
[i
+ m
] = pb
->var
[i
];
1952 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1953 pb
->geqs
[e
].coef
[i
+ m
] = pb
->geqs
[e
].coef
[i
];
1955 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1956 pb
->eqs
[e
].coef
[i
+ m
] = pb
->eqs
[e
].coef
[i
];
1958 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1959 pb
->subs
[e
].coef
[i
+ m
] = pb
->subs
[e
].coef
[i
];
1962 for (i
= pb
->safe_vars
+ m
; !omega_safe_var_p (pb
, i
); i
--)
1964 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
1965 pb
->geqs
[e
].coef
[i
] = 0;
1967 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
1968 pb
->eqs
[e
].coef
[i
] = 0;
1970 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1971 pb
->subs
[e
].coef
[i
] = 0;
1976 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
1978 pb
->var
[pb
->safe_vars
+ 1 + e
] = pb
->subs
[e
].key
;
1979 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e
]),
1981 pb
->eqs
[pb
->num_eqs
].coef
[pb
->safe_vars
+ 1 + e
] = -1;
1982 pb
->eqs
[pb
->num_eqs
].color
= omega_black
;
1984 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1986 fprintf (dump_file
, "brought back: ");
1987 omega_print_eq (dump_file
, pb
, &pb
->eqs
[pb
->num_eqs
]);
1988 fprintf (dump_file
, "\n");
1992 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
1998 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2000 fprintf (dump_file
, "variables brought back to life\n");
2001 omega_print_problem (dump_file
, pb
);
2004 cleanout_wildcards (pb
);
2009 implies (unsigned int a
, unsigned int b
)
2011 return (a
== (a
& b
));
2014 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2015 extra step is performed. Returns omega_false when there exist no
2016 solution, omega_true otherwise. */
2019 omega_eliminate_redundant (omega_pb pb
, bool expensive
)
2021 int c
, e
, e1
, e2
, e3
, p
, q
, i
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2022 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2023 omega_pb tmp_problem
;
2025 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2026 unsigned int *peqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2027 unsigned int *zeqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2028 unsigned int *neqs
= XNEWVEC (unsigned int, OMEGA_MAX_GEQS
);
2030 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2031 unsigned int pp
, pz
, pn
;
2033 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2035 fprintf (dump_file
, "in eliminate Redundant:\n");
2036 omega_print_problem (dump_file
, pb
);
2039 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2044 peqs
[e
] = zeqs
[e
] = neqs
[e
] = 0;
2046 for (i
= pb
->num_vars
; i
>= 1; i
--)
2048 if (pb
->geqs
[e
].coef
[i
] > 0)
2050 else if (pb
->geqs
[e
].coef
[i
] < 0)
2060 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2062 for (e2
= e1
- 1; e2
>= 0; e2
--)
2065 for (p
= pb
->num_vars
; p
> 1; p
--)
2066 for (q
= p
- 1; q
> 0; q
--)
2067 if ((alpha
= pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
]
2068 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]) != 0)
2074 pz
= ((zeqs
[e1
] & zeqs
[e2
]) | (peqs
[e1
] & neqs
[e2
])
2075 | (neqs
[e1
] & peqs
[e2
]));
2076 pp
= peqs
[e1
] | peqs
[e2
];
2077 pn
= neqs
[e1
] | neqs
[e2
];
2079 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2080 if (e3
!= e1
&& e3
!= e2
)
2082 if (!implies (zeqs
[e3
], pz
))
2085 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2086 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2087 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2088 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2091 if (alpha1
* alpha2
<= 0)
2103 /* Trying to prove e3 is redundant. */
2104 if (!implies (peqs
[e3
], pp
)
2105 || !implies (neqs
[e3
], pn
))
2108 if (pb
->geqs
[e3
].color
== omega_black
2109 && (pb
->geqs
[e1
].color
== omega_red
2110 || pb
->geqs
[e2
].color
== omega_red
))
2113 for (k
= pb
->num_vars
; k
>= 1; k
--)
2114 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2115 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2116 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2119 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2120 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2122 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2124 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2127 "found redundant inequality\n");
2129 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2130 alpha1
, alpha2
, alpha3
);
2132 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2133 fprintf (dump_file
, "\n");
2134 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2135 fprintf (dump_file
, "\n=> ");
2136 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2137 fprintf (dump_file
, "\n\n");
2145 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2146 or trying to prove e3 < 0, and therefore the
2147 problem has no solutions. */
2148 if (!implies (peqs
[e3
], pn
)
2149 || !implies (neqs
[e3
], pp
))
2152 if (pb
->geqs
[e1
].color
== omega_red
2153 || pb
->geqs
[e2
].color
== omega_red
2154 || pb
->geqs
[e3
].color
== omega_red
)
2157 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2158 for (k
= pb
->num_vars
; k
>= 1; k
--)
2159 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2160 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2161 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2164 c
= (alpha1
* pb
->geqs
[e1
].coef
[0]
2165 + alpha2
* pb
->geqs
[e2
].coef
[0]);
2167 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0]))
2169 /* We just proved e3 < 0, so no solutions exist. */
2170 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2173 "found implied over tight inequality\n");
2175 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2176 alpha1
, alpha2
, -alpha3
);
2177 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2178 fprintf (dump_file
, "\n");
2179 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2180 fprintf (dump_file
, "\n=> not ");
2181 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2182 fprintf (dump_file
, "\n\n");
2190 else if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] - 1))
2192 /* We just proved that e3 <=0, so e3 = 0. */
2193 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2196 "found implied tight inequality\n");
2198 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2199 alpha1
, alpha2
, -alpha3
);
2200 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e1
]));
2201 fprintf (dump_file
, "\n");
2202 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2203 fprintf (dump_file
, "\n=> inverse ");
2204 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2205 fprintf (dump_file
, "\n\n");
2208 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++],
2209 &pb
->geqs
[e3
], pb
->num_vars
);
2210 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2211 adding_equality_constraint (pb
, pb
->num_eqs
- 1);
2219 /* Delete the inequalities that were marked as dead. */
2220 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2222 omega_delete_geq (pb
, e
, pb
->num_vars
);
2225 goto eliminate_redundant_done
;
2227 tmp_problem
= XNEW (struct omega_pb_d
);
2230 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2232 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2235 "checking equation %d to see if it is redundant: ", e
);
2236 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2237 fprintf (dump_file
, "\n");
2240 omega_copy_problem (tmp_problem
, pb
);
2241 omega_negate_geq (tmp_problem
, e
);
2242 tmp_problem
->safe_vars
= 0;
2243 tmp_problem
->variables_freed
= false;
2245 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2246 omega_delete_geq (pb
, e
, pb
->num_vars
);
2252 if (!omega_reduce_with_subs
)
2254 resurrect_subs (pb
);
2255 gcc_assert (please_no_equalities_in_simplified_problems
2256 || pb
->num_subs
== 0);
2259 eliminate_redundant_done
:
2267 /* For each inequality that has coefficients bigger than 20, try to
2268 create a new constraint that cannot be derived from the original
2269 constraint and that has smaller coefficients. Add the new
2270 constraint at the end of geqs. Return the number of inequalities
2271 that have been added to PB. */
2274 smooth_weird_equations (omega_pb pb
)
2276 int e1
, e2
, e3
, p
, q
, k
, alpha
, alpha1
, alpha2
, alpha3
;
2281 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
2282 if (pb
->geqs
[e1
].color
== omega_black
)
2286 for (v
= pb
->num_vars
; v
>= 1; v
--)
2287 if (pb
->geqs
[e1
].coef
[v
] != 0 && abs (pb
->geqs
[e1
].coef
[v
]) < g
)
2288 g
= abs (pb
->geqs
[e1
].coef
[v
]);
2295 for (v
= pb
->num_vars
; v
>= 1; v
--)
2296 pb
->geqs
[e3
].coef
[v
] = int_div (6 * pb
->geqs
[e1
].coef
[v
] + g
/ 2,
2299 pb
->geqs
[e3
].color
= omega_black
;
2300 pb
->geqs
[e3
].touched
= 1;
2302 pb
->geqs
[e3
].coef
[0] = 9997;
2304 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2306 fprintf (dump_file
, "Checking to see if we can derive: ");
2307 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2308 fprintf (dump_file
, "\n from: ");
2309 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e1
]);
2310 fprintf (dump_file
, "\n");
2313 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
2314 if (e1
!= e2
&& pb
->geqs
[e2
].color
== omega_black
)
2316 for (p
= pb
->num_vars
; p
> 1; p
--)
2318 for (q
= p
- 1; q
> 0; q
--)
2321 (pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e2
].coef
[q
] -
2322 pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e1
].coef
[q
]);
2331 alpha1
= (pb
->geqs
[e2
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2332 - pb
->geqs
[e2
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2333 alpha2
= -(pb
->geqs
[e1
].coef
[q
] * pb
->geqs
[e3
].coef
[p
]
2334 - pb
->geqs
[e1
].coef
[p
] * pb
->geqs
[e3
].coef
[q
]);
2337 if (alpha1
* alpha2
<= 0)
2349 /* Try to prove e3 is redundant: verify
2350 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2351 for (k
= pb
->num_vars
; k
>= 1; k
--)
2352 if (alpha3
* pb
->geqs
[e3
].coef
[k
]
2353 != (alpha1
* pb
->geqs
[e1
].coef
[k
]
2354 + alpha2
* pb
->geqs
[e2
].coef
[k
]))
2357 c
= alpha1
* pb
->geqs
[e1
].coef
[0]
2358 + alpha2
* pb
->geqs
[e2
].coef
[0];
2360 if (c
< alpha3
* (pb
->geqs
[e3
].coef
[0] + 1))
2361 pb
->geqs
[e3
].coef
[0] = int_div (c
, alpha3
);
2366 if (pb
->geqs
[e3
].coef
[0] < 9997)
2371 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2374 "Smoothing weird equations; adding:\n");
2375 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e3
]);
2376 fprintf (dump_file
, "\nto:\n");
2377 omega_print_problem (dump_file
, pb
);
2378 fprintf (dump_file
, "\n\n");
2386 /* Replace tuples of inequalities, that define upper and lower half
2387 spaces, with an equation. */
2390 coalesce (omega_pb pb
)
2395 int found_something
= 0;
2397 for (e
= 0; e
< pb
->num_geqs
; e
++)
2398 if (pb
->geqs
[e
].color
== omega_red
)
2404 is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2406 for (e
= 0; e
< pb
->num_geqs
; e
++)
2409 for (e
= 0; e
< pb
->num_geqs
; e
++)
2410 if (pb
->geqs
[e
].color
== omega_red
2411 && !pb
->geqs
[e
].touched
)
2412 for (e2
= e
+ 1; e2
< pb
->num_geqs
; e2
++)
2413 if (!pb
->geqs
[e2
].touched
2414 && pb
->geqs
[e
].key
== -pb
->geqs
[e2
].key
2415 && pb
->geqs
[e
].coef
[0] == -pb
->geqs
[e2
].coef
[0]
2416 && pb
->geqs
[e2
].color
== omega_red
)
2418 omega_copy_eqn (&pb
->eqs
[pb
->num_eqs
++], &pb
->geqs
[e
],
2420 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
2426 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2428 omega_delete_geq (pb
, e
, pb
->num_vars
);
2430 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && found_something
)
2432 fprintf (dump_file
, "Coalesced pb->geqs into %d EQ's:\n",
2434 omega_print_problem (dump_file
, pb
);
2440 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2441 true, continue to eliminate all the red inequalities. */
2444 omega_eliminate_red (omega_pb pb
, bool eliminate_all
)
2446 int e
, e2
, e3
, i
, j
, k
, a
, alpha1
, alpha2
;
2448 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2451 omega_pb tmp_problem
;
2453 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2455 fprintf (dump_file
, "in eliminate RED:\n");
2456 omega_print_problem (dump_file
, pb
);
2459 if (pb
->num_eqs
> 0)
2460 omega_simplify_problem (pb
);
2462 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2465 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2466 if (pb
->geqs
[e
].color
== omega_black
&& !is_dead
[e
])
2467 for (e2
= e
- 1; e2
>= 0; e2
--)
2468 if (pb
->geqs
[e2
].color
== omega_black
2473 for (i
= pb
->num_vars
; i
> 1; i
--)
2474 for (j
= i
- 1; j
> 0; j
--)
2475 if ((a
= (pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e2
].coef
[j
]
2476 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e
].coef
[j
])) != 0)
2482 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2485 "found two equations to combine, i = %s, ",
2486 omega_variable_to_str (pb
, i
));
2487 fprintf (dump_file
, "j = %s, alpha = %d\n",
2488 omega_variable_to_str (pb
, j
), a
);
2489 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2490 fprintf (dump_file
, "\n");
2491 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2492 fprintf (dump_file
, "\n");
2495 for (e3
= pb
->num_geqs
- 1; e3
>= 0; e3
--)
2496 if (pb
->geqs
[e3
].color
== omega_red
)
2498 alpha1
= (pb
->geqs
[e2
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2499 - pb
->geqs
[e2
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2500 alpha2
= -(pb
->geqs
[e
].coef
[j
] * pb
->geqs
[e3
].coef
[i
]
2501 - pb
->geqs
[e
].coef
[i
] * pb
->geqs
[e3
].coef
[j
]);
2503 if ((a
> 0 && alpha1
> 0 && alpha2
> 0)
2504 || (a
< 0 && alpha1
< 0 && alpha2
< 0))
2506 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2509 "alpha1 = %d, alpha2 = %d;"
2510 "comparing against: ",
2512 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2513 fprintf (dump_file
, "\n");
2516 for (k
= pb
->num_vars
; k
>= 0; k
--)
2518 c
= (alpha1
* pb
->geqs
[e
].coef
[k
]
2519 + alpha2
* pb
->geqs
[e2
].coef
[k
]);
2521 if (c
!= a
* pb
->geqs
[e3
].coef
[k
])
2524 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && k
> 0)
2525 fprintf (dump_file
, " %s: %d, %d\n",
2526 omega_variable_to_str (pb
, k
), c
,
2527 a
* pb
->geqs
[e3
].coef
[k
]);
2532 ((a
> 0 && c
< a
* pb
->geqs
[e3
].coef
[k
])
2533 || (a
< 0 && c
> a
* pb
->geqs
[e3
].coef
[k
]))))
2535 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2539 "red equation#%d is dead "
2540 "(%d dead so far, %d remain)\n",
2542 pb
->num_geqs
- dead_count
);
2543 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2544 fprintf (dump_file
, "\n");
2545 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e2
]));
2546 fprintf (dump_file
, "\n");
2547 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e3
]));
2548 fprintf (dump_file
, "\n");
2556 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2558 omega_delete_geq (pb
, e
, pb
->num_vars
);
2562 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2564 fprintf (dump_file
, "in eliminate RED, easy tests done:\n");
2565 omega_print_problem (dump_file
, pb
);
2568 for (red_found
= 0, e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2569 if (pb
->geqs
[e
].color
== omega_red
)
2577 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2578 fprintf (dump_file
, "fast checks worked\n");
2580 if (!omega_reduce_with_subs
)
2581 gcc_assert (please_no_equalities_in_simplified_problems
2582 || pb
->num_subs
== 0);
2587 if (!omega_verify_simplification
2588 && verify_omega_pb (pb
) == omega_false
)
2592 tmp_problem
= XNEW (struct omega_pb_d
);
2594 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2595 if (pb
->geqs
[e
].color
== omega_red
)
2597 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2600 "checking equation %d to see if it is redundant: ", e
);
2601 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[e
]));
2602 fprintf (dump_file
, "\n");
2605 omega_copy_problem (tmp_problem
, pb
);
2606 omega_negate_geq (tmp_problem
, e
);
2607 tmp_problem
->safe_vars
= 0;
2608 tmp_problem
->variables_freed
= false;
2609 tmp_problem
->num_subs
= 0;
2611 if (omega_solve_problem (tmp_problem
, omega_false
) == omega_false
)
2613 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2614 fprintf (dump_file
, "it is redundant\n");
2615 omega_delete_geq (pb
, e
, pb
->num_vars
);
2619 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2620 fprintf (dump_file
, "it is not redundant\n");
2624 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2625 fprintf (dump_file
, "no need to check other red equations\n");
2633 /* omega_simplify_problem (pb); */
2635 if (!omega_reduce_with_subs
)
2636 gcc_assert (please_no_equalities_in_simplified_problems
2637 || pb
->num_subs
== 0);
2640 /* Transform some wildcard variables to non-safe variables. */
2643 chain_unprotect (omega_pb pb
)
2646 bool *unprotect
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2648 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2650 unprotect
[i
] = omega_wildcard_p (pb
, i
);
2652 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
2653 if (pb
->subs
[e
].coef
[i
])
2654 unprotect
[i
] = false;
2657 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2659 fprintf (dump_file
, "Doing chain reaction unprotection\n");
2660 omega_print_problem (dump_file
, pb
);
2662 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2664 fprintf (dump_file
, "unprotecting %s\n",
2665 omega_variable_to_str (pb
, i
));
2668 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2670 omega_unprotect_1 (pb
, &i
, unprotect
);
2672 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2674 fprintf (dump_file
, "After chain reactions\n");
2675 omega_print_problem (dump_file
, pb
);
2681 /* Reduce problem PB. */
2684 omega_problem_reduced (omega_pb pb
)
2686 if (omega_verify_simplification
2687 && !in_approximate_mode
2688 && verify_omega_pb (pb
) == omega_false
)
2691 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS
)
2692 && !omega_eliminate_redundant (pb
, true))
2695 omega_found_reduction
= omega_true
;
2697 if (!please_no_equalities_in_simplified_problems
)
2700 if (omega_reduce_with_subs
2701 || please_no_equalities_in_simplified_problems
)
2702 chain_unprotect (pb
);
2704 resurrect_subs (pb
);
2706 if (!return_single_result
)
2710 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
2711 pb
->forwarding_address
[pb
->var
[i
]] = i
;
2713 for (i
= 0; i
< pb
->num_subs
; i
++)
2714 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
2716 (*omega_when_reduced
) (pb
);
2719 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2721 fprintf (dump_file
, "-------------------------------------------\n");
2722 fprintf (dump_file
, "problem reduced:\n");
2723 omega_print_problem (dump_file
, pb
);
2724 fprintf (dump_file
, "-------------------------------------------\n");
2728 /* Eliminates all the free variables for problem PB, that is all the
2729 variables from FV to PB->NUM_VARS. */
2732 omega_free_eliminations (omega_pb pb
, int fv
)
2734 bool try_again
= true;
2736 int n_vars
= pb
->num_vars
;
2742 for (i
= n_vars
; i
> fv
; i
--)
2744 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2745 if (pb
->geqs
[e
].coef
[i
])
2750 else if (pb
->geqs
[e
].coef
[i
] > 0)
2752 for (e2
= e
- 1; e2
>= 0; e2
--)
2753 if (pb
->geqs
[e2
].coef
[i
] < 0)
2758 for (e2
= e
- 1; e2
>= 0; e2
--)
2759 if (pb
->geqs
[e2
].coef
[i
] > 0)
2766 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2767 if (pb
->subs
[e3
].coef
[i
])
2773 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2774 if (pb
->eqs
[e3
].coef
[i
])
2780 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2781 fprintf (dump_file
, "a free elimination of %s\n",
2782 omega_variable_to_str (pb
, i
));
2786 omega_delete_geq (pb
, e
, n_vars
);
2788 for (e
--; e
>= 0; e
--)
2789 if (pb
->geqs
[e
].coef
[i
])
2790 omega_delete_geq (pb
, e
, n_vars
);
2792 try_again
= (i
< n_vars
);
2795 omega_delete_variable (pb
, i
);
2796 n_vars
= pb
->num_vars
;
2801 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2803 fprintf (dump_file
, "\nafter free eliminations:\n");
2804 omega_print_problem (dump_file
, pb
);
2805 fprintf (dump_file
, "\n");
2809 /* Do free red eliminations. */
2812 free_red_eliminations (omega_pb pb
)
2814 bool try_again
= true;
2816 int n_vars
= pb
->num_vars
;
2817 bool *is_red_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2818 bool *is_dead_var
= XNEWVEC (bool, OMEGA_MAX_VARS
);
2819 bool *is_dead_geq
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
2821 for (i
= n_vars
; i
> 0; i
--)
2823 is_red_var
[i
] = false;
2824 is_dead_var
[i
] = false;
2827 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2829 is_dead_geq
[e
] = false;
2831 if (pb
->geqs
[e
].color
== omega_red
)
2832 for (i
= n_vars
; i
> 0; i
--)
2833 if (pb
->geqs
[e
].coef
[i
] != 0)
2834 is_red_var
[i
] = true;
2840 for (i
= n_vars
; i
> 0; i
--)
2841 if (!is_red_var
[i
] && !is_dead_var
[i
])
2843 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2844 if (!is_dead_geq
[e
] && pb
->geqs
[e
].coef
[i
])
2849 else if (pb
->geqs
[e
].coef
[i
] > 0)
2851 for (e2
= e
- 1; e2
>= 0; e2
--)
2852 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] < 0)
2857 for (e2
= e
- 1; e2
>= 0; e2
--)
2858 if (!is_dead_geq
[e2
] && pb
->geqs
[e2
].coef
[i
] > 0)
2865 for (e3
= pb
->num_subs
- 1; e3
>= 0; e3
--)
2866 if (pb
->subs
[e3
].coef
[i
])
2872 for (e3
= pb
->num_eqs
- 1; e3
>= 0; e3
--)
2873 if (pb
->eqs
[e3
].coef
[i
])
2879 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2880 fprintf (dump_file
, "a free red elimination of %s\n",
2881 omega_variable_to_str (pb
, i
));
2884 if (pb
->geqs
[e
].coef
[i
])
2885 is_dead_geq
[e
] = true;
2888 is_dead_var
[i
] = true;
2893 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2895 omega_delete_geq (pb
, e
, n_vars
);
2897 for (i
= n_vars
; i
> 0; i
--)
2899 omega_delete_variable (pb
, i
);
2901 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2903 fprintf (dump_file
, "\nafter free red eliminations:\n");
2904 omega_print_problem (dump_file
, pb
);
2905 fprintf (dump_file
, "\n");
2913 /* For equation EQ of the form "0 = EQN", insert in PB two
2914 inequalities "0 <= EQN" and "0 <= -EQN". */
2917 omega_convert_eq_to_geqs (omega_pb pb
, int eq
)
2921 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2922 fprintf (dump_file
, "Converting Eq to Geqs\n");
2924 /* Insert "0 <= EQN". */
2925 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2926 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2929 /* Insert "0 <= -EQN". */
2930 omega_copy_eqn (&pb
->geqs
[pb
->num_geqs
], &pb
->eqs
[eq
], pb
->num_vars
);
2931 pb
->geqs
[pb
->num_geqs
].touched
= 1;
2933 for (i
= 0; i
<= pb
->num_vars
; i
++)
2934 pb
->geqs
[pb
->num_geqs
].coef
[i
] *= -1;
2938 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2939 omega_print_problem (dump_file
, pb
);
2942 /* Eliminates variable I from PB. */
2945 omega_do_elimination (omega_pb pb
, int e
, int i
)
2947 eqn sub
= omega_alloc_eqns (0, 1);
2949 int n_vars
= pb
->num_vars
;
2951 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2952 fprintf (dump_file
, "eliminating variable %s\n",
2953 omega_variable_to_str (pb
, i
));
2955 omega_copy_eqn (sub
, &pb
->eqs
[e
], pb
->num_vars
);
2958 if (c
== 1 || c
== -1)
2960 if (pb
->eqs
[e
].color
== omega_red
)
2963 omega_substitute_red (pb
, sub
, i
, c
, &fB
);
2965 omega_convert_eq_to_geqs (pb
, e
);
2967 omega_delete_variable (pb
, i
);
2971 omega_substitute (pb
, sub
, i
, c
);
2972 omega_delete_variable (pb
, i
);
2980 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2981 fprintf (dump_file
, "performing non-exact elimination, c = %d\n", c
);
2983 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
2984 if (pb
->eqs
[e
].coef
[i
])
2986 eqn eqn
= &(pb
->eqs
[e
]);
2988 for (j
= n_vars
; j
>= 0; j
--)
2992 if (sub
->color
== omega_red
)
2993 eqn
->color
= omega_red
;
2994 for (j
= n_vars
; j
>= 0; j
--)
2995 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
2998 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
2999 if (pb
->geqs
[e
].coef
[i
])
3001 eqn eqn
= &(pb
->geqs
[e
]);
3004 if (sub
->color
== omega_red
)
3005 eqn
->color
= omega_red
;
3007 for (j
= n_vars
; j
>= 0; j
--)
3014 for (j
= n_vars
; j
>= 0; j
--)
3015 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3019 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3020 if (pb
->subs
[e
].coef
[i
])
3022 eqn eqn
= &(pb
->subs
[e
]);
3025 gcc_assert (sub
->color
== omega_black
);
3026 for (j
= n_vars
; j
>= 0; j
--)
3030 for (j
= n_vars
; j
>= 0; j
--)
3031 eqn
->coef
[j
] -= sub
->coef
[j
] * k
/ c
;
3034 if (in_approximate_mode
)
3035 omega_delete_variable (pb
, i
);
3037 omega_convert_eq_to_geqs (pb
, e2
);
3040 omega_free_eqns (sub
, 1);
3043 /* Helper function for printing "sorry, no solution". */
3045 static inline enum omega_result
3046 omega_problem_has_no_solution (void)
3048 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3049 fprintf (dump_file
, "\nequations have no solution \n");
3054 /* Helper function: solve equations in PB one at a time, following the
3055 DESIRED_RES result. */
3057 static enum omega_result
3058 omega_solve_eq (omega_pb pb
, enum omega_result desired_res
)
3065 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && pb
->num_eqs
> 0)
3067 fprintf (dump_file
, "\nomega_solve_eq (%d, %d)\n",
3068 desired_res
, may_be_red
);
3069 omega_print_problem (dump_file
, pb
);
3070 fprintf (dump_file
, "\n");
3076 j
= pb
->num_eqs
- 1;
3082 while (i
<= j
&& pb
->eqs
[i
].color
== omega_red
)
3085 while (i
<= j
&& pb
->eqs
[j
].color
== omega_black
)
3091 eq
= omega_alloc_eqns (0, 1);
3092 omega_copy_eqn (eq
, &pb
->eqs
[i
], pb
->num_vars
);
3093 omega_copy_eqn (&pb
->eqs
[i
], &pb
->eqs
[j
], pb
->num_vars
);
3094 omega_copy_eqn (&pb
->eqs
[j
], eq
, pb
->num_vars
);
3095 omega_free_eqns (eq
, 1);
3101 /* Eliminate all EQ equations */
3102 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
3104 eqn eqn
= &(pb
->eqs
[e
]);
3107 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3108 fprintf (dump_file
, "----\n");
3110 for (i
= pb
->num_vars
; i
> 0; i
--)
3116 for (j
= i
- 1; j
> 0; j
--)
3120 /* i is the position of last nonzero coefficient,
3121 g is the coefficient of i,
3122 j is the position of next nonzero coefficient. */
3126 if (eqn
->coef
[0] % g
!= 0)
3127 return omega_problem_has_no_solution ();
3129 eqn
->coef
[0] = eqn
->coef
[0] / g
;
3132 omega_do_elimination (pb
, e
, i
);
3138 if (eqn
->coef
[0] != 0)
3139 return omega_problem_has_no_solution ();
3151 omega_do_elimination (pb
, e
, i
);
3157 bool promotion_possible
=
3158 (omega_safe_var_p (pb
, j
)
3159 && pb
->safe_vars
+ 1 == i
3160 && !omega_eqn_is_red (eqn
, desired_res
)
3161 && !in_approximate_mode
);
3163 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && promotion_possible
)
3164 fprintf (dump_file
, " Promotion possible\n");
3167 if (!omega_safe_var_p (pb
, j
))
3169 for (; g
!= 1 && !omega_safe_var_p (pb
, j
); j
--)
3170 g
= gcd (abs (eqn
->coef
[j
]), g
);
3173 else if (!omega_safe_var_p (pb
, i
))
3178 for (; g
!= 1 && j
> 0; j
--)
3179 g
= gcd (abs (eqn
->coef
[j
]), g
);
3183 if (eqn
->coef
[0] % g
!= 0)
3184 return omega_problem_has_no_solution ();
3186 for (j
= 0; j
<= pb
->num_vars
; j
++)
3196 for (e2
= e
- 1; e2
>= 0; e2
--)
3197 if (pb
->eqs
[e2
].coef
[i
])
3201 for (e2
= pb
->num_geqs
- 1; e2
>= 0; e2
--)
3202 if (pb
->geqs
[e2
].coef
[i
])
3206 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
3207 if (pb
->subs
[e2
].coef
[i
])
3212 bool change
= false;
3214 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3216 fprintf (dump_file
, "Ha! We own it! \n");
3217 omega_print_eq (dump_file
, pb
, eqn
);
3218 fprintf (dump_file
, " \n");
3224 for (j
= i
- 1; j
>= 0; j
--)
3226 int t
= int_mod (eqn
->coef
[j
], g
);
3231 if (t
!= eqn
->coef
[j
])
3240 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3241 fprintf (dump_file
, "So what?\n");
3246 omega_name_wild_card (pb
, i
);
3248 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3250 omega_print_eq (dump_file
, pb
, eqn
);
3251 fprintf (dump_file
, " \n");
3260 if (promotion_possible
)
3262 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3264 fprintf (dump_file
, "promoting %s to safety\n",
3265 omega_variable_to_str (pb
, i
));
3266 omega_print_vars (dump_file
, pb
);
3271 if (!omega_wildcard_p (pb
, i
))
3272 omega_name_wild_card (pb
, i
);
3274 promotion_possible
= false;
3279 if (g2
> 1 && !in_approximate_mode
)
3281 if (pb
->eqs
[e
].color
== omega_red
)
3283 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3284 fprintf (dump_file
, "handling red equality\n");
3287 omega_do_elimination (pb
, e
, i
);
3291 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3294 "adding equation to handle safe variable \n");
3295 omega_print_eq (dump_file
, pb
, eqn
);
3296 fprintf (dump_file
, "\n----\n");
3297 omega_print_problem (dump_file
, pb
);
3298 fprintf (dump_file
, "\n----\n");
3299 fprintf (dump_file
, "\n----\n");
3302 i
= omega_add_new_wild_card (pb
);
3304 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
3305 omega_init_eqn_zero (&pb
->eqs
[e
+ 1], pb
->num_vars
);
3306 omega_copy_eqn (&pb
->eqs
[e
+ 1], eqn
, pb
->safe_vars
);
3308 for (j
= pb
->num_vars
; j
>= 0; j
--)
3310 pb
->eqs
[e
+ 1].coef
[j
] = int_mod (pb
->eqs
[e
+ 1].coef
[j
], g2
);
3312 if (2 * pb
->eqs
[e
+ 1].coef
[j
] >= g2
)
3313 pb
->eqs
[e
+ 1].coef
[j
] -= g2
;
3316 pb
->eqs
[e
+ 1].coef
[i
] = g2
;
3319 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3320 omega_print_problem (dump_file
, pb
);
3329 /* Find variable to eliminate. */
3332 gcc_assert (in_approximate_mode
);
3334 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3336 fprintf (dump_file
, "non-exact elimination: ");
3337 omega_print_eq (dump_file
, pb
, eqn
);
3338 fprintf (dump_file
, "\n");
3339 omega_print_problem (dump_file
, pb
);
3342 for (i
= pb
->num_vars
; i
> sv
; i
--)
3343 if (pb
->eqs
[e
].coef
[i
] != 0)
3347 for (i
= pb
->num_vars
; i
> sv
; i
--)
3348 if (pb
->eqs
[e
].coef
[i
] == 1 || pb
->eqs
[e
].coef
[i
] == -1)
3354 omega_do_elimination (pb
, e
, i
);
3356 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && g2
> 1)
3358 fprintf (dump_file
, "result of non-exact elimination:\n");
3359 omega_print_problem (dump_file
, pb
);
3364 int factor
= (INT_MAX
);
3367 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3368 fprintf (dump_file
, "doing moding\n");
3370 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3371 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3376 for (; i
!= sv
; i
--)
3377 if ((pb
->eqs
[e
].coef
[i
] & 1) != 0)
3383 if (j
!= 0 && i
== sv
)
3385 omega_do_mod (pb
, 2, e
, j
);
3391 for (i
= pb
->num_vars
; i
!= sv
; i
--)
3392 if (pb
->eqs
[e
].coef
[i
] != 0
3393 && factor
> abs (pb
->eqs
[e
].coef
[i
]) + 1)
3395 factor
= abs (pb
->eqs
[e
].coef
[i
]) + 1;
3401 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3402 fprintf (dump_file
, "should not have happened\n");
3406 omega_do_mod (pb
, factor
, e
, j
);
3407 /* Go back and try this equation again. */
3414 return omega_unknown
;
3417 /* Transform an inequation E to an equality, then solve DIFF problems
3418 based on PB, and only differing by the constant part that is
3419 diminished by one, trying to figure out which of the constants
3422 static enum omega_result
3423 parallel_splinter (omega_pb pb
, int e
, int diff
,
3424 enum omega_result desired_res
)
3426 omega_pb tmp_problem
;
3429 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3431 fprintf (dump_file
, "Using parallel splintering\n");
3432 omega_print_problem (dump_file
, pb
);
3435 tmp_problem
= XNEW (struct omega_pb_d
);
3436 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
], pb
->num_vars
);
3439 for (i
= 0; i
<= diff
; i
++)
3441 omega_copy_problem (tmp_problem
, pb
);
3443 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3445 fprintf (dump_file
, "Splinter # %i\n", i
);
3446 omega_print_problem (dump_file
, pb
);
3449 if (omega_solve_problem (tmp_problem
, desired_res
) == omega_true
)
3455 pb
->eqs
[0].coef
[0]--;
3462 /* Helper function: solve equations one at a time. */
3464 static enum omega_result
3465 omega_solve_geq (omega_pb pb
, enum omega_result desired_res
)
3469 enum omega_result result
;
3470 bool coupled_subscripts
= false;
3471 bool smoothed
= false;
3472 bool eliminate_again
;
3473 bool tried_eliminating_redundant
= false;
3475 if (desired_res
!= omega_simplify
)
3483 gcc_assert (desired_res
== omega_simplify
|| pb
->num_subs
== 0);
3485 /* Verify that there are not too many inequalities. */
3486 gcc_assert (pb
->num_geqs
<= OMEGA_MAX_GEQS
);
3488 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3490 fprintf (dump_file
, "\nomega_solve_geq (%d,%d):\n",
3491 desired_res
, please_no_equalities_in_simplified_problems
);
3492 omega_print_problem (dump_file
, pb
);
3493 fprintf (dump_file
, "\n");
3496 n_vars
= pb
->num_vars
;
3500 enum omega_eqn_color u_color
= omega_black
;
3501 enum omega_eqn_color l_color
= omega_black
;
3502 int upper_bound
= pos_infinity
;
3503 int lower_bound
= neg_infinity
;
3505 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3507 int a
= pb
->geqs
[e
].coef
[1];
3508 int c
= pb
->geqs
[e
].coef
[0];
3510 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3514 return omega_problem_has_no_solution ();
3521 if (lower_bound
< -c
3522 || (lower_bound
== -c
3523 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3526 l_color
= pb
->geqs
[e
].color
;
3532 c
= int_div (c
, -a
);
3535 || (upper_bound
== c
3536 && !omega_eqn_is_red (&pb
->geqs
[e
], desired_res
)))
3539 u_color
= pb
->geqs
[e
].color
;
3544 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3546 fprintf (dump_file
, "upper bound = %d\n", upper_bound
);
3547 fprintf (dump_file
, "lower bound = %d\n", lower_bound
);
3550 if (lower_bound
> upper_bound
)
3551 return omega_problem_has_no_solution ();
3553 if (desired_res
== omega_simplify
)
3556 if (pb
->safe_vars
== 1)
3559 if (lower_bound
== upper_bound
3560 && u_color
== omega_black
3561 && l_color
== omega_black
)
3563 pb
->eqs
[0].coef
[0] = -lower_bound
;
3564 pb
->eqs
[0].coef
[1] = 1;
3565 pb
->eqs
[0].color
= omega_black
;
3567 return omega_solve_problem (pb
, desired_res
);
3571 if (lower_bound
> neg_infinity
)
3573 pb
->geqs
[0].coef
[0] = -lower_bound
;
3574 pb
->geqs
[0].coef
[1] = 1;
3575 pb
->geqs
[0].key
= 1;
3576 pb
->geqs
[0].color
= l_color
;
3577 pb
->geqs
[0].touched
= 0;
3581 if (upper_bound
< pos_infinity
)
3583 pb
->geqs
[pb
->num_geqs
].coef
[0] = upper_bound
;
3584 pb
->geqs
[pb
->num_geqs
].coef
[1] = -1;
3585 pb
->geqs
[pb
->num_geqs
].key
= -1;
3586 pb
->geqs
[pb
->num_geqs
].color
= u_color
;
3587 pb
->geqs
[pb
->num_geqs
].touched
= 0;
3595 omega_problem_reduced (pb
);
3599 if (original_problem
!= no_problem
3600 && l_color
== omega_black
3601 && u_color
== omega_black
3603 && lower_bound
== upper_bound
)
3605 pb
->eqs
[0].coef
[0] = -lower_bound
;
3606 pb
->eqs
[0].coef
[1] = 1;
3608 adding_equality_constraint (pb
, 0);
3614 if (!pb
->variables_freed
)
3616 pb
->variables_freed
= true;
3618 if (desired_res
!= omega_simplify
)
3619 omega_free_eliminations (pb
, 0);
3621 omega_free_eliminations (pb
, pb
->safe_vars
);
3623 n_vars
= pb
->num_vars
;
3629 switch (normalize_omega_problem (pb
))
3631 case normalize_false
:
3635 case normalize_coupled
:
3636 coupled_subscripts
= true;
3639 case normalize_uncoupled
:
3640 coupled_subscripts
= false;
3647 n_vars
= pb
->num_vars
;
3649 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3651 fprintf (dump_file
, "\nafter normalization:\n");
3652 omega_print_problem (dump_file
, pb
);
3653 fprintf (dump_file
, "\n");
3654 fprintf (dump_file
, "eliminating variable using Fourier-Motzkin.\n");
3658 int parallel_difference
= INT_MAX
;
3659 int best_parallel_eqn
= -1;
3660 int minC
, maxC
, minCj
= 0;
3661 int lower_bound_count
= 0;
3663 bool possible_easy_int_solution
;
3664 int max_splinters
= 1;
3666 bool lucky_exact
= false;
3667 int best
= (INT_MAX
);
3668 int j
= 0, jLe
= 0, jLowerBoundCount
= 0;
3671 eliminate_again
= false;
3673 if (pb
->num_eqs
> 0)
3674 return omega_solve_problem (pb
, desired_res
);
3676 if (!coupled_subscripts
)
3678 if (pb
->safe_vars
== 0)
3681 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3682 if (!omega_safe_var_p (pb
, abs (pb
->geqs
[e
].key
)))
3683 omega_delete_geq (pb
, e
, n_vars
);
3685 pb
->num_vars
= pb
->safe_vars
;
3687 if (desired_res
== omega_simplify
)
3689 omega_problem_reduced (pb
);
3696 if (desired_res
!= omega_simplify
)
3701 if (pb
->num_geqs
== 0)
3703 if (desired_res
== omega_simplify
)
3705 pb
->num_vars
= pb
->safe_vars
;
3706 omega_problem_reduced (pb
);
3712 if (desired_res
== omega_simplify
&& n_vars
== pb
->safe_vars
)
3714 omega_problem_reduced (pb
);
3718 if (pb
->num_geqs
> OMEGA_MAX_GEQS
- 30
3719 || pb
->num_geqs
> 2 * n_vars
* n_vars
+ 4 * n_vars
+ 10)
3721 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3723 "TOO MANY EQUATIONS; "
3724 "%d equations, %d variables, "
3725 "ELIMINATING REDUNDANT ONES\n",
3726 pb
->num_geqs
, n_vars
);
3728 if (!omega_eliminate_redundant (pb
, false))
3731 n_vars
= pb
->num_vars
;
3733 if (pb
->num_eqs
> 0)
3734 return omega_solve_problem (pb
, desired_res
);
3736 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3737 fprintf (dump_file
, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3740 if (desired_res
!= omega_simplify
)
3745 for (i
= n_vars
; i
!= fv
; i
--)
3751 int upper_bound_count
= 0;
3753 lower_bound_count
= 0;
3756 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3757 if (pb
->geqs
[e
].coef
[i
] < 0)
3759 minC
= MIN (minC
, pb
->geqs
[e
].coef
[i
]);
3760 upper_bound_count
++;
3761 if (pb
->geqs
[e
].coef
[i
] < -1)
3769 else if (pb
->geqs
[e
].coef
[i
] > 0)
3771 maxC
= MAX (maxC
, pb
->geqs
[e
].coef
[i
]);
3772 lower_bound_count
++;
3774 if (pb
->geqs
[e
].coef
[i
] > 1)
3783 if (lower_bound_count
== 0
3784 || upper_bound_count
== 0)
3786 lower_bound_count
= 0;
3790 if (ub
>= 0 && lb
>= 0
3791 && pb
->geqs
[lb
].key
== -pb
->geqs
[ub
].key
)
3793 int Lc
= pb
->geqs
[lb
].coef
[i
];
3794 int Uc
= -pb
->geqs
[ub
].coef
[i
];
3796 Lc
* pb
->geqs
[ub
].coef
[0] + Uc
* pb
->geqs
[lb
].coef
[0];
3797 lucky
= (diff
>= (Uc
- 1) * (Lc
- 1));
3803 || in_approximate_mode
)
3805 score
= upper_bound_count
* lower_bound_count
;
3807 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3809 "For %s, exact, score = %d*%d, range = %d ... %d,"
3810 "\nlucky = %d, in_approximate_mode=%d \n",
3811 omega_variable_to_str (pb
, i
),
3813 lower_bound_count
, minC
, maxC
, lucky
,
3814 in_approximate_mode
);
3824 jLowerBoundCount
= lower_bound_count
;
3826 lucky_exact
= lucky
;
3833 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3835 "For %s, non-exact, score = %d*%d,"
3836 "range = %d ... %d \n",
3837 omega_variable_to_str (pb
, i
),
3839 lower_bound_count
, minC
, maxC
);
3841 score
= maxC
- minC
;
3849 jLowerBoundCount
= lower_bound_count
;
3854 if (lower_bound_count
== 0)
3856 omega_free_eliminations (pb
, pb
->safe_vars
);
3857 n_vars
= pb
->num_vars
;
3858 eliminate_again
= true;
3865 lower_bound_count
= jLowerBoundCount
;
3867 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3868 if (pb
->geqs
[e
].coef
[i
] > 0)
3870 if (pb
->geqs
[e
].coef
[i
] == -minC
)
3871 max_splinters
+= -minC
- 1;
3874 pos_mul_hwi ((pb
->geqs
[e
].coef
[i
] - 1),
3875 (-minC
- 1)) / (-minC
) + 1;
3879 /* Trying to produce exact elimination by finding redundant
3881 if (!exact
&& !tried_eliminating_redundant
)
3883 omega_eliminate_redundant (pb
, false);
3884 tried_eliminating_redundant
= true;
3885 eliminate_again
= true;
3888 tried_eliminating_redundant
= false;
3891 if (return_single_result
&& desired_res
== omega_simplify
&& !exact
)
3893 omega_problem_reduced (pb
);
3897 /* #ifndef Omega3 */
3898 /* Trying to produce exact elimination by finding redundant
3900 if (!exact
&& !tried_eliminating_redundant
)
3902 omega_eliminate_redundant (pb
, false);
3903 tried_eliminating_redundant
= true;
3906 tried_eliminating_redundant
= false;
3913 for (e1
= pb
->num_geqs
- 1; e1
>= 0; e1
--)
3914 if (pb
->geqs
[e1
].color
== omega_black
)
3915 for (e2
= e1
- 1; e2
>= 0; e2
--)
3916 if (pb
->geqs
[e2
].color
== omega_black
3917 && pb
->geqs
[e1
].key
== -pb
->geqs
[e2
].key
3918 && ((pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3919 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3920 / 2 < parallel_difference
))
3922 parallel_difference
=
3923 (pb
->geqs
[e1
].coef
[0] + pb
->geqs
[e2
].coef
[0])
3924 * (3 - single_var_geq (&pb
->geqs
[e1
], pb
->num_vars
))
3926 best_parallel_eqn
= e1
;
3929 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
3930 && best_parallel_eqn
>= 0)
3933 "Possible parallel projection, diff = %d, in ",
3934 parallel_difference
);
3935 omega_print_geq (dump_file
, pb
, &(pb
->geqs
[best_parallel_eqn
]));
3936 fprintf (dump_file
, "\n");
3937 omega_print_problem (dump_file
, pb
);
3941 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3943 fprintf (dump_file
, "going to eliminate %s, (%d,%d,%d)\n",
3944 omega_variable_to_str (pb
, i
), i
, minC
,
3946 omega_print_problem (dump_file
, pb
);
3949 fprintf (dump_file
, "(a lucky exact elimination)\n");
3952 fprintf (dump_file
, "(an exact elimination)\n");
3954 fprintf (dump_file
, "Max # of splinters = %d\n", max_splinters
);
3957 gcc_assert (max_splinters
>= 1);
3959 if (!exact
&& desired_res
== omega_simplify
&& best_parallel_eqn
>= 0
3960 && parallel_difference
<= max_splinters
)
3961 return parallel_splinter (pb
, best_parallel_eqn
, parallel_difference
,
3968 int j
= pb
->num_vars
;
3970 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3972 fprintf (dump_file
, "Swapping %d and %d\n", i
, j
);
3973 omega_print_problem (dump_file
, pb
);
3976 std::swap (pb
->var
[i
], pb
->var
[j
]);
3978 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
3979 if (pb
->geqs
[e
].coef
[i
] != pb
->geqs
[e
].coef
[j
])
3981 pb
->geqs
[e
].touched
= 1;
3982 std::swap (pb
->geqs
[e
].coef
[i
], pb
->geqs
[e
].coef
[j
]);
3985 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
3986 if (pb
->subs
[e
].coef
[i
] != pb
->subs
[e
].coef
[j
])
3987 std::swap (pb
->subs
[e
].coef
[i
], pb
->subs
[e
].coef
[j
]);
3989 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3991 fprintf (dump_file
, "Swapping complete \n");
3992 omega_print_problem (dump_file
, pb
);
3993 fprintf (dump_file
, "\n");
3999 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4001 fprintf (dump_file
, "No swap needed\n");
4002 omega_print_problem (dump_file
, pb
);
4006 n_vars
= pb
->num_vars
;
4012 int upper_bound
= pos_infinity
;
4013 int lower_bound
= neg_infinity
;
4014 enum omega_eqn_color ub_color
= omega_black
;
4015 enum omega_eqn_color lb_color
= omega_black
;
4016 int topeqn
= pb
->num_geqs
- 1;
4017 int Lc
= pb
->geqs
[Le
].coef
[i
];
4019 for (Le
= topeqn
; Le
>= 0; Le
--)
4020 if ((Lc
= pb
->geqs
[Le
].coef
[i
]) == 0)
4022 if (pb
->geqs
[Le
].coef
[1] == 1)
4024 int constantTerm
= -pb
->geqs
[Le
].coef
[0];
4026 if (constantTerm
> lower_bound
||
4027 (constantTerm
== lower_bound
&&
4028 !omega_eqn_is_red (&pb
->geqs
[Le
], desired_res
)))
4030 lower_bound
= constantTerm
;
4031 lb_color
= pb
->geqs
[Le
].color
;
4034 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4036 if (pb
->geqs
[Le
].color
== omega_black
)
4037 fprintf (dump_file
, " :::=> %s >= %d\n",
4038 omega_variable_to_str (pb
, 1),
4042 " :::=> [%s >= %d]\n",
4043 omega_variable_to_str (pb
, 1),
4049 int constantTerm
= pb
->geqs
[Le
].coef
[0];
4050 if (constantTerm
< upper_bound
||
4051 (constantTerm
== upper_bound
4052 && !omega_eqn_is_red (&pb
->geqs
[Le
],
4055 upper_bound
= constantTerm
;
4056 ub_color
= pb
->geqs
[Le
].color
;
4059 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4061 if (pb
->geqs
[Le
].color
== omega_black
)
4062 fprintf (dump_file
, " :::=> %s <= %d\n",
4063 omega_variable_to_str (pb
, 1),
4067 " :::=> [%s <= %d]\n",
4068 omega_variable_to_str (pb
, 1),
4074 for (Ue
= topeqn
; Ue
>= 0; Ue
--)
4075 if (pb
->geqs
[Ue
].coef
[i
] < 0
4076 && pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4078 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4079 int coefficient
= pb
->geqs
[Ue
].coef
[1] * Lc
4080 + pb
->geqs
[Le
].coef
[1] * Uc
;
4081 int constantTerm
= pb
->geqs
[Ue
].coef
[0] * Lc
4082 + pb
->geqs
[Le
].coef
[0] * Uc
;
4084 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4086 omega_print_geq_extra (dump_file
, pb
,
4088 fprintf (dump_file
, "\n");
4089 omega_print_geq_extra (dump_file
, pb
,
4091 fprintf (dump_file
, "\n");
4094 if (coefficient
> 0)
4096 constantTerm
= -int_div (constantTerm
, coefficient
);
4098 if (constantTerm
> lower_bound
4099 || (constantTerm
== lower_bound
4100 && (desired_res
!= omega_simplify
4101 || (pb
->geqs
[Ue
].color
== omega_black
4102 && pb
->geqs
[Le
].color
== omega_black
))))
4104 lower_bound
= constantTerm
;
4105 lb_color
= (pb
->geqs
[Ue
].color
== omega_red
4106 || pb
->geqs
[Le
].color
== omega_red
)
4107 ? omega_red
: omega_black
;
4110 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4112 if (pb
->geqs
[Ue
].color
== omega_red
4113 || pb
->geqs
[Le
].color
== omega_red
)
4115 " ::=> [%s >= %d]\n",
4116 omega_variable_to_str (pb
, 1),
4121 omega_variable_to_str (pb
, 1),
4127 constantTerm
= int_div (constantTerm
, -coefficient
);
4128 if (constantTerm
< upper_bound
4129 || (constantTerm
== upper_bound
4130 && pb
->geqs
[Ue
].color
== omega_black
4131 && pb
->geqs
[Le
].color
== omega_black
))
4133 upper_bound
= constantTerm
;
4134 ub_color
= (pb
->geqs
[Ue
].color
== omega_red
4135 || pb
->geqs
[Le
].color
== omega_red
)
4136 ? omega_red
: omega_black
;
4140 && (dump_flags
& TDF_DETAILS
))
4142 if (pb
->geqs
[Ue
].color
== omega_red
4143 || pb
->geqs
[Le
].color
== omega_red
)
4145 " ::=> [%s <= %d]\n",
4146 omega_variable_to_str (pb
, 1),
4151 omega_variable_to_str (pb
, 1),
4159 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4161 " therefore, %c%d <= %c%s%c <= %d%c\n",
4162 lb_color
== omega_red
? '[' : ' ', lower_bound
,
4163 (lb_color
== omega_red
&& ub_color
== omega_black
)
4165 omega_variable_to_str (pb
, 1),
4166 (lb_color
== omega_black
&& ub_color
== omega_red
)
4168 upper_bound
, ub_color
== omega_red
? ']' : ' ');
4170 if (lower_bound
> upper_bound
)
4173 if (pb
->safe_vars
== 1)
4175 if (upper_bound
== lower_bound
4176 && !(ub_color
== omega_red
|| lb_color
== omega_red
)
4177 && !please_no_equalities_in_simplified_problems
)
4180 pb
->eqs
[0].coef
[1] = -1;
4181 pb
->eqs
[0].coef
[0] = upper_bound
;
4183 if (ub_color
== omega_red
4184 || lb_color
== omega_red
)
4185 pb
->eqs
[0].color
= omega_red
;
4187 if (desired_res
== omega_simplify
4188 && pb
->eqs
[0].color
== omega_black
)
4189 return omega_solve_problem (pb
, desired_res
);
4192 if (upper_bound
!= pos_infinity
)
4194 pb
->geqs
[0].coef
[1] = -1;
4195 pb
->geqs
[0].coef
[0] = upper_bound
;
4196 pb
->geqs
[0].color
= ub_color
;
4197 pb
->geqs
[0].key
= -1;
4198 pb
->geqs
[0].touched
= 0;
4202 if (lower_bound
!= neg_infinity
)
4204 pb
->geqs
[pb
->num_geqs
].coef
[1] = 1;
4205 pb
->geqs
[pb
->num_geqs
].coef
[0] = -lower_bound
;
4206 pb
->geqs
[pb
->num_geqs
].color
= lb_color
;
4207 pb
->geqs
[pb
->num_geqs
].key
= 1;
4208 pb
->geqs
[pb
->num_geqs
].touched
= 0;
4213 if (desired_res
== omega_simplify
)
4215 omega_problem_reduced (pb
);
4221 && (desired_res
!= omega_simplify
4222 || (lb_color
== omega_black
4223 && ub_color
== omega_black
))
4224 && original_problem
!= no_problem
4225 && lower_bound
== upper_bound
)
4227 for (i
= original_problem
->num_vars
; i
>= 0; i
--)
4228 if (original_problem
->var
[i
] == pb
->var
[1])
4234 e
= original_problem
->num_eqs
++;
4235 omega_init_eqn_zero (&original_problem
->eqs
[e
],
4236 original_problem
->num_vars
);
4237 original_problem
->eqs
[e
].coef
[i
] = -1;
4238 original_problem
->eqs
[e
].coef
[0] = upper_bound
;
4240 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4243 "adding equality %d to outer problem\n", e
);
4244 omega_print_problem (dump_file
, original_problem
);
4251 eliminate_again
= true;
4253 if (lower_bound_count
== 1)
4255 eqn lbeqn
= omega_alloc_eqns (0, 1);
4256 int Lc
= pb
->geqs
[Le
].coef
[i
];
4258 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4259 fprintf (dump_file
, "an inplace elimination\n");
4261 omega_copy_eqn (lbeqn
, &pb
->geqs
[Le
], (n_vars
+ 1));
4262 omega_delete_geq_extra (pb
, Le
, n_vars
+ 1);
4264 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4265 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4267 if (lbeqn
->key
== -pb
->geqs
[Ue
].key
)
4268 omega_delete_geq_extra (pb
, Ue
, n_vars
+ 1);
4272 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4273 pb
->geqs
[Ue
].touched
= 1;
4274 eliminate_again
= false;
4276 if (lbeqn
->color
== omega_red
)
4277 pb
->geqs
[Ue
].color
= omega_red
;
4279 for (k
= 0; k
<= n_vars
; k
++)
4280 pb
->geqs
[Ue
].coef
[k
] =
4281 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4282 mul_hwi (lbeqn
->coef
[k
], Uc
);
4284 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4286 omega_print_geq (dump_file
, pb
,
4288 fprintf (dump_file
, "\n");
4293 omega_free_eqns (lbeqn
, 1);
4298 int *dead_eqns
= XNEWVEC (int, OMEGA_MAX_GEQS
);
4299 bool *is_dead
= XNEWVEC (bool, OMEGA_MAX_GEQS
);
4301 int top_eqn
= pb
->num_geqs
- 1;
4302 lower_bound_count
--;
4304 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4305 fprintf (dump_file
, "lower bound count = %d\n",
4308 for (Le
= top_eqn
; Le
>= 0; Le
--)
4309 if (pb
->geqs
[Le
].coef
[i
] > 0)
4311 int Lc
= pb
->geqs
[Le
].coef
[i
];
4312 for (Ue
= top_eqn
; Ue
>= 0; Ue
--)
4313 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4315 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4318 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4321 e2
= pb
->num_geqs
++;
4323 e2
= dead_eqns
[--num_dead
];
4325 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4327 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4330 "Le = %d, Ue = %d, gen = %d\n",
4332 omega_print_geq_extra (dump_file
, pb
,
4334 fprintf (dump_file
, "\n");
4335 omega_print_geq_extra (dump_file
, pb
,
4337 fprintf (dump_file
, "\n");
4340 eliminate_again
= false;
4342 for (k
= n_vars
; k
>= 0; k
--)
4343 pb
->geqs
[e2
].coef
[k
] =
4344 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4345 mul_hwi (pb
->geqs
[Le
].coef
[k
], Uc
);
4347 pb
->geqs
[e2
].coef
[n_vars
+ 1] = 0;
4348 pb
->geqs
[e2
].touched
= 1;
4350 if (pb
->geqs
[Ue
].color
== omega_red
4351 || pb
->geqs
[Le
].color
== omega_red
)
4352 pb
->geqs
[e2
].color
= omega_red
;
4354 pb
->geqs
[e2
].color
= omega_black
;
4356 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4358 omega_print_geq (dump_file
, pb
,
4360 fprintf (dump_file
, "\n");
4364 if (lower_bound_count
== 0)
4366 dead_eqns
[num_dead
++] = Ue
;
4368 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4369 fprintf (dump_file
, "Killed %d\n", Ue
);
4373 lower_bound_count
--;
4374 dead_eqns
[num_dead
++] = Le
;
4376 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4377 fprintf (dump_file
, "Killed %d\n", Le
);
4380 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4383 while (num_dead
> 0)
4384 is_dead
[dead_eqns
[--num_dead
]] = true;
4386 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4388 omega_delete_geq_extra (pb
, e
, n_vars
+ 1);
4399 rS
= omega_alloc_problem (0, 0);
4400 iS
= omega_alloc_problem (0, 0);
4402 possible_easy_int_solution
= true;
4404 for (e
= 0; e
< pb
->num_geqs
; e
++)
4405 if (pb
->geqs
[e
].coef
[i
] == 0)
4407 omega_copy_eqn (&(rS
->geqs
[e2
]), &pb
->geqs
[e
],
4409 omega_copy_eqn (&(iS
->geqs
[e2
]), &pb
->geqs
[e
],
4412 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4415 fprintf (dump_file
, "Copying (%d, %d): ", i
,
4416 pb
->geqs
[e
].coef
[i
]);
4417 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[e
]);
4418 fprintf (dump_file
, "\n");
4419 for (t
= 0; t
<= n_vars
+ 1; t
++)
4420 fprintf (dump_file
, "%d ", pb
->geqs
[e
].coef
[t
]);
4421 fprintf (dump_file
, "\n");
4425 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4428 for (Le
= pb
->num_geqs
- 1; Le
>= 0; Le
--)
4429 if (pb
->geqs
[Le
].coef
[i
] > 0)
4430 for (Ue
= pb
->num_geqs
- 1; Ue
>= 0; Ue
--)
4431 if (pb
->geqs
[Ue
].coef
[i
] < 0)
4434 int Lc
= pb
->geqs
[Le
].coef
[i
];
4435 int Uc
= -pb
->geqs
[Ue
].coef
[i
];
4437 if (pb
->geqs
[Le
].key
!= -pb
->geqs
[Ue
].key
)
4440 rS
->geqs
[e2
].touched
= iS
->geqs
[e2
].touched
= 1;
4442 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4444 fprintf (dump_file
, "---\n");
4446 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4447 Le
, Lc
, Ue
, Uc
, e2
);
4448 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Le
]);
4449 fprintf (dump_file
, "\n");
4450 omega_print_geq_extra (dump_file
, pb
, &pb
->geqs
[Ue
]);
4451 fprintf (dump_file
, "\n");
4456 for (k
= n_vars
; k
>= 0; k
--)
4457 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4458 pb
->geqs
[Ue
].coef
[k
] + pb
->geqs
[Le
].coef
[k
];
4460 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1);
4464 for (k
= n_vars
; k
>= 0; k
--)
4465 iS
->geqs
[e2
].coef
[k
] = rS
->geqs
[e2
].coef
[k
] =
4466 mul_hwi (pb
->geqs
[Ue
].coef
[k
], Lc
) +
4467 mul_hwi (pb
->geqs
[Le
].coef
[k
], Uc
);
4469 iS
->geqs
[e2
].coef
[0] -= (Uc
- 1) * (Lc
- 1);
4472 if (pb
->geqs
[Ue
].color
== omega_red
4473 || pb
->geqs
[Le
].color
== omega_red
)
4474 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_red
;
4476 iS
->geqs
[e2
].color
= rS
->geqs
[e2
].color
= omega_black
;
4478 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4480 omega_print_geq (dump_file
, pb
, &(rS
->geqs
[e2
]));
4481 fprintf (dump_file
, "\n");
4485 gcc_assert (e2
< OMEGA_MAX_GEQS
);
4487 else if (pb
->geqs
[Ue
].coef
[0] * Lc
+
4488 pb
->geqs
[Le
].coef
[0] * Uc
-
4489 (Uc
- 1) * (Lc
- 1) < 0)
4490 possible_easy_int_solution
= false;
4493 iS
->variables_initialized
= rS
->variables_initialized
= true;
4494 iS
->num_vars
= rS
->num_vars
= pb
->num_vars
;
4495 iS
->num_geqs
= rS
->num_geqs
= e2
;
4496 iS
->num_eqs
= rS
->num_eqs
= 0;
4497 iS
->num_subs
= rS
->num_subs
= pb
->num_subs
;
4498 iS
->safe_vars
= rS
->safe_vars
= pb
->safe_vars
;
4500 for (e
= n_vars
; e
>= 0; e
--)
4501 rS
->var
[e
] = pb
->var
[e
];
4503 for (e
= n_vars
; e
>= 0; e
--)
4504 iS
->var
[e
] = pb
->var
[e
];
4506 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
4508 omega_copy_eqn (&(rS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4509 omega_copy_eqn (&(iS
->subs
[e
]), &(pb
->subs
[e
]), pb
->num_vars
);
4513 n_vars
= pb
->num_vars
;
4515 if (desired_res
!= omega_true
)
4517 if (original_problem
== no_problem
)
4519 original_problem
= pb
;
4520 result
= omega_solve_geq (rS
, omega_false
);
4521 original_problem
= no_problem
;
4524 result
= omega_solve_geq (rS
, omega_false
);
4526 if (result
== omega_false
)
4533 if (pb
->num_eqs
> 0)
4535 /* An equality constraint must have been found */
4538 return omega_solve_problem (pb
, desired_res
);
4542 if (desired_res
!= omega_false
)
4545 int lower_bounds
= 0;
4546 int *lower_bound
= XNEWVEC (int, OMEGA_MAX_GEQS
);
4548 if (possible_easy_int_solution
)
4551 result
= omega_solve_geq (iS
, desired_res
);
4554 if (result
!= omega_false
)
4563 if (!exact
&& best_parallel_eqn
>= 0
4564 && parallel_difference
<= max_splinters
)
4569 return parallel_splinter (pb
, best_parallel_eqn
,
4570 parallel_difference
,
4574 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4575 fprintf (dump_file
, "have to do exact analysis\n");
4579 for (e
= 0; e
< pb
->num_geqs
; e
++)
4580 if (pb
->geqs
[e
].coef
[i
] > 1)
4581 lower_bound
[lower_bounds
++] = e
;
4583 /* Sort array LOWER_BOUND. */
4584 for (j
= 0; j
< lower_bounds
; j
++)
4588 for (int k
= j
+ 1; k
< lower_bounds
; k
++)
4589 if (pb
->geqs
[lower_bound
[smallest
]].coef
[i
] >
4590 pb
->geqs
[lower_bound
[k
]].coef
[i
])
4593 std::swap (lower_bound
[smallest
], lower_bound
[j
]);
4596 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4598 fprintf (dump_file
, "lower bound coefficients = ");
4600 for (j
= 0; j
< lower_bounds
; j
++)
4601 fprintf (dump_file
, " %d",
4602 pb
->geqs
[lower_bound
[j
]].coef
[i
]);
4604 fprintf (dump_file
, "\n");
4607 for (j
= 0; j
< lower_bounds
; j
++)
4611 int worst_lower_bound_constant
= -minC
;
4614 max_incr
= (((pb
->geqs
[e
].coef
[i
] - 1) *
4615 (worst_lower_bound_constant
- 1) - 1)
4616 / worst_lower_bound_constant
);
4617 /* max_incr += 2; */
4619 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4621 fprintf (dump_file
, "for equation ");
4622 omega_print_geq (dump_file
, pb
, &pb
->geqs
[e
]);
4624 "\ntry decrements from 0 to %d\n",
4626 omega_print_problem (dump_file
, pb
);
4629 if (max_incr
> 50 && !smoothed
4630 && smooth_weird_equations (pb
))
4636 goto solve_geq_start
;
4639 omega_copy_eqn (&pb
->eqs
[0], &pb
->geqs
[e
],
4641 pb
->eqs
[0].color
= omega_black
;
4642 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
4643 pb
->geqs
[e
].touched
= 1;
4646 for (c
= max_incr
; c
>= 0; c
--)
4648 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4651 "trying next decrement of %d\n",
4653 omega_print_problem (dump_file
, pb
);
4656 omega_copy_problem (rS
, pb
);
4658 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4659 omega_print_problem (dump_file
, rS
);
4661 result
= omega_solve_problem (rS
, desired_res
);
4663 if (result
== omega_true
)
4672 pb
->eqs
[0].coef
[0]--;
4675 if (j
+ 1 < lower_bounds
)
4678 omega_copy_eqn (&pb
->geqs
[e
], &pb
->eqs
[0],
4680 pb
->geqs
[e
].touched
= 1;
4681 pb
->geqs
[e
].color
= omega_black
;
4682 omega_copy_problem (rS
, pb
);
4684 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4686 "exhausted lower bound, "
4687 "checking if still feasible ");
4689 result
= omega_solve_problem (rS
, omega_false
);
4691 if (result
== omega_false
)
4696 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4697 fprintf (dump_file
, "fall-off the end\n");
4709 return omega_unknown
;
4710 } while (eliminate_again
);
4714 /* Because the omega solver is recursive, this counter limits the
4716 static int omega_solve_depth
= 0;
4718 /* Return omega_true when the problem PB has a solution following the
4722 omega_solve_problem (omega_pb pb
, enum omega_result desired_res
)
4724 enum omega_result result
;
4726 gcc_assert (pb
->num_vars
>= pb
->safe_vars
);
4727 omega_solve_depth
++;
4729 if (desired_res
!= omega_simplify
)
4732 if (omega_solve_depth
> 50)
4734 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4737 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4738 omega_solve_depth
, in_approximate_mode
);
4739 omega_print_problem (dump_file
, pb
);
4744 if (omega_solve_eq (pb
, desired_res
) == omega_false
)
4746 omega_solve_depth
--;
4750 if (in_approximate_mode
&& !pb
->num_geqs
)
4752 result
= omega_true
;
4753 pb
->num_vars
= pb
->safe_vars
;
4754 omega_problem_reduced (pb
);
4757 result
= omega_solve_geq (pb
, desired_res
);
4759 omega_solve_depth
--;
4761 if (!omega_reduce_with_subs
)
4763 resurrect_subs (pb
);
4764 gcc_assert (please_no_equalities_in_simplified_problems
4765 || !result
|| pb
->num_subs
== 0);
4771 /* Return true if red equations constrain the set of possible solutions.
4772 We assume that there are solutions to the black equations by
4773 themselves, so if there is no solution to the combined problem, we
4777 omega_problem_has_red_equations (omega_pb pb
)
4783 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4785 fprintf (dump_file
, "Checking for red equations:\n");
4786 omega_print_problem (dump_file
, pb
);
4789 please_no_equalities_in_simplified_problems
++;
4792 if (omega_single_result
)
4793 return_single_result
++;
4795 create_color
= true;
4796 result
= (omega_simplify_problem (pb
) == omega_false
);
4798 if (omega_single_result
)
4799 return_single_result
--;
4802 please_no_equalities_in_simplified_problems
--;
4806 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4807 fprintf (dump_file
, "Gist is FALSE\n");
4812 pb
->eqs
[0].color
= omega_red
;
4814 for (i
= pb
->num_vars
; i
> 0; i
--)
4815 pb
->eqs
[0].coef
[i
] = 0;
4817 pb
->eqs
[0].coef
[0] = 1;
4821 free_red_eliminations (pb
);
4822 gcc_assert (pb
->num_eqs
== 0);
4824 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4825 if (pb
->geqs
[e
].color
== omega_red
)
4834 for (i
= pb
->safe_vars
; i
>= 1; i
--)
4839 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4841 if (pb
->geqs
[e
].coef
[i
])
4843 if (pb
->geqs
[e
].coef
[i
] > 0)
4844 lb
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4847 ub
|= (1 + (pb
->geqs
[e
].color
== omega_red
? 1 : 0));
4851 if (ub
== 2 || lb
== 2)
4854 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4855 fprintf (dump_file
, "checks for upper/lower bounds worked!\n");
4857 if (!omega_reduce_with_subs
)
4859 resurrect_subs (pb
);
4860 gcc_assert (pb
->num_subs
== 0);
4868 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4870 "*** Doing potentially expensive elimination tests "
4871 "for red equations\n");
4873 please_no_equalities_in_simplified_problems
++;
4874 omega_eliminate_red (pb
, true);
4875 please_no_equalities_in_simplified_problems
--;
4878 gcc_assert (pb
->num_eqs
== 0);
4880 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4881 if (pb
->geqs
[e
].color
== omega_red
)
4887 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4891 "******************** Redundant Red Equations eliminated!!\n");
4894 "******************** Red Equations remain\n");
4896 omega_print_problem (dump_file
, pb
);
4899 if (!omega_reduce_with_subs
)
4901 normalize_return_type r
;
4903 resurrect_subs (pb
);
4904 r
= normalize_omega_problem (pb
);
4905 gcc_assert (r
!= normalize_false
);
4908 cleanout_wildcards (pb
);
4909 gcc_assert (pb
->num_subs
== 0);
4915 /* Calls omega_simplify_problem in approximate mode. */
4918 omega_simplify_approximate (omega_pb pb
)
4920 enum omega_result result
;
4922 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4923 fprintf (dump_file
, "(Entering approximate mode\n");
4925 in_approximate_mode
= true;
4926 result
= omega_simplify_problem (pb
);
4927 in_approximate_mode
= false;
4929 gcc_assert (pb
->num_vars
== pb
->safe_vars
);
4930 if (!omega_reduce_with_subs
)
4931 gcc_assert (pb
->num_subs
== 0);
4933 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4934 fprintf (dump_file
, "Leaving approximate mode)\n");
4940 /* Simplifies problem PB by eliminating redundant constraints and
4941 reducing the constraints system to a minimal form. Returns
4942 omega_true when the problem was successfully reduced, omega_unknown
4943 when the solver is unable to determine an answer. */
4946 omega_simplify_problem (omega_pb pb
)
4950 omega_found_reduction
= omega_false
;
4952 if (!pb
->variables_initialized
)
4953 omega_initialize_variables (pb
);
4955 if (next_key
* 3 > MAX_KEYS
)
4960 next_key
= OMEGA_MAX_VARS
+ 1;
4962 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4963 pb
->geqs
[e
].touched
= 1;
4965 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
4966 hash_master
[i
].touched
= -1;
4968 pb
->hash_version
= hash_version
;
4971 else if (pb
->hash_version
!= hash_version
)
4975 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
4976 pb
->geqs
[e
].touched
= 1;
4978 pb
->hash_version
= hash_version
;
4981 if (pb
->num_vars
> pb
->num_eqs
+ 3 * pb
->safe_vars
)
4982 omega_free_eliminations (pb
, pb
->safe_vars
);
4984 if (!may_be_red
&& pb
->num_subs
== 0 && pb
->safe_vars
== 0)
4986 omega_found_reduction
= omega_solve_problem (pb
, omega_unknown
);
4988 if (omega_found_reduction
!= omega_false
4989 && !return_single_result
)
4993 (*omega_when_reduced
) (pb
);
4996 return omega_found_reduction
;
4999 omega_solve_problem (pb
, omega_simplify
);
5001 if (omega_found_reduction
!= omega_false
)
5003 for (i
= 1; omega_safe_var_p (pb
, i
); i
++)
5004 pb
->forwarding_address
[pb
->var
[i
]] = i
;
5006 for (i
= 0; i
< pb
->num_subs
; i
++)
5007 pb
->forwarding_address
[pb
->subs
[i
].key
] = -i
- 1;
5010 if (!omega_reduce_with_subs
)
5011 gcc_assert (please_no_equalities_in_simplified_problems
5012 || omega_found_reduction
== omega_false
5013 || pb
->num_subs
== 0);
5015 return omega_found_reduction
;
5018 /* Make variable VAR unprotected: it then can be eliminated. */
5021 omega_unprotect_variable (omega_pb pb
, int var
)
5024 idx
= pb
->forwarding_address
[var
];
5031 if (idx
< pb
->num_subs
)
5033 omega_copy_eqn (&pb
->subs
[idx
], &pb
->subs
[pb
->num_subs
],
5035 pb
->forwarding_address
[pb
->subs
[idx
].key
] = -idx
- 1;
5040 int *bring_to_life
= XNEWVEC (int, OMEGA_MAX_VARS
);
5043 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5044 bring_to_life
[e
] = (pb
->subs
[e
].coef
[idx
] != 0);
5046 for (e2
= pb
->num_subs
- 1; e2
>= 0; e2
--)
5047 if (bring_to_life
[e2
])
5052 if (pb
->safe_vars
< pb
->num_vars
)
5054 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5056 pb
->geqs
[e
].coef
[pb
->num_vars
] =
5057 pb
->geqs
[e
].coef
[pb
->safe_vars
];
5059 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5062 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5064 pb
->eqs
[e
].coef
[pb
->num_vars
] =
5065 pb
->eqs
[e
].coef
[pb
->safe_vars
];
5067 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5070 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5072 pb
->subs
[e
].coef
[pb
->num_vars
] =
5073 pb
->subs
[e
].coef
[pb
->safe_vars
];
5075 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5078 pb
->var
[pb
->num_vars
] = pb
->var
[pb
->safe_vars
];
5079 pb
->forwarding_address
[pb
->var
[pb
->num_vars
]] =
5084 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5085 pb
->geqs
[e
].coef
[pb
->safe_vars
] = 0;
5087 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5088 pb
->eqs
[e
].coef
[pb
->safe_vars
] = 0;
5090 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5091 pb
->subs
[e
].coef
[pb
->safe_vars
] = 0;
5094 pb
->var
[pb
->safe_vars
] = pb
->subs
[e2
].key
;
5095 pb
->forwarding_address
[pb
->subs
[e2
].key
] = pb
->safe_vars
;
5097 omega_copy_eqn (&(pb
->eqs
[pb
->num_eqs
]), &(pb
->subs
[e2
]),
5099 pb
->eqs
[pb
->num_eqs
++].coef
[pb
->safe_vars
] = -1;
5100 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5102 if (e2
< pb
->num_subs
- 1)
5103 omega_copy_eqn (&(pb
->subs
[e2
]), &(pb
->subs
[pb
->num_subs
- 1]),
5109 omega_unprotect_1 (pb
, &idx
, NULL
);
5110 free (bring_to_life
);
5113 chain_unprotect (pb
);
5116 /* Unprotects VAR and simplifies PB. */
5119 omega_constrain_variable_sign (omega_pb pb
, enum omega_eqn_color color
,
5122 int n_vars
= pb
->num_vars
;
5124 int k
= pb
->forwarding_address
[var
];
5133 omega_copy_eqn (&pb
->geqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5135 for (j
= 0; j
<= n_vars
; j
++)
5136 pb
->geqs
[e
].coef
[j
] *= sign
;
5138 pb
->geqs
[e
].coef
[0]--;
5139 pb
->geqs
[e
].touched
= 1;
5140 pb
->geqs
[e
].color
= color
;
5145 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5146 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5147 pb
->eqs
[e
].color
= color
;
5153 omega_init_eqn_zero (&pb
->geqs
[e
], pb
->num_vars
);
5154 pb
->geqs
[e
].coef
[k
] = sign
;
5155 pb
->geqs
[e
].coef
[0] = -1;
5156 pb
->geqs
[e
].touched
= 1;
5157 pb
->geqs
[e
].color
= color
;
5162 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5163 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5164 pb
->eqs
[e
].coef
[k
] = 1;
5165 pb
->eqs
[e
].color
= color
;
5168 omega_unprotect_variable (pb
, var
);
5169 return omega_simplify_problem (pb
);
5172 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5175 omega_constrain_variable_value (omega_pb pb
, enum omega_eqn_color color
,
5179 int k
= pb
->forwarding_address
[var
];
5185 gcc_assert (pb
->num_eqs
<= OMEGA_MAX_EQS
);
5186 omega_copy_eqn (&pb
->eqs
[e
], &pb
->subs
[k
], pb
->num_vars
);
5187 pb
->eqs
[e
].coef
[0] -= value
;
5192 omega_init_eqn_zero (&pb
->eqs
[e
], pb
->num_vars
);
5193 pb
->eqs
[e
].coef
[k
] = 1;
5194 pb
->eqs
[e
].coef
[0] = -value
;
5197 pb
->eqs
[e
].color
= color
;
5200 /* Return false when the upper and lower bounds are not coupled.
5201 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5205 omega_query_variable (omega_pb pb
, int i
, int *lower_bound
, int *upper_bound
)
5207 int n_vars
= pb
->num_vars
;
5210 bool coupled
= false;
5212 *lower_bound
= neg_infinity
;
5213 *upper_bound
= pos_infinity
;
5214 i
= pb
->forwarding_address
[i
];
5220 for (j
= 1; j
<= n_vars
; j
++)
5221 if (pb
->subs
[i
].coef
[j
] != 0)
5224 *upper_bound
= *lower_bound
= pb
->subs
[i
].coef
[0];
5228 for (e
= pb
->num_subs
- 1; e
>= 0; e
--)
5229 if (pb
->subs
[e
].coef
[i
] != 0)
5235 for (e
= pb
->num_eqs
- 1; e
>= 0; e
--)
5236 if (pb
->eqs
[e
].coef
[i
] != 0)
5240 for (j
= 1; j
<= n_vars
; j
++)
5241 if (i
!= j
&& pb
->eqs
[e
].coef
[j
] != 0)
5252 *lower_bound
= *upper_bound
=
5253 -pb
->eqs
[e
].coef
[i
] * pb
->eqs
[e
].coef
[0];
5258 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5259 if (pb
->geqs
[e
].coef
[i
] != 0)
5261 if (pb
->geqs
[e
].key
== i
)
5262 *lower_bound
= MAX (*lower_bound
, -pb
->geqs
[e
].coef
[0]);
5264 else if (pb
->geqs
[e
].key
== -i
)
5265 *upper_bound
= MIN (*upper_bound
, pb
->geqs
[e
].coef
[0]);
5274 /* Sets the lower bound L and upper bound U for the values of variable
5275 I, and sets COULD_BE_ZERO to true if variable I might take value
5276 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5280 query_coupled_variable (omega_pb pb
, int i
, int *l
, int *u
,
5281 bool *could_be_zero
, int lower_bound
, int upper_bound
)
5288 /* Preconditions. */
5289 gcc_assert (abs (pb
->forwarding_address
[i
]) == 1
5290 && pb
->num_vars
+ pb
->num_subs
== 2
5291 && pb
->num_eqs
+ pb
->num_subs
== 1);
5293 /* Define variable I in terms of variable V. */
5294 if (pb
->forwarding_address
[i
] == -1)
5303 sign
= -eqn
->coef
[1];
5307 for (e
= pb
->num_geqs
- 1; e
>= 0; e
--)
5308 if (pb
->geqs
[e
].coef
[v
] != 0)
5310 if (pb
->geqs
[e
].coef
[v
] == 1)
5311 lower_bound
= MAX (lower_bound
, -pb
->geqs
[e
].coef
[0]);
5314 upper_bound
= MIN (upper_bound
, pb
->geqs
[e
].coef
[0]);
5317 if (lower_bound
> upper_bound
)
5325 if (lower_bound
== neg_infinity
)
5327 if (eqn
->coef
[v
] > 0)
5328 b1
= sign
* neg_infinity
;
5331 b1
= -sign
* neg_infinity
;
5334 b1
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * lower_bound
);
5336 if (upper_bound
== pos_infinity
)
5338 if (eqn
->coef
[v
] > 0)
5339 b2
= sign
* pos_infinity
;
5342 b2
= -sign
* pos_infinity
;
5345 b2
= sign
* (eqn
->coef
[0] + eqn
->coef
[v
] * upper_bound
);
5347 *l
= MAX (*l
, b1
<= b2
? b1
: b2
);
5348 *u
= MIN (*u
, b1
<= b2
? b2
: b1
);
5350 *could_be_zero
= (*l
<= 0 && 0 <= *u
5351 && int_mod (eqn
->coef
[0], abs (eqn
->coef
[v
])) == 0);
5354 /* Return false when a lower bound L and an upper bound U for variable
5355 I in problem PB have been initialized. */
5358 omega_query_variable_bounds (omega_pb pb
, int i
, int *l
, int *u
)
5363 if (!omega_query_variable (pb
, i
, l
, u
)
5364 || (pb
->num_vars
== 1 && pb
->forwarding_address
[i
] == 1))
5367 if (abs (pb
->forwarding_address
[i
]) == 1
5368 && pb
->num_vars
+ pb
->num_subs
== 2
5369 && pb
->num_eqs
+ pb
->num_subs
== 1)
5372 query_coupled_variable (pb
, i
, l
, u
, &could_be_zero
, neg_infinity
,
5380 /* For problem PB, return an integer that represents the classic data
5381 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5382 masks that are added to the result. When DIST_KNOWN is true, DIST
5383 is set to the classic data dependence distance. LOWER_BOUND and
5384 UPPER_BOUND are bounds on the value of variable I, for example, it
5385 is possible to narrow the iteration domain with safe approximations
5386 of loop counts, and thus discard some data dependences that cannot
5390 omega_query_variable_signs (omega_pb pb
, int i
, int dd_lt
,
5391 int dd_eq
, int dd_gt
, int lower_bound
,
5392 int upper_bound
, bool *dist_known
, int *dist
)
5401 omega_query_variable (pb
, i
, &l
, &u
);
5402 query_coupled_variable (pb
, i
, &l
, &u
, &could_be_zero
, lower_bound
,
5421 *dist_known
= false;
5426 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5427 safe variables. Safe variables are not eliminated during the
5428 Fourier-Motzkin elimination. Safe variables are all those
5429 variables that are placed at the beginning of the array of
5430 variables: P->var[0, ..., NPROT - 1]. */
5433 omega_alloc_problem (int nvars
, int nprot
)
5437 gcc_assert (nvars
<= OMEGA_MAX_VARS
);
5438 omega_initialize ();
5440 /* Allocate and initialize PB. */
5441 pb
= XCNEW (struct omega_pb_d
);
5442 pb
->var
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5443 pb
->forwarding_address
= XCNEWVEC (int, OMEGA_MAX_VARS
+ 2);
5444 pb
->geqs
= omega_alloc_eqns (0, OMEGA_MAX_GEQS
);
5445 pb
->eqs
= omega_alloc_eqns (0, OMEGA_MAX_EQS
);
5446 pb
->subs
= omega_alloc_eqns (0, OMEGA_MAX_VARS
+ 1);
5448 pb
->hash_version
= hash_version
;
5449 pb
->num_vars
= nvars
;
5450 pb
->safe_vars
= nprot
;
5451 pb
->variables_initialized
= false;
5452 pb
->variables_freed
= false;
5459 /* Keeps the state of the initialization. */
5460 static bool omega_initialized
= false;
5462 /* Initialization of the Omega solver. */
5465 omega_initialize (void)
5469 if (omega_initialized
)
5473 next_key
= OMEGA_MAX_VARS
+ 1;
5474 packing
= XCNEWVEC (int, OMEGA_MAX_VARS
);
5475 fast_lookup
= XCNEWVEC (int, MAX_KEYS
* 2);
5476 fast_lookup_red
= XCNEWVEC (int, MAX_KEYS
* 2);
5477 hash_master
= omega_alloc_eqns (0, HASH_TABLE_SIZE
);
5479 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++)
5480 hash_master
[i
].touched
= -1;
5482 sprintf (wild_name
[0], "1");
5483 sprintf (wild_name
[1], "a");
5484 sprintf (wild_name
[2], "b");
5485 sprintf (wild_name
[3], "c");
5486 sprintf (wild_name
[4], "d");
5487 sprintf (wild_name
[5], "e");
5488 sprintf (wild_name
[6], "f");
5489 sprintf (wild_name
[7], "g");
5490 sprintf (wild_name
[8], "h");
5491 sprintf (wild_name
[9], "i");
5492 sprintf (wild_name
[10], "j");
5493 sprintf (wild_name
[11], "k");
5494 sprintf (wild_name
[12], "l");
5495 sprintf (wild_name
[13], "m");
5496 sprintf (wild_name
[14], "n");
5497 sprintf (wild_name
[15], "o");
5498 sprintf (wild_name
[16], "p");
5499 sprintf (wild_name
[17], "q");
5500 sprintf (wild_name
[18], "r");
5501 sprintf (wild_name
[19], "s");
5502 sprintf (wild_name
[20], "t");
5503 sprintf (wild_name
[40 - 1], "alpha");
5504 sprintf (wild_name
[40 - 2], "beta");
5505 sprintf (wild_name
[40 - 3], "gamma");
5506 sprintf (wild_name
[40 - 4], "delta");
5507 sprintf (wild_name
[40 - 5], "tau");
5508 sprintf (wild_name
[40 - 6], "sigma");
5509 sprintf (wild_name
[40 - 7], "chi");
5510 sprintf (wild_name
[40 - 8], "omega");
5511 sprintf (wild_name
[40 - 9], "pi");
5512 sprintf (wild_name
[40 - 10], "ni");
5513 sprintf (wild_name
[40 - 11], "Alpha");
5514 sprintf (wild_name
[40 - 12], "Beta");
5515 sprintf (wild_name
[40 - 13], "Gamma");
5516 sprintf (wild_name
[40 - 14], "Delta");
5517 sprintf (wild_name
[40 - 15], "Tau");
5518 sprintf (wild_name
[40 - 16], "Sigma");
5519 sprintf (wild_name
[40 - 17], "Chi");
5520 sprintf (wild_name
[40 - 18], "Omega");
5521 sprintf (wild_name
[40 - 19], "xxx");
5523 omega_initialized
= true;