[asan] Avoid instrumenting duplicated memory access in the same basic block
[gcc.git] / gcc / omega.c
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.
4
5 This code has no license restrictions, and is considered public
6 domain.
7
8 Changes copyright (C) 2005-2013 Free Software Foundation, Inc.
9 Contributed by Sebastian Pop <sebastian.pop@inria.fr>
10
11 This file is part of GCC.
12
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
16 version.
17
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
21 for more details.
22
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/>. */
26
27 /* For a detailed description, see "Constraint-Based Array Dependence
28 Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
29 Wonnacott's thesis:
30 ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
31 */
32
33 #include "config.h"
34 #include "system.h"
35 #include "coretypes.h"
36 #include "tree.h"
37 #include "diagnostic-core.h"
38 #include "dumpfile.h"
39 #include "omega.h"
40
41 /* When set to true, keep substitution variables. When set to false,
42 resurrect substitution variables (convert substitutions back to EQs). */
43 static bool omega_reduce_with_subs = true;
44
45 /* When set to true, omega_simplify_problem checks for problem with no
46 solutions, calling verify_omega_pb. */
47 static bool omega_verify_simplification = false;
48
49 /* When set to true, only produce a single simplified result. */
50 static bool omega_single_result = false;
51
52 /* Set return_single_result to 1 when omega_single_result is true. */
53 static int return_single_result = 0;
54
55 /* Hash table for equations generated by the solver. */
56 #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
57 #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
58 static eqn hash_master;
59 static int next_key;
60 static int hash_version = 0;
61
62 /* Set to true for making the solver enter in approximation mode. */
63 static bool in_approximate_mode = false;
64
65 /* When set to zero, the solver is allowed to add new equalities to
66 the problem to be solved. */
67 static int conservative = 0;
68
69 /* Set to omega_true when the problem was successfully reduced, set to
70 omega_unknown when the solver is unable to determine an answer. */
71 static enum omega_result omega_found_reduction;
72
73 /* Set to true when the solver is allowed to add omega_red equations. */
74 static bool create_color = false;
75
76 /* Set to nonzero when the problem to be solved can be reduced. */
77 static int may_be_red = 0;
78
79 /* When false, there should be no substitution equations in the
80 simplified problem. */
81 static int please_no_equalities_in_simplified_problems = 0;
82
83 /* Variables names for pretty printing. */
84 static char wild_name[200][40];
85
86 /* Pointer to the void problem. */
87 static omega_pb no_problem = (omega_pb) 0;
88
89 /* Pointer to the problem to be solved. */
90 static omega_pb original_problem = (omega_pb) 0;
91
92
93 /* Return the integer A divided by B. */
94
95 static inline int
96 int_div (int a, int b)
97 {
98 if (a > 0)
99 return a/b;
100 else
101 return -((-a + b - 1)/b);
102 }
103
104 /* Return the integer A modulo B. */
105
106 static inline int
107 int_mod (int a, int b)
108 {
109 return a - b * int_div (a, b);
110 }
111
112 /* Test whether equation E is red. */
113
114 static inline bool
115 omega_eqn_is_red (eqn e, int desired_res)
116 {
117 return (desired_res == omega_simplify && e->color == omega_red);
118 }
119
120 /* Return a string for VARIABLE. */
121
122 static inline char *
123 omega_var_to_str (int variable)
124 {
125 if (0 <= variable && variable <= 20)
126 return wild_name[variable];
127
128 if (-20 < variable && variable < 0)
129 return wild_name[40 + variable];
130
131 /* Collapse all the entries that would have overflowed. */
132 return wild_name[21];
133 }
134
135 /* Return a string for variable I in problem PB. */
136
137 static inline char *
138 omega_variable_to_str (omega_pb pb, int i)
139 {
140 return omega_var_to_str (pb->var[i]);
141 }
142
143 /* Do nothing function: used for default initializations. */
144
145 void
146 omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
147 {
148 }
149
150 void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
151
152 /* Print to FILE from PB equation E with all its coefficients
153 multiplied by C. */
154
155 static void
156 omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
157 {
158 int i;
159 bool first = true;
160 int n = pb->num_vars;
161 int went_first = -1;
162
163 for (i = 1; i <= n; i++)
164 if (c * e->coef[i] > 0)
165 {
166 first = false;
167 went_first = i;
168
169 if (c * e->coef[i] == 1)
170 fprintf (file, "%s", omega_variable_to_str (pb, i));
171 else
172 fprintf (file, "%d * %s", c * e->coef[i],
173 omega_variable_to_str (pb, i));
174 break;
175 }
176
177 for (i = 1; i <= n; i++)
178 if (i != went_first && c * e->coef[i] != 0)
179 {
180 if (!first && c * e->coef[i] > 0)
181 fprintf (file, " + ");
182
183 first = false;
184
185 if (c * e->coef[i] == 1)
186 fprintf (file, "%s", omega_variable_to_str (pb, i));
187 else if (c * e->coef[i] == -1)
188 fprintf (file, " - %s", omega_variable_to_str (pb, i));
189 else
190 fprintf (file, "%d * %s", c * e->coef[i],
191 omega_variable_to_str (pb, i));
192 }
193
194 if (!first && c * e->coef[0] > 0)
195 fprintf (file, " + ");
196
197 if (first || c * e->coef[0] != 0)
198 fprintf (file, "%d", c * e->coef[0]);
199 }
200
201 /* Print to FILE the equation E of problem PB. */
202
203 void
204 omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
205 {
206 int i;
207 int n = pb->num_vars + extra;
208 bool is_lt = test && e->coef[0] == -1;
209 bool first;
210
211 if (test)
212 {
213 if (e->touched)
214 fprintf (file, "!");
215
216 else if (e->key != 0)
217 fprintf (file, "%d: ", e->key);
218 }
219
220 if (e->color == omega_red)
221 fprintf (file, "[");
222
223 first = true;
224
225 for (i = is_lt ? 1 : 0; i <= n; i++)
226 if (e->coef[i] < 0)
227 {
228 if (!first)
229 fprintf (file, " + ");
230 else
231 first = false;
232
233 if (i == 0)
234 fprintf (file, "%d", -e->coef[i]);
235 else if (e->coef[i] == -1)
236 fprintf (file, "%s", omega_variable_to_str (pb, i));
237 else
238 fprintf (file, "%d * %s", -e->coef[i],
239 omega_variable_to_str (pb, i));
240 }
241
242 if (first)
243 {
244 if (is_lt)
245 {
246 fprintf (file, "1");
247 is_lt = false;
248 }
249 else
250 fprintf (file, "0");
251 }
252
253 if (test == 0)
254 fprintf (file, " = ");
255 else if (is_lt)
256 fprintf (file, " < ");
257 else
258 fprintf (file, " <= ");
259
260 first = true;
261
262 for (i = 0; i <= n; i++)
263 if (e->coef[i] > 0)
264 {
265 if (!first)
266 fprintf (file, " + ");
267 else
268 first = false;
269
270 if (i == 0)
271 fprintf (file, "%d", e->coef[i]);
272 else if (e->coef[i] == 1)
273 fprintf (file, "%s", omega_variable_to_str (pb, i));
274 else
275 fprintf (file, "%d * %s", e->coef[i],
276 omega_variable_to_str (pb, i));
277 }
278
279 if (first)
280 fprintf (file, "0");
281
282 if (e->color == omega_red)
283 fprintf (file, "]");
284 }
285
286 /* Print to FILE all the variables of problem PB. */
287
288 static void
289 omega_print_vars (FILE *file, omega_pb pb)
290 {
291 int i;
292
293 fprintf (file, "variables = ");
294
295 if (pb->safe_vars > 0)
296 fprintf (file, "protected (");
297
298 for (i = 1; i <= pb->num_vars; i++)
299 {
300 fprintf (file, "%s", omega_variable_to_str (pb, i));
301
302 if (i == pb->safe_vars)
303 fprintf (file, ")");
304
305 if (i < pb->num_vars)
306 fprintf (file, ", ");
307 }
308
309 fprintf (file, "\n");
310 }
311
312 /* Debug problem PB. */
313
314 DEBUG_FUNCTION void
315 debug_omega_problem (omega_pb pb)
316 {
317 omega_print_problem (stderr, pb);
318 }
319
320 /* Print to FILE problem PB. */
321
322 void
323 omega_print_problem (FILE *file, omega_pb pb)
324 {
325 int e;
326
327 if (!pb->variables_initialized)
328 omega_initialize_variables (pb);
329
330 omega_print_vars (file, pb);
331
332 for (e = 0; e < pb->num_eqs; e++)
333 {
334 omega_print_eq (file, pb, &pb->eqs[e]);
335 fprintf (file, "\n");
336 }
337
338 fprintf (file, "Done with EQ\n");
339
340 for (e = 0; e < pb->num_geqs; e++)
341 {
342 omega_print_geq (file, pb, &pb->geqs[e]);
343 fprintf (file, "\n");
344 }
345
346 fprintf (file, "Done with GEQ\n");
347
348 for (e = 0; e < pb->num_subs; e++)
349 {
350 eqn eq = &pb->subs[e];
351
352 if (eq->color == omega_red)
353 fprintf (file, "[");
354
355 if (eq->key > 0)
356 fprintf (file, "%s := ", omega_var_to_str (eq->key));
357 else
358 fprintf (file, "#%d := ", eq->key);
359
360 omega_print_term (file, pb, eq, 1);
361
362 if (eq->color == omega_red)
363 fprintf (file, "]");
364
365 fprintf (file, "\n");
366 }
367 }
368
369 /* Return the number of equations in PB tagged omega_red. */
370
371 int
372 omega_count_red_equations (omega_pb pb)
373 {
374 int e, i;
375 int result = 0;
376
377 for (e = 0; e < pb->num_eqs; e++)
378 if (pb->eqs[e].color == omega_red)
379 {
380 for (i = pb->num_vars; i > 0; i--)
381 if (pb->geqs[e].coef[i])
382 break;
383
384 if (i == 0 && pb->geqs[e].coef[0] == 1)
385 return 0;
386 else
387 result += 2;
388 }
389
390 for (e = 0; e < pb->num_geqs; e++)
391 if (pb->geqs[e].color == omega_red)
392 result += 1;
393
394 for (e = 0; e < pb->num_subs; e++)
395 if (pb->subs[e].color == omega_red)
396 result += 2;
397
398 return result;
399 }
400
401 /* Print to FILE all the equations in PB that are tagged omega_red. */
402
403 void
404 omega_print_red_equations (FILE *file, omega_pb pb)
405 {
406 int e;
407
408 if (!pb->variables_initialized)
409 omega_initialize_variables (pb);
410
411 omega_print_vars (file, pb);
412
413 for (e = 0; e < pb->num_eqs; e++)
414 if (pb->eqs[e].color == omega_red)
415 {
416 omega_print_eq (file, pb, &pb->eqs[e]);
417 fprintf (file, "\n");
418 }
419
420 for (e = 0; e < pb->num_geqs; e++)
421 if (pb->geqs[e].color == omega_red)
422 {
423 omega_print_geq (file, pb, &pb->geqs[e]);
424 fprintf (file, "\n");
425 }
426
427 for (e = 0; e < pb->num_subs; e++)
428 if (pb->subs[e].color == omega_red)
429 {
430 eqn eq = &pb->subs[e];
431 fprintf (file, "[");
432
433 if (eq->key > 0)
434 fprintf (file, "%s := ", omega_var_to_str (eq->key));
435 else
436 fprintf (file, "#%d := ", eq->key);
437
438 omega_print_term (file, pb, eq, 1);
439 fprintf (file, "]\n");
440 }
441 }
442
443 /* Pretty print PB to FILE. */
444
445 void
446 omega_pretty_print_problem (FILE *file, omega_pb pb)
447 {
448 int e, v, v1, v2, v3, t;
449 bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
450 int stuffPrinted = 0;
451 bool change;
452
453 typedef enum {
454 none, le, lt
455 } partial_order_type;
456
457 partial_order_type **po = XNEWVEC (partial_order_type *,
458 OMEGA_MAX_VARS * OMEGA_MAX_VARS);
459 int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
460 int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
461 int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
462 int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
463 int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
464 int i, m;
465 bool multiprint;
466
467 if (!pb->variables_initialized)
468 omega_initialize_variables (pb);
469
470 if (pb->num_vars > 0)
471 {
472 omega_eliminate_redundant (pb, false);
473
474 for (e = 0; e < pb->num_eqs; e++)
475 {
476 if (stuffPrinted)
477 fprintf (file, "; ");
478
479 stuffPrinted = 1;
480 omega_print_eq (file, pb, &pb->eqs[e]);
481 }
482
483 for (e = 0; e < pb->num_geqs; e++)
484 live[e] = true;
485
486 while (1)
487 {
488 for (v = 1; v <= pb->num_vars; v++)
489 {
490 last_links[v] = first_links[v] = 0;
491 chain_length[v] = 0;
492
493 for (v2 = 1; v2 <= pb->num_vars; v2++)
494 po[v][v2] = none;
495 }
496
497 for (e = 0; e < pb->num_geqs; e++)
498 if (live[e])
499 {
500 for (v = 1; v <= pb->num_vars; v++)
501 if (pb->geqs[e].coef[v] == 1)
502 first_links[v]++;
503 else if (pb->geqs[e].coef[v] == -1)
504 last_links[v]++;
505
506 v1 = pb->num_vars;
507
508 while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
509 v1--;
510
511 v2 = v1 - 1;
512
513 while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
514 v2--;
515
516 v3 = v2 - 1;
517
518 while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
519 v3--;
520
521 if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
522 || v2 <= 0 || v3 > 0
523 || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
524 {
525 /* Not a partial order relation. */
526 }
527 else
528 {
529 if (pb->geqs[e].coef[v1] == 1)
530 {
531 v3 = v2;
532 v2 = v1;
533 v1 = v3;
534 }
535
536 /* Relation is v1 <= v2 or v1 < v2. */
537 po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
538 po_eq[v1][v2] = e;
539 }
540 }
541 for (v = 1; v <= pb->num_vars; v++)
542 chain_length[v] = last_links[v];
543
544 /* Just in case pb->num_vars <= 0. */
545 change = false;
546 for (t = 0; t < pb->num_vars; t++)
547 {
548 change = false;
549
550 for (v1 = 1; v1 <= pb->num_vars; v1++)
551 for (v2 = 1; v2 <= pb->num_vars; v2++)
552 if (po[v1][v2] != none &&
553 chain_length[v1] <= chain_length[v2])
554 {
555 chain_length[v1] = chain_length[v2] + 1;
556 change = true;
557 }
558 }
559
560 /* Caught in cycle. */
561 gcc_assert (!change);
562
563 for (v1 = 1; v1 <= pb->num_vars; v1++)
564 if (chain_length[v1] == 0)
565 first_links[v1] = 0;
566
567 v = 1;
568
569 for (v1 = 2; v1 <= pb->num_vars; v1++)
570 if (chain_length[v1] + first_links[v1] >
571 chain_length[v] + first_links[v])
572 v = v1;
573
574 if (chain_length[v] + first_links[v] == 0)
575 break;
576
577 if (stuffPrinted)
578 fprintf (file, "; ");
579
580 stuffPrinted = 1;
581
582 /* Chain starts at v. */
583 {
584 int tmp;
585 bool first = true;
586
587 for (e = 0; e < pb->num_geqs; e++)
588 if (live[e] && pb->geqs[e].coef[v] == 1)
589 {
590 if (!first)
591 fprintf (file, ", ");
592
593 tmp = pb->geqs[e].coef[v];
594 pb->geqs[e].coef[v] = 0;
595 omega_print_term (file, pb, &pb->geqs[e], -1);
596 pb->geqs[e].coef[v] = tmp;
597 live[e] = false;
598 first = false;
599 }
600
601 if (!first)
602 fprintf (file, " <= ");
603 }
604
605 /* Find chain. */
606 chain[0] = v;
607 m = 1;
608 while (1)
609 {
610 /* Print chain. */
611 for (v2 = 1; v2 <= pb->num_vars; v2++)
612 if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
613 break;
614
615 if (v2 > pb->num_vars)
616 break;
617
618 chain[m++] = v2;
619 v = v2;
620 }
621
622 fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
623
624 for (multiprint = false, i = 1; i < m; i++)
625 {
626 v = chain[i - 1];
627 v2 = chain[i];
628
629 if (po[v][v2] == le)
630 fprintf (file, " <= ");
631 else
632 fprintf (file, " < ");
633
634 fprintf (file, "%s", omega_variable_to_str (pb, v2));
635 live[po_eq[v][v2]] = false;
636
637 if (!multiprint && i < m - 1)
638 for (v3 = 1; v3 <= pb->num_vars; v3++)
639 {
640 if (v == v3 || v2 == v3
641 || po[v][v2] != po[v][v3]
642 || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
643 continue;
644
645 fprintf (file, ",%s", omega_variable_to_str (pb, v3));
646 live[po_eq[v][v3]] = false;
647 live[po_eq[v3][chain[i + 1]]] = false;
648 multiprint = true;
649 }
650 else
651 multiprint = false;
652 }
653
654 v = chain[m - 1];
655 /* Print last_links. */
656 {
657 int tmp;
658 bool first = true;
659
660 for (e = 0; e < pb->num_geqs; e++)
661 if (live[e] && pb->geqs[e].coef[v] == -1)
662 {
663 if (!first)
664 fprintf (file, ", ");
665 else
666 fprintf (file, " <= ");
667
668 tmp = pb->geqs[e].coef[v];
669 pb->geqs[e].coef[v] = 0;
670 omega_print_term (file, pb, &pb->geqs[e], 1);
671 pb->geqs[e].coef[v] = tmp;
672 live[e] = false;
673 first = false;
674 }
675 }
676 }
677
678 for (e = 0; e < pb->num_geqs; e++)
679 if (live[e])
680 {
681 if (stuffPrinted)
682 fprintf (file, "; ");
683 stuffPrinted = 1;
684 omega_print_geq (file, pb, &pb->geqs[e]);
685 }
686
687 for (e = 0; e < pb->num_subs; e++)
688 {
689 eqn eq = &pb->subs[e];
690
691 if (stuffPrinted)
692 fprintf (file, "; ");
693
694 stuffPrinted = 1;
695
696 if (eq->key > 0)
697 fprintf (file, "%s := ", omega_var_to_str (eq->key));
698 else
699 fprintf (file, "#%d := ", eq->key);
700
701 omega_print_term (file, pb, eq, 1);
702 }
703 }
704
705 free (live);
706 free (po);
707 free (po_eq);
708 free (last_links);
709 free (first_links);
710 free (chain_length);
711 free (chain);
712 }
713
714 /* Assign to variable I in PB the next wildcard name. The name of a
715 wildcard is a negative number. */
716 static int next_wild_card = 0;
717
718 static void
719 omega_name_wild_card (omega_pb pb, int i)
720 {
721 --next_wild_card;
722 if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
723 next_wild_card = -1;
724 pb->var[i] = next_wild_card;
725 }
726
727 /* Return the index of the last protected (or safe) variable in PB,
728 after having added a new wildcard variable. */
729
730 static int
731 omega_add_new_wild_card (omega_pb pb)
732 {
733 int e;
734 int i = ++pb->safe_vars;
735 pb->num_vars++;
736
737 /* Make a free place in the protected (safe) variables, by moving
738 the non protected variable pointed by "I" at the end, ie. at
739 offset pb->num_vars. */
740 if (pb->num_vars != i)
741 {
742 /* Move "I" for all the inequalities. */
743 for (e = pb->num_geqs - 1; e >= 0; e--)
744 {
745 if (pb->geqs[e].coef[i])
746 pb->geqs[e].touched = 1;
747
748 pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
749 }
750
751 /* Move "I" for all the equalities. */
752 for (e = pb->num_eqs - 1; e >= 0; e--)
753 pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
754
755 /* Move "I" for all the substitutions. */
756 for (e = pb->num_subs - 1; e >= 0; e--)
757 pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
758
759 /* Move the identifier. */
760 pb->var[pb->num_vars] = pb->var[i];
761 }
762
763 /* Initialize at zero all the coefficients */
764 for (e = pb->num_geqs - 1; e >= 0; e--)
765 pb->geqs[e].coef[i] = 0;
766
767 for (e = pb->num_eqs - 1; e >= 0; e--)
768 pb->eqs[e].coef[i] = 0;
769
770 for (e = pb->num_subs - 1; e >= 0; e--)
771 pb->subs[e].coef[i] = 0;
772
773 /* And give it a name. */
774 omega_name_wild_card (pb, i);
775 return i;
776 }
777
778 /* Delete inequality E from problem PB that has N_VARS variables. */
779
780 static void
781 omega_delete_geq (omega_pb pb, int e, int n_vars)
782 {
783 if (dump_file && (dump_flags & TDF_DETAILS))
784 {
785 fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
786 omega_print_geq (dump_file, pb, &pb->geqs[e]);
787 fprintf (dump_file, "\n");
788 }
789
790 if (e < pb->num_geqs - 1)
791 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
792
793 pb->num_geqs--;
794 }
795
796 /* Delete extra inequality E from problem PB that has N_VARS
797 variables. */
798
799 static void
800 omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
801 {
802 if (dump_file && (dump_flags & TDF_DETAILS))
803 {
804 fprintf (dump_file, "Deleting %d: ",e);
805 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
806 fprintf (dump_file, "\n");
807 }
808
809 if (e < pb->num_geqs - 1)
810 omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
811
812 pb->num_geqs--;
813 }
814
815
816 /* Remove variable I from problem PB. */
817
818 static void
819 omega_delete_variable (omega_pb pb, int i)
820 {
821 int n_vars = pb->num_vars;
822 int e;
823
824 if (omega_safe_var_p (pb, i))
825 {
826 int j = pb->safe_vars;
827
828 for (e = pb->num_geqs - 1; e >= 0; e--)
829 {
830 pb->geqs[e].touched = 1;
831 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
832 pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
833 }
834
835 for (e = pb->num_eqs - 1; e >= 0; e--)
836 {
837 pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
838 pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
839 }
840
841 for (e = pb->num_subs - 1; e >= 0; e--)
842 {
843 pb->subs[e].coef[i] = pb->subs[e].coef[j];
844 pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
845 }
846
847 pb->var[i] = pb->var[j];
848 pb->var[j] = pb->var[n_vars];
849 }
850 else if (i < n_vars)
851 {
852 for (e = pb->num_geqs - 1; e >= 0; e--)
853 if (pb->geqs[e].coef[n_vars])
854 {
855 pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
856 pb->geqs[e].touched = 1;
857 }
858
859 for (e = pb->num_eqs - 1; e >= 0; e--)
860 pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
861
862 for (e = pb->num_subs - 1; e >= 0; e--)
863 pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
864
865 pb->var[i] = pb->var[n_vars];
866 }
867
868 if (omega_safe_var_p (pb, i))
869 pb->safe_vars--;
870
871 pb->num_vars--;
872 }
873
874 /* Because the coefficients of an equation are sparse, PACKING records
875 indices for non null coefficients. */
876 static int *packing;
877
878 /* Set up the coefficients of PACKING, following the coefficients of
879 equation EQN that has NUM_VARS variables. */
880
881 static inline int
882 setup_packing (eqn eqn, int num_vars)
883 {
884 int k;
885 int n = 0;
886
887 for (k = num_vars; k >= 0; k--)
888 if (eqn->coef[k])
889 packing[n++] = k;
890
891 return n;
892 }
893
894 /* Computes a linear combination of EQ and SUB at VAR with coefficient
895 C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
896 non null indices of SUB stored in PACKING. */
897
898 static inline void
899 omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
900 int top_var)
901 {
902 if (eq->coef[var] != 0)
903 {
904 if (eq->color == omega_black)
905 *found_black = true;
906 else
907 {
908 int j, k = eq->coef[var];
909
910 eq->coef[var] = 0;
911
912 for (j = top_var; j >= 0; j--)
913 eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
914 }
915 }
916 }
917
918 /* Substitute in PB variable VAR with "C * SUB". */
919
920 static void
921 omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
922 {
923 int e, top_var = setup_packing (sub, pb->num_vars);
924
925 *found_black = false;
926
927 if (dump_file && (dump_flags & TDF_DETAILS))
928 {
929 if (sub->color == omega_red)
930 fprintf (dump_file, "[");
931
932 fprintf (dump_file, "substituting using %s := ",
933 omega_variable_to_str (pb, var));
934 omega_print_term (dump_file, pb, sub, -c);
935
936 if (sub->color == omega_red)
937 fprintf (dump_file, "]");
938
939 fprintf (dump_file, "\n");
940 omega_print_vars (dump_file, pb);
941 }
942
943 for (e = pb->num_eqs - 1; e >= 0; e--)
944 {
945 eqn eqn = &(pb->eqs[e]);
946
947 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
948
949 if (dump_file && (dump_flags & TDF_DETAILS))
950 {
951 omega_print_eq (dump_file, pb, eqn);
952 fprintf (dump_file, "\n");
953 }
954 }
955
956 for (e = pb->num_geqs - 1; e >= 0; e--)
957 {
958 eqn eqn = &(pb->geqs[e]);
959
960 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
961
962 if (eqn->coef[var] && eqn->color == omega_red)
963 eqn->touched = 1;
964
965 if (dump_file && (dump_flags & TDF_DETAILS))
966 {
967 omega_print_geq (dump_file, pb, eqn);
968 fprintf (dump_file, "\n");
969 }
970 }
971
972 for (e = pb->num_subs - 1; e >= 0; e--)
973 {
974 eqn eqn = &(pb->subs[e]);
975
976 omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
977
978 if (dump_file && (dump_flags & TDF_DETAILS))
979 {
980 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
981 omega_print_term (dump_file, pb, eqn, 1);
982 fprintf (dump_file, "\n");
983 }
984 }
985
986 if (dump_file && (dump_flags & TDF_DETAILS))
987 fprintf (dump_file, "---\n\n");
988
989 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
990 *found_black = true;
991 }
992
993 /* Substitute in PB variable VAR with "C * SUB". */
994
995 static void
996 omega_substitute (omega_pb pb, eqn sub, int var, int c)
997 {
998 int e, j, j0;
999 int top_var = setup_packing (sub, pb->num_vars);
1000
1001 if (dump_file && (dump_flags & TDF_DETAILS))
1002 {
1003 fprintf (dump_file, "substituting using %s := ",
1004 omega_variable_to_str (pb, var));
1005 omega_print_term (dump_file, pb, sub, -c);
1006 fprintf (dump_file, "\n");
1007 omega_print_vars (dump_file, pb);
1008 }
1009
1010 if (top_var < 0)
1011 {
1012 for (e = pb->num_eqs - 1; e >= 0; e--)
1013 pb->eqs[e].coef[var] = 0;
1014
1015 for (e = pb->num_geqs - 1; e >= 0; e--)
1016 if (pb->geqs[e].coef[var] != 0)
1017 {
1018 pb->geqs[e].touched = 1;
1019 pb->geqs[e].coef[var] = 0;
1020 }
1021
1022 for (e = pb->num_subs - 1; e >= 0; e--)
1023 pb->subs[e].coef[var] = 0;
1024
1025 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1026 {
1027 int k;
1028 eqn eqn = &(pb->subs[pb->num_subs++]);
1029
1030 for (k = pb->num_vars; k >= 0; k--)
1031 eqn->coef[k] = 0;
1032
1033 eqn->key = pb->var[var];
1034 eqn->color = omega_black;
1035 }
1036 }
1037 else if (top_var == 0 && packing[0] == 0)
1038 {
1039 c = -sub->coef[0] * c;
1040
1041 for (e = pb->num_eqs - 1; e >= 0; e--)
1042 {
1043 pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
1044 pb->eqs[e].coef[var] = 0;
1045 }
1046
1047 for (e = pb->num_geqs - 1; e >= 0; e--)
1048 if (pb->geqs[e].coef[var] != 0)
1049 {
1050 pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
1051 pb->geqs[e].coef[var] = 0;
1052 pb->geqs[e].touched = 1;
1053 }
1054
1055 for (e = pb->num_subs - 1; e >= 0; e--)
1056 {
1057 pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
1058 pb->subs[e].coef[var] = 0;
1059 }
1060
1061 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1062 {
1063 int k;
1064 eqn eqn = &(pb->subs[pb->num_subs++]);
1065
1066 for (k = pb->num_vars; k >= 1; k--)
1067 eqn->coef[k] = 0;
1068
1069 eqn->coef[0] = c;
1070 eqn->key = pb->var[var];
1071 eqn->color = omega_black;
1072 }
1073
1074 if (dump_file && (dump_flags & TDF_DETAILS))
1075 {
1076 fprintf (dump_file, "---\n\n");
1077 omega_print_problem (dump_file, pb);
1078 fprintf (dump_file, "===\n\n");
1079 }
1080 }
1081 else
1082 {
1083 for (e = pb->num_eqs - 1; e >= 0; e--)
1084 {
1085 eqn eqn = &(pb->eqs[e]);
1086 int k = eqn->coef[var];
1087
1088 if (k != 0)
1089 {
1090 k = c * k;
1091 eqn->coef[var] = 0;
1092
1093 for (j = top_var; j >= 0; j--)
1094 {
1095 j0 = packing[j];
1096 eqn->coef[j0] -= sub->coef[j0] * k;
1097 }
1098 }
1099
1100 if (dump_file && (dump_flags & TDF_DETAILS))
1101 {
1102 omega_print_eq (dump_file, pb, eqn);
1103 fprintf (dump_file, "\n");
1104 }
1105 }
1106
1107 for (e = pb->num_geqs - 1; e >= 0; e--)
1108 {
1109 eqn eqn = &(pb->geqs[e]);
1110 int k = eqn->coef[var];
1111
1112 if (k != 0)
1113 {
1114 k = c * k;
1115 eqn->touched = 1;
1116 eqn->coef[var] = 0;
1117
1118 for (j = top_var; j >= 0; j--)
1119 {
1120 j0 = packing[j];
1121 eqn->coef[j0] -= sub->coef[j0] * k;
1122 }
1123 }
1124
1125 if (dump_file && (dump_flags & TDF_DETAILS))
1126 {
1127 omega_print_geq (dump_file, pb, eqn);
1128 fprintf (dump_file, "\n");
1129 }
1130 }
1131
1132 for (e = pb->num_subs - 1; e >= 0; e--)
1133 {
1134 eqn eqn = &(pb->subs[e]);
1135 int k = eqn->coef[var];
1136
1137 if (k != 0)
1138 {
1139 k = c * k;
1140 eqn->coef[var] = 0;
1141
1142 for (j = top_var; j >= 0; j--)
1143 {
1144 j0 = packing[j];
1145 eqn->coef[j0] -= sub->coef[j0] * k;
1146 }
1147 }
1148
1149 if (dump_file && (dump_flags & TDF_DETAILS))
1150 {
1151 fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
1152 omega_print_term (dump_file, pb, eqn, 1);
1153 fprintf (dump_file, "\n");
1154 }
1155 }
1156
1157 if (dump_file && (dump_flags & TDF_DETAILS))
1158 {
1159 fprintf (dump_file, "---\n\n");
1160 omega_print_problem (dump_file, pb);
1161 fprintf (dump_file, "===\n\n");
1162 }
1163
1164 if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
1165 {
1166 int k;
1167 eqn eqn = &(pb->subs[pb->num_subs++]);
1168 c = -c;
1169
1170 for (k = pb->num_vars; k >= 0; k--)
1171 eqn->coef[k] = c * (sub->coef[k]);
1172
1173 eqn->key = pb->var[var];
1174 eqn->color = sub->color;
1175 }
1176 }
1177 }
1178
1179 /* Solve e = factor alpha for x_j and substitute. */
1180
1181 static void
1182 omega_do_mod (omega_pb pb, int factor, int e, int j)
1183 {
1184 int k, i;
1185 eqn eq = omega_alloc_eqns (0, 1);
1186 int nfactor;
1187 bool kill_j = false;
1188
1189 omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
1190
1191 for (k = pb->num_vars; k >= 0; k--)
1192 {
1193 eq->coef[k] = int_mod (eq->coef[k], factor);
1194
1195 if (2 * eq->coef[k] >= factor)
1196 eq->coef[k] -= factor;
1197 }
1198
1199 nfactor = eq->coef[j];
1200
1201 if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
1202 {
1203 i = omega_add_new_wild_card (pb);
1204 eq->coef[pb->num_vars] = eq->coef[i];
1205 eq->coef[j] = 0;
1206 eq->coef[i] = -factor;
1207 kill_j = true;
1208 }
1209 else
1210 {
1211 eq->coef[j] = -factor;
1212 if (!omega_wildcard_p (pb, j))
1213 omega_name_wild_card (pb, j);
1214 }
1215
1216 omega_substitute (pb, eq, j, nfactor);
1217
1218 for (k = pb->num_vars; k >= 0; k--)
1219 pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
1220
1221 if (kill_j)
1222 omega_delete_variable (pb, j);
1223
1224 if (dump_file && (dump_flags & TDF_DETAILS))
1225 {
1226 fprintf (dump_file, "Mod-ing and normalizing produces:\n");
1227 omega_print_problem (dump_file, pb);
1228 }
1229
1230 omega_free_eqns (eq, 1);
1231 }
1232
1233 /* Multiplies by -1 inequality E. */
1234
1235 void
1236 omega_negate_geq (omega_pb pb, int e)
1237 {
1238 int i;
1239
1240 for (i = pb->num_vars; i >= 0; i--)
1241 pb->geqs[e].coef[i] *= -1;
1242
1243 pb->geqs[e].coef[0]--;
1244 pb->geqs[e].touched = 1;
1245 }
1246
1247 /* Returns OMEGA_TRUE when problem PB has a solution. */
1248
1249 static enum omega_result
1250 verify_omega_pb (omega_pb pb)
1251 {
1252 enum omega_result result;
1253 int e;
1254 bool any_color = false;
1255 omega_pb tmp_problem = XNEW (struct omega_pb_d);
1256
1257 omega_copy_problem (tmp_problem, pb);
1258 tmp_problem->safe_vars = 0;
1259 tmp_problem->num_subs = 0;
1260
1261 for (e = pb->num_geqs - 1; e >= 0; e--)
1262 if (pb->geqs[e].color == omega_red)
1263 {
1264 any_color = true;
1265 break;
1266 }
1267
1268 if (please_no_equalities_in_simplified_problems)
1269 any_color = true;
1270
1271 if (any_color)
1272 original_problem = no_problem;
1273 else
1274 original_problem = pb;
1275
1276 if (dump_file && (dump_flags & TDF_DETAILS))
1277 {
1278 fprintf (dump_file, "verifying problem");
1279
1280 if (any_color)
1281 fprintf (dump_file, " (color mode)");
1282
1283 fprintf (dump_file, " :\n");
1284 omega_print_problem (dump_file, pb);
1285 }
1286
1287 result = omega_solve_problem (tmp_problem, omega_unknown);
1288 original_problem = no_problem;
1289 free (tmp_problem);
1290
1291 if (dump_file && (dump_flags & TDF_DETAILS))
1292 {
1293 if (result != omega_false)
1294 fprintf (dump_file, "verified problem\n");
1295 else
1296 fprintf (dump_file, "disproved problem\n");
1297 omega_print_problem (dump_file, pb);
1298 }
1299
1300 return result;
1301 }
1302
1303 /* Add a new equality to problem PB at last position E. */
1304
1305 static void
1306 adding_equality_constraint (omega_pb pb, int e)
1307 {
1308 if (original_problem != no_problem
1309 && original_problem != pb
1310 && !conservative)
1311 {
1312 int i, j;
1313 int e2 = original_problem->num_eqs++;
1314
1315 if (dump_file && (dump_flags & TDF_DETAILS))
1316 fprintf (dump_file,
1317 "adding equality constraint %d to outer problem\n", e2);
1318 omega_init_eqn_zero (&original_problem->eqs[e2],
1319 original_problem->num_vars);
1320
1321 for (i = pb->num_vars; i >= 1; i--)
1322 {
1323 for (j = original_problem->num_vars; j >= 1; j--)
1324 if (original_problem->var[j] == pb->var[i])
1325 break;
1326
1327 if (j <= 0)
1328 {
1329 if (dump_file && (dump_flags & TDF_DETAILS))
1330 fprintf (dump_file, "retracting\n");
1331 original_problem->num_eqs--;
1332 return;
1333 }
1334 original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
1335 }
1336
1337 original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
1338
1339 if (dump_file && (dump_flags & TDF_DETAILS))
1340 omega_print_problem (dump_file, original_problem);
1341 }
1342 }
1343
1344 static int *fast_lookup;
1345 static int *fast_lookup_red;
1346
1347 typedef enum {
1348 normalize_false,
1349 normalize_uncoupled,
1350 normalize_coupled
1351 } normalize_return_type;
1352
1353 /* Normalizes PB by removing redundant constraints. Returns
1354 normalize_false when the constraints system has no solution,
1355 otherwise returns normalize_coupled or normalize_uncoupled. */
1356
1357 static normalize_return_type
1358 normalize_omega_problem (omega_pb pb)
1359 {
1360 int e, i, j, k, n_vars;
1361 int coupled_subscripts = 0;
1362
1363 n_vars = pb->num_vars;
1364
1365 for (e = 0; e < pb->num_geqs; e++)
1366 {
1367 if (!pb->geqs[e].touched)
1368 {
1369 if (!single_var_geq (&pb->geqs[e], n_vars))
1370 coupled_subscripts = 1;
1371 }
1372 else
1373 {
1374 int g, top_var, i0, hashCode;
1375 int *p = &packing[0];
1376
1377 for (k = 1; k <= n_vars; k++)
1378 if (pb->geqs[e].coef[k])
1379 *(p++) = k;
1380
1381 top_var = (p - &packing[0]) - 1;
1382
1383 if (top_var == -1)
1384 {
1385 if (pb->geqs[e].coef[0] < 0)
1386 {
1387 if (dump_file && (dump_flags & TDF_DETAILS))
1388 {
1389 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1390 fprintf (dump_file, "\nequations have no solution \n");
1391 }
1392 return normalize_false;
1393 }
1394
1395 omega_delete_geq (pb, e, n_vars);
1396 e--;
1397 continue;
1398 }
1399 else if (top_var == 0)
1400 {
1401 int singlevar = packing[0];
1402
1403 g = pb->geqs[e].coef[singlevar];
1404
1405 if (g > 0)
1406 {
1407 pb->geqs[e].coef[singlevar] = 1;
1408 pb->geqs[e].key = singlevar;
1409 }
1410 else
1411 {
1412 g = -g;
1413 pb->geqs[e].coef[singlevar] = -1;
1414 pb->geqs[e].key = -singlevar;
1415 }
1416
1417 if (g > 1)
1418 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1419 }
1420 else
1421 {
1422 int g2;
1423 int hash_key_multiplier = 31;
1424
1425 coupled_subscripts = 1;
1426 i0 = top_var;
1427 i = packing[i0--];
1428 g = pb->geqs[e].coef[i];
1429 hashCode = g * (i + 3);
1430
1431 if (g < 0)
1432 g = -g;
1433
1434 for (; i0 >= 0; i0--)
1435 {
1436 int x;
1437
1438 i = packing[i0];
1439 x = pb->geqs[e].coef[i];
1440 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1441
1442 if (x < 0)
1443 x = -x;
1444
1445 if (x == 1)
1446 {
1447 g = 1;
1448 i0--;
1449 break;
1450 }
1451 else
1452 g = gcd (x, g);
1453 }
1454
1455 for (; i0 >= 0; i0--)
1456 {
1457 int x;
1458 i = packing[i0];
1459 x = pb->geqs[e].coef[i];
1460 hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
1461 }
1462
1463 if (g > 1)
1464 {
1465 pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
1466 i0 = top_var;
1467 i = packing[i0--];
1468 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1469 hashCode = pb->geqs[e].coef[i] * (i + 3);
1470
1471 for (; i0 >= 0; i0--)
1472 {
1473 i = packing[i0];
1474 pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
1475 hashCode = hashCode * hash_key_multiplier * (i + 3)
1476 + pb->geqs[e].coef[i];
1477 }
1478 }
1479
1480 g2 = abs (hashCode);
1481
1482 if (dump_file && (dump_flags & TDF_DETAILS))
1483 {
1484 fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
1485 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1486 fprintf (dump_file, "\n");
1487 }
1488
1489 j = g2 % HASH_TABLE_SIZE;
1490
1491 do {
1492 eqn proto = &(hash_master[j]);
1493
1494 if (proto->touched == g2)
1495 {
1496 if (proto->coef[0] == top_var)
1497 {
1498 if (hashCode >= 0)
1499 for (i0 = top_var; i0 >= 0; i0--)
1500 {
1501 i = packing[i0];
1502
1503 if (pb->geqs[e].coef[i] != proto->coef[i])
1504 break;
1505 }
1506 else
1507 for (i0 = top_var; i0 >= 0; i0--)
1508 {
1509 i = packing[i0];
1510
1511 if (pb->geqs[e].coef[i] != -proto->coef[i])
1512 break;
1513 }
1514
1515 if (i0 < 0)
1516 {
1517 if (hashCode >= 0)
1518 pb->geqs[e].key = proto->key;
1519 else
1520 pb->geqs[e].key = -proto->key;
1521 break;
1522 }
1523 }
1524 }
1525 else if (proto->touched < 0)
1526 {
1527 omega_init_eqn_zero (proto, pb->num_vars);
1528 if (hashCode >= 0)
1529 for (i0 = top_var; i0 >= 0; i0--)
1530 {
1531 i = packing[i0];
1532 proto->coef[i] = pb->geqs[e].coef[i];
1533 }
1534 else
1535 for (i0 = top_var; i0 >= 0; i0--)
1536 {
1537 i = packing[i0];
1538 proto->coef[i] = -pb->geqs[e].coef[i];
1539 }
1540
1541 proto->coef[0] = top_var;
1542 proto->touched = g2;
1543
1544 if (dump_file && (dump_flags & TDF_DETAILS))
1545 fprintf (dump_file, " constraint key = %d\n",
1546 next_key);
1547
1548 proto->key = next_key++;
1549
1550 /* Too many hash keys generated. */
1551 gcc_assert (proto->key <= MAX_KEYS);
1552
1553 if (hashCode >= 0)
1554 pb->geqs[e].key = proto->key;
1555 else
1556 pb->geqs[e].key = -proto->key;
1557
1558 break;
1559 }
1560
1561 j = (j + 1) % HASH_TABLE_SIZE;
1562 } while (1);
1563 }
1564
1565 pb->geqs[e].touched = 0;
1566 }
1567
1568 {
1569 int eKey = pb->geqs[e].key;
1570 int e2;
1571 if (e > 0)
1572 {
1573 int cTerm = pb->geqs[e].coef[0];
1574 e2 = fast_lookup[MAX_KEYS - eKey];
1575
1576 if (e2 < e && pb->geqs[e2].key == -eKey
1577 && pb->geqs[e2].color == omega_black)
1578 {
1579 if (pb->geqs[e2].coef[0] < -cTerm)
1580 {
1581 if (dump_file && (dump_flags & TDF_DETAILS))
1582 {
1583 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1584 fprintf (dump_file, "\n");
1585 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1586 fprintf (dump_file,
1587 "\nequations have no solution \n");
1588 }
1589 return normalize_false;
1590 }
1591
1592 if (pb->geqs[e2].coef[0] == -cTerm
1593 && (create_color
1594 || pb->geqs[e].color == omega_black))
1595 {
1596 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1597 pb->num_vars);
1598 if (pb->geqs[e].color == omega_black)
1599 adding_equality_constraint (pb, pb->num_eqs);
1600 pb->num_eqs++;
1601 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1602 }
1603 }
1604
1605 e2 = fast_lookup_red[MAX_KEYS - eKey];
1606
1607 if (e2 < e && pb->geqs[e2].key == -eKey
1608 && pb->geqs[e2].color == omega_red)
1609 {
1610 if (pb->geqs[e2].coef[0] < -cTerm)
1611 {
1612 if (dump_file && (dump_flags & TDF_DETAILS))
1613 {
1614 omega_print_geq (dump_file, pb, &pb->geqs[e]);
1615 fprintf (dump_file, "\n");
1616 omega_print_geq (dump_file, pb, &pb->geqs[e2]);
1617 fprintf (dump_file,
1618 "\nequations have no solution \n");
1619 }
1620 return normalize_false;
1621 }
1622
1623 if (pb->geqs[e2].coef[0] == -cTerm && create_color)
1624 {
1625 omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
1626 pb->num_vars);
1627 pb->eqs[pb->num_eqs].color = omega_red;
1628 pb->num_eqs++;
1629 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
1630 }
1631 }
1632
1633 e2 = fast_lookup[MAX_KEYS + eKey];
1634
1635 if (e2 < e && pb->geqs[e2].key == eKey
1636 && pb->geqs[e2].color == omega_black)
1637 {
1638 if (pb->geqs[e2].coef[0] > cTerm)
1639 {
1640 if (pb->geqs[e].color == omega_black)
1641 {
1642 if (dump_file && (dump_flags & TDF_DETAILS))
1643 {
1644 fprintf (dump_file,
1645 "Removing Redundant Equation: ");
1646 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1647 fprintf (dump_file, "\n");
1648 fprintf (dump_file,
1649 "[a] Made Redundant by: ");
1650 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1651 fprintf (dump_file, "\n");
1652 }
1653 pb->geqs[e2].coef[0] = cTerm;
1654 omega_delete_geq (pb, e, n_vars);
1655 e--;
1656 continue;
1657 }
1658 }
1659 else
1660 {
1661 if (dump_file && (dump_flags & TDF_DETAILS))
1662 {
1663 fprintf (dump_file, "Removing Redundant Equation: ");
1664 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1665 fprintf (dump_file, "\n");
1666 fprintf (dump_file, "[b] Made Redundant by: ");
1667 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1668 fprintf (dump_file, "\n");
1669 }
1670 omega_delete_geq (pb, e, n_vars);
1671 e--;
1672 continue;
1673 }
1674 }
1675
1676 e2 = fast_lookup_red[MAX_KEYS + eKey];
1677
1678 if (e2 < e && pb->geqs[e2].key == eKey
1679 && pb->geqs[e2].color == omega_red)
1680 {
1681 if (pb->geqs[e2].coef[0] >= cTerm)
1682 {
1683 if (dump_file && (dump_flags & TDF_DETAILS))
1684 {
1685 fprintf (dump_file, "Removing Redundant Equation: ");
1686 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1687 fprintf (dump_file, "\n");
1688 fprintf (dump_file, "[c] Made Redundant by: ");
1689 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1690 fprintf (dump_file, "\n");
1691 }
1692 pb->geqs[e2].coef[0] = cTerm;
1693 pb->geqs[e2].color = pb->geqs[e].color;
1694 }
1695 else if (pb->geqs[e].color == omega_red)
1696 {
1697 if (dump_file && (dump_flags & TDF_DETAILS))
1698 {
1699 fprintf (dump_file, "Removing Redundant Equation: ");
1700 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
1701 fprintf (dump_file, "\n");
1702 fprintf (dump_file, "[d] Made Redundant by: ");
1703 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
1704 fprintf (dump_file, "\n");
1705 }
1706 }
1707 omega_delete_geq (pb, e, n_vars);
1708 e--;
1709 continue;
1710
1711 }
1712 }
1713
1714 if (pb->geqs[e].color == omega_red)
1715 fast_lookup_red[MAX_KEYS + eKey] = e;
1716 else
1717 fast_lookup[MAX_KEYS + eKey] = e;
1718 }
1719 }
1720
1721 create_color = false;
1722 return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
1723 }
1724
1725 /* Divide the coefficients of EQN by their gcd. N_VARS is the number
1726 of variables in EQN. */
1727
1728 static inline void
1729 divide_eqn_by_gcd (eqn eqn, int n_vars)
1730 {
1731 int var, g = 0;
1732
1733 for (var = n_vars; var >= 0; var--)
1734 g = gcd (abs (eqn->coef[var]), g);
1735
1736 if (g)
1737 for (var = n_vars; var >= 0; var--)
1738 eqn->coef[var] = eqn->coef[var] / g;
1739 }
1740
1741 /* Rewrite some non-safe variables in function of protected
1742 wildcard variables. */
1743
1744 static void
1745 cleanout_wildcards (omega_pb pb)
1746 {
1747 int e, i, j;
1748 int n_vars = pb->num_vars;
1749 bool renormalize = false;
1750
1751 for (e = pb->num_eqs - 1; e >= 0; e--)
1752 for (i = n_vars; !omega_safe_var_p (pb, i); i--)
1753 if (pb->eqs[e].coef[i] != 0)
1754 {
1755 /* i is the last nonzero non-safe variable. */
1756
1757 for (j = i - 1; !omega_safe_var_p (pb, j); j--)
1758 if (pb->eqs[e].coef[j] != 0)
1759 break;
1760
1761 /* j is the next nonzero non-safe variable, or points
1762 to a safe variable: it is then a wildcard variable. */
1763
1764 /* Clean it out. */
1765 if (omega_safe_var_p (pb, j))
1766 {
1767 eqn sub = &(pb->eqs[e]);
1768 int c = pb->eqs[e].coef[i];
1769 int a = abs (c);
1770 int e2;
1771
1772 if (dump_file && (dump_flags & TDF_DETAILS))
1773 {
1774 fprintf (dump_file,
1775 "Found a single wild card equality: ");
1776 omega_print_eq (dump_file, pb, &pb->eqs[e]);
1777 fprintf (dump_file, "\n");
1778 omega_print_problem (dump_file, pb);
1779 }
1780
1781 for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
1782 if (e != e2 && pb->eqs[e2].coef[i]
1783 && (pb->eqs[e2].color == omega_red
1784 || (pb->eqs[e2].color == omega_black
1785 && pb->eqs[e].color == omega_black)))
1786 {
1787 eqn eqn = &(pb->eqs[e2]);
1788 int var, k;
1789
1790 for (var = n_vars; var >= 0; var--)
1791 eqn->coef[var] *= a;
1792
1793 k = eqn->coef[i];
1794
1795 for (var = n_vars; var >= 0; var--)
1796 eqn->coef[var] -= sub->coef[var] * k / c;
1797
1798 eqn->coef[i] = 0;
1799 divide_eqn_by_gcd (eqn, n_vars);
1800 }
1801
1802 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
1803 if (pb->geqs[e2].coef[i]
1804 && (pb->geqs[e2].color == omega_red
1805 || (pb->eqs[e].color == omega_black
1806 && pb->geqs[e2].color == omega_black)))
1807 {
1808 eqn eqn = &(pb->geqs[e2]);
1809 int var, k;
1810
1811 for (var = n_vars; var >= 0; var--)
1812 eqn->coef[var] *= a;
1813
1814 k = eqn->coef[i];
1815
1816 for (var = n_vars; var >= 0; var--)
1817 eqn->coef[var] -= sub->coef[var] * k / c;
1818
1819 eqn->coef[i] = 0;
1820 eqn->touched = 1;
1821 renormalize = true;
1822 }
1823
1824 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
1825 if (pb->subs[e2].coef[i]
1826 && (pb->subs[e2].color == omega_red
1827 || (pb->subs[e2].color == omega_black
1828 && pb->eqs[e].color == omega_black)))
1829 {
1830 eqn eqn = &(pb->subs[e2]);
1831 int var, k;
1832
1833 for (var = n_vars; var >= 0; var--)
1834 eqn->coef[var] *= a;
1835
1836 k = eqn->coef[i];
1837
1838 for (var = n_vars; var >= 0; var--)
1839 eqn->coef[var] -= sub->coef[var] * k / c;
1840
1841 eqn->coef[i] = 0;
1842 divide_eqn_by_gcd (eqn, n_vars);
1843 }
1844
1845 if (dump_file && (dump_flags & TDF_DETAILS))
1846 {
1847 fprintf (dump_file, "cleaned-out wildcard: ");
1848 omega_print_problem (dump_file, pb);
1849 }
1850 break;
1851 }
1852 }
1853
1854 if (renormalize)
1855 normalize_omega_problem (pb);
1856 }
1857
1858 /* Swap values contained in I and J. */
1859
1860 static inline void
1861 swap (int *i, int *j)
1862 {
1863 int tmp;
1864 tmp = *i;
1865 *i = *j;
1866 *j = tmp;
1867 }
1868
1869 /* Swap values contained in I and J. */
1870
1871 static inline void
1872 bswap (bool *i, bool *j)
1873 {
1874 bool tmp;
1875 tmp = *i;
1876 *i = *j;
1877 *j = tmp;
1878 }
1879
1880 /* Make variable IDX unprotected in PB, by swapping its index at the
1881 PB->safe_vars rank. */
1882
1883 static inline void
1884 omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
1885 {
1886 /* If IDX is protected... */
1887 if (*idx < pb->safe_vars)
1888 {
1889 /* ... swap its index with the last non protected index. */
1890 int j = pb->safe_vars;
1891 int e;
1892
1893 for (e = pb->num_geqs - 1; e >= 0; e--)
1894 {
1895 pb->geqs[e].touched = 1;
1896 swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
1897 }
1898
1899 for (e = pb->num_eqs - 1; e >= 0; e--)
1900 swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
1901
1902 for (e = pb->num_subs - 1; e >= 0; e--)
1903 swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
1904
1905 if (unprotect)
1906 bswap (&unprotect[*idx], &unprotect[j]);
1907
1908 swap (&pb->var[*idx], &pb->var[j]);
1909 pb->forwarding_address[pb->var[*idx]] = *idx;
1910 pb->forwarding_address[pb->var[j]] = j;
1911 (*idx)--;
1912 }
1913
1914 /* The variable at pb->safe_vars is also unprotected now. */
1915 pb->safe_vars--;
1916 }
1917
1918 /* During the Fourier-Motzkin elimination some variables are
1919 substituted with other variables. This function resurrects the
1920 substituted variables in PB. */
1921
1922 static void
1923 resurrect_subs (omega_pb pb)
1924 {
1925 if (pb->num_subs > 0
1926 && please_no_equalities_in_simplified_problems == 0)
1927 {
1928 int i, e, m;
1929
1930 if (dump_file && (dump_flags & TDF_DETAILS))
1931 {
1932 fprintf (dump_file,
1933 "problem reduced, bringing variables back to life\n");
1934 omega_print_problem (dump_file, pb);
1935 }
1936
1937 for (i = 1; omega_safe_var_p (pb, i); i++)
1938 if (omega_wildcard_p (pb, i))
1939 omega_unprotect_1 (pb, &i, NULL);
1940
1941 m = pb->num_subs;
1942
1943 for (e = pb->num_geqs - 1; e >= 0; e--)
1944 if (single_var_geq (&pb->geqs[e], pb->num_vars))
1945 {
1946 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
1947 pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
1948 }
1949 else
1950 {
1951 pb->geqs[e].touched = 1;
1952 pb->geqs[e].key = 0;
1953 }
1954
1955 for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
1956 {
1957 pb->var[i + m] = pb->var[i];
1958
1959 for (e = pb->num_geqs - 1; e >= 0; e--)
1960 pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
1961
1962 for (e = pb->num_eqs - 1; e >= 0; e--)
1963 pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
1964
1965 for (e = pb->num_subs - 1; e >= 0; e--)
1966 pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
1967 }
1968
1969 for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
1970 {
1971 for (e = pb->num_geqs - 1; e >= 0; e--)
1972 pb->geqs[e].coef[i] = 0;
1973
1974 for (e = pb->num_eqs - 1; e >= 0; e--)
1975 pb->eqs[e].coef[i] = 0;
1976
1977 for (e = pb->num_subs - 1; e >= 0; e--)
1978 pb->subs[e].coef[i] = 0;
1979 }
1980
1981 pb->num_vars += m;
1982
1983 for (e = pb->num_subs - 1; e >= 0; e--)
1984 {
1985 pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
1986 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
1987 pb->num_vars);
1988 pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
1989 pb->eqs[pb->num_eqs].color = omega_black;
1990
1991 if (dump_file && (dump_flags & TDF_DETAILS))
1992 {
1993 fprintf (dump_file, "brought back: ");
1994 omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
1995 fprintf (dump_file, "\n");
1996 }
1997
1998 pb->num_eqs++;
1999 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2000 }
2001
2002 pb->safe_vars += m;
2003 pb->num_subs = 0;
2004
2005 if (dump_file && (dump_flags & TDF_DETAILS))
2006 {
2007 fprintf (dump_file, "variables brought back to life\n");
2008 omega_print_problem (dump_file, pb);
2009 }
2010
2011 cleanout_wildcards (pb);
2012 }
2013 }
2014
2015 static inline bool
2016 implies (unsigned int a, unsigned int b)
2017 {
2018 return (a == (a & b));
2019 }
2020
2021 /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
2022 extra step is performed. Returns omega_false when there exist no
2023 solution, omega_true otherwise. */
2024
2025 enum omega_result
2026 omega_eliminate_redundant (omega_pb pb, bool expensive)
2027 {
2028 int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
2029 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2030 omega_pb tmp_problem;
2031
2032 /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
2033 unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2034 unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2035 unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
2036
2037 /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
2038 unsigned int pp, pz, pn;
2039
2040 if (dump_file && (dump_flags & TDF_DETAILS))
2041 {
2042 fprintf (dump_file, "in eliminate Redundant:\n");
2043 omega_print_problem (dump_file, pb);
2044 }
2045
2046 for (e = pb->num_geqs - 1; e >= 0; e--)
2047 {
2048 int tmp = 1;
2049
2050 is_dead[e] = false;
2051 peqs[e] = zeqs[e] = neqs[e] = 0;
2052
2053 for (i = pb->num_vars; i >= 1; i--)
2054 {
2055 if (pb->geqs[e].coef[i] > 0)
2056 peqs[e] |= tmp;
2057 else if (pb->geqs[e].coef[i] < 0)
2058 neqs[e] |= tmp;
2059 else
2060 zeqs[e] |= tmp;
2061
2062 tmp <<= 1;
2063 }
2064 }
2065
2066
2067 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2068 if (!is_dead[e1])
2069 for (e2 = e1 - 1; e2 >= 0; e2--)
2070 if (!is_dead[e2])
2071 {
2072 for (p = pb->num_vars; p > 1; p--)
2073 for (q = p - 1; q > 0; q--)
2074 if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
2075 - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
2076 goto foundPQ;
2077
2078 continue;
2079
2080 foundPQ:
2081 pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
2082 | (neqs[e1] & peqs[e2]));
2083 pp = peqs[e1] | peqs[e2];
2084 pn = neqs[e1] | neqs[e2];
2085
2086 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2087 if (e3 != e1 && e3 != e2)
2088 {
2089 if (!implies (zeqs[e3], pz))
2090 goto nextE3;
2091
2092 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2093 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2094 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2095 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2096 alpha3 = alpha;
2097
2098 if (alpha1 * alpha2 <= 0)
2099 goto nextE3;
2100
2101 if (alpha1 < 0)
2102 {
2103 alpha1 = -alpha1;
2104 alpha2 = -alpha2;
2105 alpha3 = -alpha3;
2106 }
2107
2108 if (alpha3 > 0)
2109 {
2110 /* Trying to prove e3 is redundant. */
2111 if (!implies (peqs[e3], pp)
2112 || !implies (neqs[e3], pn))
2113 goto nextE3;
2114
2115 if (pb->geqs[e3].color == omega_black
2116 && (pb->geqs[e1].color == omega_red
2117 || pb->geqs[e2].color == omega_red))
2118 goto nextE3;
2119
2120 for (k = pb->num_vars; k >= 1; k--)
2121 if (alpha3 * pb->geqs[e3].coef[k]
2122 != (alpha1 * pb->geqs[e1].coef[k]
2123 + alpha2 * pb->geqs[e2].coef[k]))
2124 goto nextE3;
2125
2126 c = (alpha1 * pb->geqs[e1].coef[0]
2127 + alpha2 * pb->geqs[e2].coef[0]);
2128
2129 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2130 {
2131 if (dump_file && (dump_flags & TDF_DETAILS))
2132 {
2133 fprintf (dump_file,
2134 "found redundant inequality\n");
2135 fprintf (dump_file,
2136 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2137 alpha1, alpha2, alpha3);
2138
2139 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2140 fprintf (dump_file, "\n");
2141 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2142 fprintf (dump_file, "\n=> ");
2143 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2144 fprintf (dump_file, "\n\n");
2145 }
2146
2147 is_dead[e3] = true;
2148 }
2149 }
2150 else
2151 {
2152 /* Trying to prove e3 <= 0 and therefore e3 = 0,
2153 or trying to prove e3 < 0, and therefore the
2154 problem has no solutions. */
2155 if (!implies (peqs[e3], pn)
2156 || !implies (neqs[e3], pp))
2157 goto nextE3;
2158
2159 if (pb->geqs[e1].color == omega_red
2160 || pb->geqs[e2].color == omega_red
2161 || pb->geqs[e3].color == omega_red)
2162 goto nextE3;
2163
2164 /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2165 for (k = pb->num_vars; k >= 1; k--)
2166 if (alpha3 * pb->geqs[e3].coef[k]
2167 != (alpha1 * pb->geqs[e1].coef[k]
2168 + alpha2 * pb->geqs[e2].coef[k]))
2169 goto nextE3;
2170
2171 c = (alpha1 * pb->geqs[e1].coef[0]
2172 + alpha2 * pb->geqs[e2].coef[0]);
2173
2174 if (c < alpha3 * (pb->geqs[e3].coef[0]))
2175 {
2176 /* We just proved e3 < 0, so no solutions exist. */
2177 if (dump_file && (dump_flags & TDF_DETAILS))
2178 {
2179 fprintf (dump_file,
2180 "found implied over tight inequality\n");
2181 fprintf (dump_file,
2182 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2183 alpha1, alpha2, -alpha3);
2184 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2185 fprintf (dump_file, "\n");
2186 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2187 fprintf (dump_file, "\n=> not ");
2188 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2189 fprintf (dump_file, "\n\n");
2190 }
2191 free (is_dead);
2192 free (peqs);
2193 free (zeqs);
2194 free (neqs);
2195 return omega_false;
2196 }
2197 else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2198 {
2199 /* We just proved that e3 <=0, so e3 = 0. */
2200 if (dump_file && (dump_flags & TDF_DETAILS))
2201 {
2202 fprintf (dump_file,
2203 "found implied tight inequality\n");
2204 fprintf (dump_file,
2205 "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2206 alpha1, alpha2, -alpha3);
2207 omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2208 fprintf (dump_file, "\n");
2209 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2210 fprintf (dump_file, "\n=> inverse ");
2211 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2212 fprintf (dump_file, "\n\n");
2213 }
2214
2215 omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2216 &pb->geqs[e3], pb->num_vars);
2217 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2218 adding_equality_constraint (pb, pb->num_eqs - 1);
2219 is_dead[e3] = true;
2220 }
2221 }
2222 nextE3:;
2223 }
2224 }
2225
2226 /* Delete the inequalities that were marked as dead. */
2227 for (e = pb->num_geqs - 1; e >= 0; e--)
2228 if (is_dead[e])
2229 omega_delete_geq (pb, e, pb->num_vars);
2230
2231 if (!expensive)
2232 goto eliminate_redundant_done;
2233
2234 tmp_problem = XNEW (struct omega_pb_d);
2235 conservative++;
2236
2237 for (e = pb->num_geqs - 1; e >= 0; e--)
2238 {
2239 if (dump_file && (dump_flags & TDF_DETAILS))
2240 {
2241 fprintf (dump_file,
2242 "checking equation %d to see if it is redundant: ", e);
2243 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2244 fprintf (dump_file, "\n");
2245 }
2246
2247 omega_copy_problem (tmp_problem, pb);
2248 omega_negate_geq (tmp_problem, e);
2249 tmp_problem->safe_vars = 0;
2250 tmp_problem->variables_freed = false;
2251
2252 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2253 omega_delete_geq (pb, e, pb->num_vars);
2254 }
2255
2256 free (tmp_problem);
2257 conservative--;
2258
2259 if (!omega_reduce_with_subs)
2260 {
2261 resurrect_subs (pb);
2262 gcc_assert (please_no_equalities_in_simplified_problems
2263 || pb->num_subs == 0);
2264 }
2265
2266 eliminate_redundant_done:
2267 free (is_dead);
2268 free (peqs);
2269 free (zeqs);
2270 free (neqs);
2271 return omega_true;
2272 }
2273
2274 /* For each inequality that has coefficients bigger than 20, try to
2275 create a new constraint that cannot be derived from the original
2276 constraint and that has smaller coefficients. Add the new
2277 constraint at the end of geqs. Return the number of inequalities
2278 that have been added to PB. */
2279
2280 static int
2281 smooth_weird_equations (omega_pb pb)
2282 {
2283 int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2284 int c;
2285 int v;
2286 int result = 0;
2287
2288 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2289 if (pb->geqs[e1].color == omega_black)
2290 {
2291 int g = 999999;
2292
2293 for (v = pb->num_vars; v >= 1; v--)
2294 if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2295 g = abs (pb->geqs[e1].coef[v]);
2296
2297 /* Magic number. */
2298 if (g > 20)
2299 {
2300 e3 = pb->num_geqs;
2301
2302 for (v = pb->num_vars; v >= 1; v--)
2303 pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2304 g);
2305
2306 pb->geqs[e3].color = omega_black;
2307 pb->geqs[e3].touched = 1;
2308 /* Magic number. */
2309 pb->geqs[e3].coef[0] = 9997;
2310
2311 if (dump_file && (dump_flags & TDF_DETAILS))
2312 {
2313 fprintf (dump_file, "Checking to see if we can derive: ");
2314 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2315 fprintf (dump_file, "\n from: ");
2316 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2317 fprintf (dump_file, "\n");
2318 }
2319
2320 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2321 if (e1 != e2 && pb->geqs[e2].color == omega_black)
2322 {
2323 for (p = pb->num_vars; p > 1; p--)
2324 {
2325 for (q = p - 1; q > 0; q--)
2326 {
2327 alpha =
2328 (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2329 pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2330 if (alpha != 0)
2331 goto foundPQ;
2332 }
2333 }
2334 continue;
2335
2336 foundPQ:
2337
2338 alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2339 - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2340 alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2341 - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2342 alpha3 = alpha;
2343
2344 if (alpha1 * alpha2 <= 0)
2345 continue;
2346
2347 if (alpha1 < 0)
2348 {
2349 alpha1 = -alpha1;
2350 alpha2 = -alpha2;
2351 alpha3 = -alpha3;
2352 }
2353
2354 if (alpha3 > 0)
2355 {
2356 /* Try to prove e3 is redundant: verify
2357 alpha1*v1 + alpha2*v2 = alpha3*v3. */
2358 for (k = pb->num_vars; k >= 1; k--)
2359 if (alpha3 * pb->geqs[e3].coef[k]
2360 != (alpha1 * pb->geqs[e1].coef[k]
2361 + alpha2 * pb->geqs[e2].coef[k]))
2362 goto nextE2;
2363
2364 c = alpha1 * pb->geqs[e1].coef[0]
2365 + alpha2 * pb->geqs[e2].coef[0];
2366
2367 if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2368 pb->geqs[e3].coef[0] = int_div (c, alpha3);
2369 }
2370 nextE2:;
2371 }
2372
2373 if (pb->geqs[e3].coef[0] < 9997)
2374 {
2375 result++;
2376 pb->num_geqs++;
2377
2378 if (dump_file && (dump_flags & TDF_DETAILS))
2379 {
2380 fprintf (dump_file,
2381 "Smoothing weird equations; adding:\n");
2382 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2383 fprintf (dump_file, "\nto:\n");
2384 omega_print_problem (dump_file, pb);
2385 fprintf (dump_file, "\n\n");
2386 }
2387 }
2388 }
2389 }
2390 return result;
2391 }
2392
2393 /* Replace tuples of inequalities, that define upper and lower half
2394 spaces, with an equation. */
2395
2396 static void
2397 coalesce (omega_pb pb)
2398 {
2399 int e, e2;
2400 int colors = 0;
2401 bool *is_dead;
2402 int found_something = 0;
2403
2404 for (e = 0; e < pb->num_geqs; e++)
2405 if (pb->geqs[e].color == omega_red)
2406 colors++;
2407
2408 if (colors < 2)
2409 return;
2410
2411 is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2412
2413 for (e = 0; e < pb->num_geqs; e++)
2414 is_dead[e] = false;
2415
2416 for (e = 0; e < pb->num_geqs; e++)
2417 if (pb->geqs[e].color == omega_red
2418 && !pb->geqs[e].touched)
2419 for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2420 if (!pb->geqs[e2].touched
2421 && pb->geqs[e].key == -pb->geqs[e2].key
2422 && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2423 && pb->geqs[e2].color == omega_red)
2424 {
2425 omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2426 pb->num_vars);
2427 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2428 found_something++;
2429 is_dead[e] = true;
2430 is_dead[e2] = true;
2431 }
2432
2433 for (e = pb->num_geqs - 1; e >= 0; e--)
2434 if (is_dead[e])
2435 omega_delete_geq (pb, e, pb->num_vars);
2436
2437 if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2438 {
2439 fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2440 found_something);
2441 omega_print_problem (dump_file, pb);
2442 }
2443
2444 free (is_dead);
2445 }
2446
2447 /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
2448 true, continue to eliminate all the red inequalities. */
2449
2450 void
2451 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2452 {
2453 int e, e2, e3, i, j, k, a, alpha1, alpha2;
2454 int c = 0;
2455 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2456 int dead_count = 0;
2457 int red_found;
2458 omega_pb tmp_problem;
2459
2460 if (dump_file && (dump_flags & TDF_DETAILS))
2461 {
2462 fprintf (dump_file, "in eliminate RED:\n");
2463 omega_print_problem (dump_file, pb);
2464 }
2465
2466 if (pb->num_eqs > 0)
2467 omega_simplify_problem (pb);
2468
2469 for (e = pb->num_geqs - 1; e >= 0; e--)
2470 is_dead[e] = false;
2471
2472 for (e = pb->num_geqs - 1; e >= 0; e--)
2473 if (pb->geqs[e].color == omega_black && !is_dead[e])
2474 for (e2 = e - 1; e2 >= 0; e2--)
2475 if (pb->geqs[e2].color == omega_black
2476 && !is_dead[e2])
2477 {
2478 a = 0;
2479
2480 for (i = pb->num_vars; i > 1; i--)
2481 for (j = i - 1; j > 0; j--)
2482 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2483 - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2484 goto found_pair;
2485
2486 continue;
2487
2488 found_pair:
2489 if (dump_file && (dump_flags & TDF_DETAILS))
2490 {
2491 fprintf (dump_file,
2492 "found two equations to combine, i = %s, ",
2493 omega_variable_to_str (pb, i));
2494 fprintf (dump_file, "j = %s, alpha = %d\n",
2495 omega_variable_to_str (pb, j), a);
2496 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2497 fprintf (dump_file, "\n");
2498 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2499 fprintf (dump_file, "\n");
2500 }
2501
2502 for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2503 if (pb->geqs[e3].color == omega_red)
2504 {
2505 alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2506 - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2507 alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2508 - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2509
2510 if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2511 || (a < 0 && alpha1 < 0 && alpha2 < 0))
2512 {
2513 if (dump_file && (dump_flags & TDF_DETAILS))
2514 {
2515 fprintf (dump_file,
2516 "alpha1 = %d, alpha2 = %d;"
2517 "comparing against: ",
2518 alpha1, alpha2);
2519 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2520 fprintf (dump_file, "\n");
2521 }
2522
2523 for (k = pb->num_vars; k >= 0; k--)
2524 {
2525 c = (alpha1 * pb->geqs[e].coef[k]
2526 + alpha2 * pb->geqs[e2].coef[k]);
2527
2528 if (c != a * pb->geqs[e3].coef[k])
2529 break;
2530
2531 if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2532 fprintf (dump_file, " %s: %d, %d\n",
2533 omega_variable_to_str (pb, k), c,
2534 a * pb->geqs[e3].coef[k]);
2535 }
2536
2537 if (k < 0
2538 || (k == 0 &&
2539 ((a > 0 && c < a * pb->geqs[e3].coef[k])
2540 || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2541 {
2542 if (dump_file && (dump_flags & TDF_DETAILS))
2543 {
2544 dead_count++;
2545 fprintf (dump_file,
2546 "red equation#%d is dead "
2547 "(%d dead so far, %d remain)\n",
2548 e3, dead_count,
2549 pb->num_geqs - dead_count);
2550 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2551 fprintf (dump_file, "\n");
2552 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2553 fprintf (dump_file, "\n");
2554 omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2555 fprintf (dump_file, "\n");
2556 }
2557 is_dead[e3] = true;
2558 }
2559 }
2560 }
2561 }
2562
2563 for (e = pb->num_geqs - 1; e >= 0; e--)
2564 if (is_dead[e])
2565 omega_delete_geq (pb, e, pb->num_vars);
2566
2567 free (is_dead);
2568
2569 if (dump_file && (dump_flags & TDF_DETAILS))
2570 {
2571 fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2572 omega_print_problem (dump_file, pb);
2573 }
2574
2575 for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2576 if (pb->geqs[e].color == omega_red)
2577 red_found = 1;
2578
2579 if (!red_found)
2580 {
2581 if (dump_file && (dump_flags & TDF_DETAILS))
2582 fprintf (dump_file, "fast checks worked\n");
2583
2584 if (!omega_reduce_with_subs)
2585 gcc_assert (please_no_equalities_in_simplified_problems
2586 || pb->num_subs == 0);
2587
2588 return;
2589 }
2590
2591 if (!omega_verify_simplification
2592 && verify_omega_pb (pb) == omega_false)
2593 return;
2594
2595 conservative++;
2596 tmp_problem = XNEW (struct omega_pb_d);
2597
2598 for (e = pb->num_geqs - 1; e >= 0; e--)
2599 if (pb->geqs[e].color == omega_red)
2600 {
2601 if (dump_file && (dump_flags & TDF_DETAILS))
2602 {
2603 fprintf (dump_file,
2604 "checking equation %d to see if it is redundant: ", e);
2605 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2606 fprintf (dump_file, "\n");
2607 }
2608
2609 omega_copy_problem (tmp_problem, pb);
2610 omega_negate_geq (tmp_problem, e);
2611 tmp_problem->safe_vars = 0;
2612 tmp_problem->variables_freed = false;
2613 tmp_problem->num_subs = 0;
2614
2615 if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2616 {
2617 if (dump_file && (dump_flags & TDF_DETAILS))
2618 fprintf (dump_file, "it is redundant\n");
2619 omega_delete_geq (pb, e, pb->num_vars);
2620 }
2621 else
2622 {
2623 if (dump_file && (dump_flags & TDF_DETAILS))
2624 fprintf (dump_file, "it is not redundant\n");
2625
2626 if (!eliminate_all)
2627 {
2628 if (dump_file && (dump_flags & TDF_DETAILS))
2629 fprintf (dump_file, "no need to check other red equations\n");
2630 break;
2631 }
2632 }
2633 }
2634
2635 conservative--;
2636 free (tmp_problem);
2637 /* omega_simplify_problem (pb); */
2638
2639 if (!omega_reduce_with_subs)
2640 gcc_assert (please_no_equalities_in_simplified_problems
2641 || pb->num_subs == 0);
2642 }
2643
2644 /* Transform some wildcard variables to non-safe variables. */
2645
2646 static void
2647 chain_unprotect (omega_pb pb)
2648 {
2649 int i, e;
2650 bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2651
2652 for (i = 1; omega_safe_var_p (pb, i); i++)
2653 {
2654 unprotect[i] = omega_wildcard_p (pb, i);
2655
2656 for (e = pb->num_subs - 1; e >= 0; e--)
2657 if (pb->subs[e].coef[i])
2658 unprotect[i] = false;
2659 }
2660
2661 if (dump_file && (dump_flags & TDF_DETAILS))
2662 {
2663 fprintf (dump_file, "Doing chain reaction unprotection\n");
2664 omega_print_problem (dump_file, pb);
2665
2666 for (i = 1; omega_safe_var_p (pb, i); i++)
2667 if (unprotect[i])
2668 fprintf (dump_file, "unprotecting %s\n",
2669 omega_variable_to_str (pb, i));
2670 }
2671
2672 for (i = 1; omega_safe_var_p (pb, i); i++)
2673 if (unprotect[i])
2674 omega_unprotect_1 (pb, &i, unprotect);
2675
2676 if (dump_file && (dump_flags & TDF_DETAILS))
2677 {
2678 fprintf (dump_file, "After chain reactions\n");
2679 omega_print_problem (dump_file, pb);
2680 }
2681
2682 free (unprotect);
2683 }
2684
2685 /* Reduce problem PB. */
2686
2687 static void
2688 omega_problem_reduced (omega_pb pb)
2689 {
2690 if (omega_verify_simplification
2691 && !in_approximate_mode
2692 && verify_omega_pb (pb) == omega_false)
2693 return;
2694
2695 if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2696 && !omega_eliminate_redundant (pb, true))
2697 return;
2698
2699 omega_found_reduction = omega_true;
2700
2701 if (!please_no_equalities_in_simplified_problems)
2702 coalesce (pb);
2703
2704 if (omega_reduce_with_subs
2705 || please_no_equalities_in_simplified_problems)
2706 chain_unprotect (pb);
2707 else
2708 resurrect_subs (pb);
2709
2710 if (!return_single_result)
2711 {
2712 int i;
2713
2714 for (i = 1; omega_safe_var_p (pb, i); i++)
2715 pb->forwarding_address[pb->var[i]] = i;
2716
2717 for (i = 0; i < pb->num_subs; i++)
2718 pb->forwarding_address[pb->subs[i].key] = -i - 1;
2719
2720 (*omega_when_reduced) (pb);
2721 }
2722
2723 if (dump_file && (dump_flags & TDF_DETAILS))
2724 {
2725 fprintf (dump_file, "-------------------------------------------\n");
2726 fprintf (dump_file, "problem reduced:\n");
2727 omega_print_problem (dump_file, pb);
2728 fprintf (dump_file, "-------------------------------------------\n");
2729 }
2730 }
2731
2732 /* Eliminates all the free variables for problem PB, that is all the
2733 variables from FV to PB->NUM_VARS. */
2734
2735 static void
2736 omega_free_eliminations (omega_pb pb, int fv)
2737 {
2738 bool try_again = true;
2739 int i, e, e2;
2740 int n_vars = pb->num_vars;
2741
2742 while (try_again)
2743 {
2744 try_again = false;
2745
2746 for (i = n_vars; i > fv; i--)
2747 {
2748 for (e = pb->num_geqs - 1; e >= 0; e--)
2749 if (pb->geqs[e].coef[i])
2750 break;
2751
2752 if (e < 0)
2753 e2 = e;
2754 else if (pb->geqs[e].coef[i] > 0)
2755 {
2756 for (e2 = e - 1; e2 >= 0; e2--)
2757 if (pb->geqs[e2].coef[i] < 0)
2758 break;
2759 }
2760 else
2761 {
2762 for (e2 = e - 1; e2 >= 0; e2--)
2763 if (pb->geqs[e2].coef[i] > 0)
2764 break;
2765 }
2766
2767 if (e2 < 0)
2768 {
2769 int e3;
2770 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2771 if (pb->subs[e3].coef[i])
2772 break;
2773
2774 if (e3 >= 0)
2775 continue;
2776
2777 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2778 if (pb->eqs[e3].coef[i])
2779 break;
2780
2781 if (e3 >= 0)
2782 continue;
2783
2784 if (dump_file && (dump_flags & TDF_DETAILS))
2785 fprintf (dump_file, "a free elimination of %s\n",
2786 omega_variable_to_str (pb, i));
2787
2788 if (e >= 0)
2789 {
2790 omega_delete_geq (pb, e, n_vars);
2791
2792 for (e--; e >= 0; e--)
2793 if (pb->geqs[e].coef[i])
2794 omega_delete_geq (pb, e, n_vars);
2795
2796 try_again = (i < n_vars);
2797 }
2798
2799 omega_delete_variable (pb, i);
2800 n_vars = pb->num_vars;
2801 }
2802 }
2803 }
2804
2805 if (dump_file && (dump_flags & TDF_DETAILS))
2806 {
2807 fprintf (dump_file, "\nafter free eliminations:\n");
2808 omega_print_problem (dump_file, pb);
2809 fprintf (dump_file, "\n");
2810 }
2811 }
2812
2813 /* Do free red eliminations. */
2814
2815 static void
2816 free_red_eliminations (omega_pb pb)
2817 {
2818 bool try_again = true;
2819 int i, e, e2;
2820 int n_vars = pb->num_vars;
2821 bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2822 bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2823 bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2824
2825 for (i = n_vars; i > 0; i--)
2826 {
2827 is_red_var[i] = false;
2828 is_dead_var[i] = false;
2829 }
2830
2831 for (e = pb->num_geqs - 1; e >= 0; e--)
2832 {
2833 is_dead_geq[e] = false;
2834
2835 if (pb->geqs[e].color == omega_red)
2836 for (i = n_vars; i > 0; i--)
2837 if (pb->geqs[e].coef[i] != 0)
2838 is_red_var[i] = true;
2839 }
2840
2841 while (try_again)
2842 {
2843 try_again = false;
2844 for (i = n_vars; i > 0; i--)
2845 if (!is_red_var[i] && !is_dead_var[i])
2846 {
2847 for (e = pb->num_geqs - 1; e >= 0; e--)
2848 if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2849 break;
2850
2851 if (e < 0)
2852 e2 = e;
2853 else if (pb->geqs[e].coef[i] > 0)
2854 {
2855 for (e2 = e - 1; e2 >= 0; e2--)
2856 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2857 break;
2858 }
2859 else
2860 {
2861 for (e2 = e - 1; e2 >= 0; e2--)
2862 if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2863 break;
2864 }
2865
2866 if (e2 < 0)
2867 {
2868 int e3;
2869 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2870 if (pb->subs[e3].coef[i])
2871 break;
2872
2873 if (e3 >= 0)
2874 continue;
2875
2876 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2877 if (pb->eqs[e3].coef[i])
2878 break;
2879
2880 if (e3 >= 0)
2881 continue;
2882
2883 if (dump_file && (dump_flags & TDF_DETAILS))
2884 fprintf (dump_file, "a free red elimination of %s\n",
2885 omega_variable_to_str (pb, i));
2886
2887 for (; e >= 0; e--)
2888 if (pb->geqs[e].coef[i])
2889 is_dead_geq[e] = true;
2890
2891 try_again = true;
2892 is_dead_var[i] = true;
2893 }
2894 }
2895 }
2896
2897 for (e = pb->num_geqs - 1; e >= 0; e--)
2898 if (is_dead_geq[e])
2899 omega_delete_geq (pb, e, n_vars);
2900
2901 for (i = n_vars; i > 0; i--)
2902 if (is_dead_var[i])
2903 omega_delete_variable (pb, i);
2904
2905 if (dump_file && (dump_flags & TDF_DETAILS))
2906 {
2907 fprintf (dump_file, "\nafter free red eliminations:\n");
2908 omega_print_problem (dump_file, pb);
2909 fprintf (dump_file, "\n");
2910 }
2911
2912 free (is_red_var);
2913 free (is_dead_var);
2914 free (is_dead_geq);
2915 }
2916
2917 /* For equation EQ of the form "0 = EQN", insert in PB two
2918 inequalities "0 <= EQN" and "0 <= -EQN". */
2919
2920 void
2921 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2922 {
2923 int i;
2924
2925 if (dump_file && (dump_flags & TDF_DETAILS))
2926 fprintf (dump_file, "Converting Eq to Geqs\n");
2927
2928 /* Insert "0 <= EQN". */
2929 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2930 pb->geqs[pb->num_geqs].touched = 1;
2931 pb->num_geqs++;
2932
2933 /* Insert "0 <= -EQN". */
2934 omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2935 pb->geqs[pb->num_geqs].touched = 1;
2936
2937 for (i = 0; i <= pb->num_vars; i++)
2938 pb->geqs[pb->num_geqs].coef[i] *= -1;
2939
2940 pb->num_geqs++;
2941
2942 if (dump_file && (dump_flags & TDF_DETAILS))
2943 omega_print_problem (dump_file, pb);
2944 }
2945
2946 /* Eliminates variable I from PB. */
2947
2948 static void
2949 omega_do_elimination (omega_pb pb, int e, int i)
2950 {
2951 eqn sub = omega_alloc_eqns (0, 1);
2952 int c;
2953 int n_vars = pb->num_vars;
2954
2955 if (dump_file && (dump_flags & TDF_DETAILS))
2956 fprintf (dump_file, "eliminating variable %s\n",
2957 omega_variable_to_str (pb, i));
2958
2959 omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
2960 c = sub->coef[i];
2961 sub->coef[i] = 0;
2962 if (c == 1 || c == -1)
2963 {
2964 if (pb->eqs[e].color == omega_red)
2965 {
2966 bool fB;
2967 omega_substitute_red (pb, sub, i, c, &fB);
2968 if (fB)
2969 omega_convert_eq_to_geqs (pb, e);
2970 else
2971 omega_delete_variable (pb, i);
2972 }
2973 else
2974 {
2975 omega_substitute (pb, sub, i, c);
2976 omega_delete_variable (pb, i);
2977 }
2978 }
2979 else
2980 {
2981 int a = abs (c);
2982 int e2 = e;
2983
2984 if (dump_file && (dump_flags & TDF_DETAILS))
2985 fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
2986
2987 for (e = pb->num_eqs - 1; e >= 0; e--)
2988 if (pb->eqs[e].coef[i])
2989 {
2990 eqn eqn = &(pb->eqs[e]);
2991 int j, k;
2992 for (j = n_vars; j >= 0; j--)
2993 eqn->coef[j] *= a;
2994 k = eqn->coef[i];
2995 eqn->coef[i] = 0;
2996 if (sub->color == omega_red)
2997 eqn->color = omega_red;
2998 for (j = n_vars; j >= 0; j--)
2999 eqn->coef[j] -= sub->coef[j] * k / c;
3000 }
3001
3002 for (e = pb->num_geqs - 1; e >= 0; e--)
3003 if (pb->geqs[e].coef[i])
3004 {
3005 eqn eqn = &(pb->geqs[e]);
3006 int j, k;
3007
3008 if (sub->color == omega_red)
3009 eqn->color = omega_red;
3010
3011 for (j = n_vars; j >= 0; j--)
3012 eqn->coef[j] *= a;
3013
3014 eqn->touched = 1;
3015 k = eqn->coef[i];
3016 eqn->coef[i] = 0;
3017
3018 for (j = n_vars; j >= 0; j--)
3019 eqn->coef[j] -= sub->coef[j] * k / c;
3020
3021 }
3022
3023 for (e = pb->num_subs - 1; e >= 0; e--)
3024 if (pb->subs[e].coef[i])
3025 {
3026 eqn eqn = &(pb->subs[e]);
3027 int j, k;
3028 gcc_assert (0);
3029 gcc_assert (sub->color == omega_black);
3030 for (j = n_vars; j >= 0; j--)
3031 eqn->coef[j] *= a;
3032 k = eqn->coef[i];
3033 eqn->coef[i] = 0;
3034 for (j = n_vars; j >= 0; j--)
3035 eqn->coef[j] -= sub->coef[j] * k / c;
3036 }
3037
3038 if (in_approximate_mode)
3039 omega_delete_variable (pb, i);
3040 else
3041 omega_convert_eq_to_geqs (pb, e2);
3042 }
3043
3044 omega_free_eqns (sub, 1);
3045 }
3046
3047 /* Helper function for printing "sorry, no solution". */
3048
3049 static inline enum omega_result
3050 omega_problem_has_no_solution (void)
3051 {
3052 if (dump_file && (dump_flags & TDF_DETAILS))
3053 fprintf (dump_file, "\nequations have no solution \n");
3054
3055 return omega_false;
3056 }
3057
3058 /* Helper function: solve equations in PB one at a time, following the
3059 DESIRED_RES result. */
3060
3061 static enum omega_result
3062 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3063 {
3064 int i, j, e;
3065 int g, g2;
3066 g = 0;
3067
3068
3069 if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3070 {
3071 fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3072 desired_res, may_be_red);
3073 omega_print_problem (dump_file, pb);
3074 fprintf (dump_file, "\n");
3075 }
3076
3077 if (may_be_red)
3078 {
3079 i = 0;
3080 j = pb->num_eqs - 1;
3081
3082 while (1)
3083 {
3084 eqn eq;
3085
3086 while (i <= j && pb->eqs[i].color == omega_red)
3087 i++;
3088
3089 while (i <= j && pb->eqs[j].color == omega_black)
3090 j--;
3091
3092 if (i >= j)
3093 break;
3094
3095 eq = omega_alloc_eqns (0, 1);
3096 omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3097 omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3098 omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3099 omega_free_eqns (eq, 1);
3100 i++;
3101 j--;
3102 }
3103 }
3104
3105 /* Eliminate all EQ equations */
3106 for (e = pb->num_eqs - 1; e >= 0; e--)
3107 {
3108 eqn eqn = &(pb->eqs[e]);
3109 int sv;
3110
3111 if (dump_file && (dump_flags & TDF_DETAILS))
3112 fprintf (dump_file, "----\n");
3113
3114 for (i = pb->num_vars; i > 0; i--)
3115 if (eqn->coef[i])
3116 break;
3117
3118 g = eqn->coef[i];
3119
3120 for (j = i - 1; j > 0; j--)
3121 if (eqn->coef[j])
3122 break;
3123
3124 /* i is the position of last nonzero coefficient,
3125 g is the coefficient of i,
3126 j is the position of next nonzero coefficient. */
3127
3128 if (j == 0)
3129 {
3130 if (eqn->coef[0] % g != 0)
3131 return omega_problem_has_no_solution ();
3132
3133 eqn->coef[0] = eqn->coef[0] / g;
3134 eqn->coef[i] = 1;
3135 pb->num_eqs--;
3136 omega_do_elimination (pb, e, i);
3137 continue;
3138 }
3139
3140 else if (j == -1)
3141 {
3142 if (eqn->coef[0] != 0)
3143 return omega_problem_has_no_solution ();
3144
3145 pb->num_eqs--;
3146 continue;
3147 }
3148
3149 if (g < 0)
3150 g = -g;
3151
3152 if (g == 1)
3153 {
3154 pb->num_eqs--;
3155 omega_do_elimination (pb, e, i);
3156 }
3157
3158 else
3159 {
3160 int k = j;
3161 bool promotion_possible =
3162 (omega_safe_var_p (pb, j)
3163 && pb->safe_vars + 1 == i
3164 && !omega_eqn_is_red (eqn, desired_res)
3165 && !in_approximate_mode);
3166
3167 if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3168 fprintf (dump_file, " Promotion possible\n");
3169
3170 normalizeEQ:
3171 if (!omega_safe_var_p (pb, j))
3172 {
3173 for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3174 g = gcd (abs (eqn->coef[j]), g);
3175 g2 = g;
3176 }
3177 else if (!omega_safe_var_p (pb, i))
3178 g2 = g;
3179 else
3180 g2 = 0;
3181
3182 for (; g != 1 && j > 0; j--)
3183 g = gcd (abs (eqn->coef[j]), g);
3184
3185 if (g > 1)
3186 {
3187 if (eqn->coef[0] % g != 0)
3188 return omega_problem_has_no_solution ();
3189
3190 for (j = 0; j <= pb->num_vars; j++)
3191 eqn->coef[j] /= g;
3192
3193 g2 = g2 / g;
3194 }
3195
3196 if (g2 > 1)
3197 {
3198 int e2;
3199
3200 for (e2 = e - 1; e2 >= 0; e2--)
3201 if (pb->eqs[e2].coef[i])
3202 break;
3203
3204 if (e2 == -1)
3205 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3206 if (pb->geqs[e2].coef[i])
3207 break;
3208
3209 if (e2 == -1)
3210 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3211 if (pb->subs[e2].coef[i])
3212 break;
3213
3214 if (e2 == -1)
3215 {
3216 bool change = false;
3217
3218 if (dump_file && (dump_flags & TDF_DETAILS))
3219 {
3220 fprintf (dump_file, "Ha! We own it! \n");
3221 omega_print_eq (dump_file, pb, eqn);
3222 fprintf (dump_file, " \n");
3223 }
3224
3225 g = eqn->coef[i];
3226 g = abs (g);
3227
3228 for (j = i - 1; j >= 0; j--)
3229 {
3230 int t = int_mod (eqn->coef[j], g);
3231
3232 if (2 * t >= g)
3233 t -= g;
3234
3235 if (t != eqn->coef[j])
3236 {
3237 eqn->coef[j] = t;
3238 change = true;
3239 }
3240 }
3241
3242 if (!change)
3243 {
3244 if (dump_file && (dump_flags & TDF_DETAILS))
3245 fprintf (dump_file, "So what?\n");
3246 }
3247
3248 else
3249 {
3250 omega_name_wild_card (pb, i);
3251
3252 if (dump_file && (dump_flags & TDF_DETAILS))
3253 {
3254 omega_print_eq (dump_file, pb, eqn);
3255 fprintf (dump_file, " \n");
3256 }
3257
3258 e++;
3259 continue;
3260 }
3261 }
3262 }
3263
3264 if (promotion_possible)
3265 {
3266 if (dump_file && (dump_flags & TDF_DETAILS))
3267 {
3268 fprintf (dump_file, "promoting %s to safety\n",
3269 omega_variable_to_str (pb, i));
3270 omega_print_vars (dump_file, pb);
3271 }
3272
3273 pb->safe_vars++;
3274
3275 if (!omega_wildcard_p (pb, i))
3276 omega_name_wild_card (pb, i);
3277
3278 promotion_possible = false;
3279 j = k;
3280 goto normalizeEQ;
3281 }
3282
3283 if (g2 > 1 && !in_approximate_mode)
3284 {
3285 if (pb->eqs[e].color == omega_red)
3286 {
3287 if (dump_file && (dump_flags & TDF_DETAILS))
3288 fprintf (dump_file, "handling red equality\n");
3289
3290 pb->num_eqs--;
3291 omega_do_elimination (pb, e, i);
3292 continue;
3293 }
3294
3295 if (dump_file && (dump_flags & TDF_DETAILS))
3296 {
3297 fprintf (dump_file,
3298 "adding equation to handle safe variable \n");
3299 omega_print_eq (dump_file, pb, eqn);
3300 fprintf (dump_file, "\n----\n");
3301 omega_print_problem (dump_file, pb);
3302 fprintf (dump_file, "\n----\n");
3303 fprintf (dump_file, "\n----\n");
3304 }
3305
3306 i = omega_add_new_wild_card (pb);
3307 pb->num_eqs++;
3308 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3309 omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3310 omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3311
3312 for (j = pb->num_vars; j >= 0; j--)
3313 {
3314 pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3315
3316 if (2 * pb->eqs[e + 1].coef[j] >= g2)
3317 pb->eqs[e + 1].coef[j] -= g2;
3318 }
3319
3320 pb->eqs[e + 1].coef[i] = g2;
3321 e += 2;
3322
3323 if (dump_file && (dump_flags & TDF_DETAILS))
3324 omega_print_problem (dump_file, pb);
3325
3326 continue;
3327 }
3328
3329 sv = pb->safe_vars;
3330 if (g2 == 0)
3331 sv = 0;
3332
3333 /* Find variable to eliminate. */
3334 if (g2 > 1)
3335 {
3336 gcc_assert (in_approximate_mode);
3337
3338 if (dump_file && (dump_flags & TDF_DETAILS))
3339 {
3340 fprintf (dump_file, "non-exact elimination: ");
3341 omega_print_eq (dump_file, pb, eqn);
3342 fprintf (dump_file, "\n");
3343 omega_print_problem (dump_file, pb);
3344 }
3345
3346 for (i = pb->num_vars; i > sv; i--)
3347 if (pb->eqs[e].coef[i] != 0)
3348 break;
3349 }
3350 else
3351 for (i = pb->num_vars; i > sv; i--)
3352 if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3353 break;
3354
3355 if (i > sv)
3356 {
3357 pb->num_eqs--;
3358 omega_do_elimination (pb, e, i);
3359
3360 if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3361 {
3362 fprintf (dump_file, "result of non-exact elimination:\n");
3363 omega_print_problem (dump_file, pb);
3364 }
3365 }
3366 else
3367 {
3368 int factor = (INT_MAX);
3369 j = 0;
3370
3371 if (dump_file && (dump_flags & TDF_DETAILS))
3372 fprintf (dump_file, "doing moding\n");
3373
3374 for (i = pb->num_vars; i != sv; i--)
3375 if ((pb->eqs[e].coef[i] & 1) != 0)
3376 {
3377 j = i;
3378 i--;
3379
3380 for (; i != sv; i--)
3381 if ((pb->eqs[e].coef[i] & 1) != 0)
3382 break;
3383
3384 break;
3385 }
3386
3387 if (j != 0 && i == sv)
3388 {
3389 omega_do_mod (pb, 2, e, j);
3390 e++;
3391 continue;
3392 }
3393
3394 j = 0;
3395 for (i = pb->num_vars; i != sv; i--)
3396 if (pb->eqs[e].coef[i] != 0
3397 && factor > abs (pb->eqs[e].coef[i]) + 1)
3398 {
3399 factor = abs (pb->eqs[e].coef[i]) + 1;
3400 j = i;
3401 }
3402
3403 if (j == sv)
3404 {
3405 if (dump_file && (dump_flags & TDF_DETAILS))
3406 fprintf (dump_file, "should not have happened\n");
3407 gcc_assert (0);
3408 }
3409
3410 omega_do_mod (pb, factor, e, j);
3411 /* Go back and try this equation again. */
3412 e++;
3413 }
3414 }
3415 }
3416
3417 pb->num_eqs = 0;
3418 return omega_unknown;
3419 }
3420
3421 /* Transform an inequation E to an equality, then solve DIFF problems
3422 based on PB, and only differing by the constant part that is
3423 diminished by one, trying to figure out which of the constants
3424 satisfies PB. */
3425
3426 static enum omega_result
3427 parallel_splinter (omega_pb pb, int e, int diff,
3428 enum omega_result desired_res)
3429 {
3430 omega_pb tmp_problem;
3431 int i;
3432
3433 if (dump_file && (dump_flags & TDF_DETAILS))
3434 {
3435 fprintf (dump_file, "Using parallel splintering\n");
3436 omega_print_problem (dump_file, pb);
3437 }
3438
3439 tmp_problem = XNEW (struct omega_pb_d);
3440 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3441 pb->num_eqs = 1;
3442
3443 for (i = 0; i <= diff; i++)
3444 {
3445 omega_copy_problem (tmp_problem, pb);
3446
3447 if (dump_file && (dump_flags & TDF_DETAILS))
3448 {
3449 fprintf (dump_file, "Splinter # %i\n", i);
3450 omega_print_problem (dump_file, pb);
3451 }
3452
3453 if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3454 {
3455 free (tmp_problem);
3456 return omega_true;
3457 }
3458
3459 pb->eqs[0].coef[0]--;
3460 }
3461
3462 free (tmp_problem);
3463 return omega_false;
3464 }
3465
3466 /* Helper function: solve equations one at a time. */
3467
3468 static enum omega_result
3469 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3470 {
3471 int i, e;
3472 int n_vars, fv;
3473 enum omega_result result;
3474 bool coupled_subscripts = false;
3475 bool smoothed = false;
3476 bool eliminate_again;
3477 bool tried_eliminating_redundant = false;
3478
3479 if (desired_res != omega_simplify)
3480 {
3481 pb->num_subs = 0;
3482 pb->safe_vars = 0;
3483 }
3484
3485 solve_geq_start:
3486 do {
3487 gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3488
3489 /* Verify that there are not too many inequalities. */
3490 gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3491
3492 if (dump_file && (dump_flags & TDF_DETAILS))
3493 {
3494 fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3495 desired_res, please_no_equalities_in_simplified_problems);
3496 omega_print_problem (dump_file, pb);
3497 fprintf (dump_file, "\n");
3498 }
3499
3500 n_vars = pb->num_vars;
3501
3502 if (n_vars == 1)
3503 {
3504 enum omega_eqn_color u_color = omega_black;
3505 enum omega_eqn_color l_color = omega_black;
3506 int upper_bound = pos_infinity;
3507 int lower_bound = neg_infinity;
3508
3509 for (e = pb->num_geqs - 1; e >= 0; e--)
3510 {
3511 int a = pb->geqs[e].coef[1];
3512 int c = pb->geqs[e].coef[0];
3513
3514 /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
3515 if (a == 0)
3516 {
3517 if (c < 0)
3518 return omega_problem_has_no_solution ();
3519 }
3520 else if (a > 0)
3521 {
3522 if (a != 1)
3523 c = int_div (c, a);
3524
3525 if (lower_bound < -c
3526 || (lower_bound == -c
3527 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3528 {
3529 lower_bound = -c;
3530 l_color = pb->geqs[e].color;
3531 }
3532 }
3533 else
3534 {
3535 if (a != -1)
3536 c = int_div (c, -a);
3537
3538 if (upper_bound > c
3539 || (upper_bound == c
3540 && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3541 {
3542 upper_bound = c;
3543 u_color = pb->geqs[e].color;
3544 }
3545 }
3546 }
3547
3548 if (dump_file && (dump_flags & TDF_DETAILS))
3549 {
3550 fprintf (dump_file, "upper bound = %d\n", upper_bound);
3551 fprintf (dump_file, "lower bound = %d\n", lower_bound);
3552 }
3553
3554 if (lower_bound > upper_bound)
3555 return omega_problem_has_no_solution ();
3556
3557 if (desired_res == omega_simplify)
3558 {
3559 pb->num_geqs = 0;
3560 if (pb->safe_vars == 1)
3561 {
3562
3563 if (lower_bound == upper_bound
3564 && u_color == omega_black
3565 && l_color == omega_black)
3566 {
3567 pb->eqs[0].coef[0] = -lower_bound;
3568 pb->eqs[0].coef[1] = 1;
3569 pb->eqs[0].color = omega_black;
3570 pb->num_eqs = 1;
3571 return omega_solve_problem (pb, desired_res);
3572 }
3573 else
3574 {
3575 if (lower_bound > neg_infinity)
3576 {
3577 pb->geqs[0].coef[0] = -lower_bound;
3578 pb->geqs[0].coef[1] = 1;
3579 pb->geqs[0].key = 1;
3580 pb->geqs[0].color = l_color;
3581 pb->geqs[0].touched = 0;
3582 pb->num_geqs = 1;
3583 }
3584
3585 if (upper_bound < pos_infinity)
3586 {
3587 pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3588 pb->geqs[pb->num_geqs].coef[1] = -1;
3589 pb->geqs[pb->num_geqs].key = -1;
3590 pb->geqs[pb->num_geqs].color = u_color;
3591 pb->geqs[pb->num_geqs].touched = 0;
3592 pb->num_geqs++;
3593 }
3594 }
3595 }
3596 else
3597 pb->num_vars = 0;
3598
3599 omega_problem_reduced (pb);
3600 return omega_false;
3601 }
3602
3603 if (original_problem != no_problem
3604 && l_color == omega_black
3605 && u_color == omega_black
3606 && !conservative
3607 && lower_bound == upper_bound)
3608 {
3609 pb->eqs[0].coef[0] = -lower_bound;
3610 pb->eqs[0].coef[1] = 1;
3611 pb->num_eqs = 1;
3612 adding_equality_constraint (pb, 0);
3613 }
3614
3615 return omega_true;
3616 }
3617
3618 if (!pb->variables_freed)
3619 {
3620 pb->variables_freed = true;
3621
3622 if (desired_res != omega_simplify)
3623 omega_free_eliminations (pb, 0);
3624 else
3625 omega_free_eliminations (pb, pb->safe_vars);
3626
3627 n_vars = pb->num_vars;
3628
3629 if (n_vars == 1)
3630 continue;
3631 }
3632
3633 switch (normalize_omega_problem (pb))
3634 {
3635 case normalize_false:
3636 return omega_false;
3637 break;
3638
3639 case normalize_coupled:
3640 coupled_subscripts = true;
3641 break;
3642
3643 case normalize_uncoupled:
3644 coupled_subscripts = false;
3645 break;
3646
3647 default:
3648 gcc_unreachable ();
3649 }
3650
3651 n_vars = pb->num_vars;
3652
3653 if (dump_file && (dump_flags & TDF_DETAILS))
3654 {
3655 fprintf (dump_file, "\nafter normalization:\n");
3656 omega_print_problem (dump_file, pb);
3657 fprintf (dump_file, "\n");
3658 fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3659 }
3660
3661 do {
3662 int parallel_difference = INT_MAX;
3663 int best_parallel_eqn = -1;
3664 int minC, maxC, minCj = 0;
3665 int lower_bound_count = 0;
3666 int e2, Le = 0, Ue;
3667 bool possible_easy_int_solution;
3668 int max_splinters = 1;
3669 bool exact = false;
3670 bool lucky_exact = false;
3671 int best = (INT_MAX);
3672 int j = 0, jLe = 0, jLowerBoundCount = 0;
3673
3674
3675 eliminate_again = false;
3676
3677 if (pb->num_eqs > 0)
3678 return omega_solve_problem (pb, desired_res);
3679
3680 if (!coupled_subscripts)
3681 {
3682 if (pb->safe_vars == 0)
3683 pb->num_geqs = 0;
3684 else
3685 for (e = pb->num_geqs - 1; e >= 0; e--)
3686 if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3687 omega_delete_geq (pb, e, n_vars);
3688
3689 pb->num_vars = pb->safe_vars;
3690
3691 if (desired_res == omega_simplify)
3692 {
3693 omega_problem_reduced (pb);
3694 return omega_false;
3695 }
3696
3697 return omega_true;
3698 }
3699
3700 if (desired_res != omega_simplify)
3701 fv = 0;
3702 else
3703 fv = pb->safe_vars;
3704
3705 if (pb->num_geqs == 0)
3706 {
3707 if (desired_res == omega_simplify)
3708 {
3709 pb->num_vars = pb->safe_vars;
3710 omega_problem_reduced (pb);
3711 return omega_false;
3712 }
3713 return omega_true;
3714 }
3715
3716 if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3717 {
3718 omega_problem_reduced (pb);
3719 return omega_false;
3720 }
3721
3722 if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3723 || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3724 {
3725 if (dump_file && (dump_flags & TDF_DETAILS))
3726 fprintf (dump_file,
3727 "TOO MANY EQUATIONS; "
3728 "%d equations, %d variables, "
3729 "ELIMINATING REDUNDANT ONES\n",
3730 pb->num_geqs, n_vars);
3731
3732 if (!omega_eliminate_redundant (pb, false))
3733 return omega_false;
3734
3735 n_vars = pb->num_vars;
3736
3737 if (pb->num_eqs > 0)
3738 return omega_solve_problem (pb, desired_res);
3739
3740 if (dump_file && (dump_flags & TDF_DETAILS))
3741 fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3742 }
3743
3744 if (desired_res != omega_simplify)
3745 fv = 0;
3746 else
3747 fv = pb->safe_vars;
3748
3749 for (i = n_vars; i != fv; i--)
3750 {
3751 int score;
3752 int ub = -2;
3753 int lb = -2;
3754 bool lucky = false;
3755 int upper_bound_count = 0;
3756
3757 lower_bound_count = 0;
3758 minC = maxC = 0;
3759
3760 for (e = pb->num_geqs - 1; e >= 0; e--)
3761 if (pb->geqs[e].coef[i] < 0)
3762 {
3763 minC = MIN (minC, pb->geqs[e].coef[i]);
3764 upper_bound_count++;
3765 if (pb->geqs[e].coef[i] < -1)
3766 {
3767 if (ub == -2)
3768 ub = e;
3769 else
3770 ub = -1;
3771 }
3772 }
3773 else if (pb->geqs[e].coef[i] > 0)
3774 {
3775 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3776 lower_bound_count++;
3777 Le = e;
3778 if (pb->geqs[e].coef[i] > 1)
3779 {
3780 if (lb == -2)
3781 lb = e;
3782 else
3783 lb = -1;
3784 }
3785 }
3786
3787 if (lower_bound_count == 0
3788 || upper_bound_count == 0)
3789 {
3790 lower_bound_count = 0;
3791 break;
3792 }
3793
3794 if (ub >= 0 && lb >= 0
3795 && pb->geqs[lb].key == -pb->geqs[ub].key)
3796 {
3797 int Lc = pb->geqs[lb].coef[i];
3798 int Uc = -pb->geqs[ub].coef[i];
3799 int diff =
3800 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3801 lucky = (diff >= (Uc - 1) * (Lc - 1));
3802 }
3803
3804 if (maxC == 1
3805 || minC == -1
3806 || lucky
3807 || in_approximate_mode)
3808 {
3809 score = upper_bound_count * lower_bound_count;
3810
3811 if (dump_file && (dump_flags & TDF_DETAILS))
3812 fprintf (dump_file,
3813 "For %s, exact, score = %d*%d, range = %d ... %d,"
3814 "\nlucky = %d, in_approximate_mode=%d \n",
3815 omega_variable_to_str (pb, i),
3816 upper_bound_count,
3817 lower_bound_count, minC, maxC, lucky,
3818 in_approximate_mode);
3819
3820 if (!exact
3821 || score < best)
3822 {
3823
3824 best = score;
3825 j = i;
3826 minCj = minC;
3827 jLe = Le;
3828 jLowerBoundCount = lower_bound_count;
3829 exact = true;
3830 lucky_exact = lucky;
3831 if (score == 1)
3832 break;
3833 }
3834 }
3835 else if (!exact)
3836 {
3837 if (dump_file && (dump_flags & TDF_DETAILS))
3838 fprintf (dump_file,
3839 "For %s, non-exact, score = %d*%d,"
3840 "range = %d ... %d \n",
3841 omega_variable_to_str (pb, i),
3842 upper_bound_count,
3843 lower_bound_count, minC, maxC);
3844
3845 score = maxC - minC;
3846
3847 if (best > score)
3848 {
3849 best = score;
3850 j = i;
3851 minCj = minC;
3852 jLe = Le;
3853 jLowerBoundCount = lower_bound_count;
3854 }
3855 }
3856 }
3857
3858 if (lower_bound_count == 0)
3859 {
3860 omega_free_eliminations (pb, pb->safe_vars);
3861 n_vars = pb->num_vars;
3862 eliminate_again = true;
3863 continue;
3864 }
3865
3866 i = j;
3867 minC = minCj;
3868 Le = jLe;
3869 lower_bound_count = jLowerBoundCount;
3870
3871 for (e = pb->num_geqs - 1; e >= 0; e--)
3872 if (pb->geqs[e].coef[i] > 0)
3873 {
3874 if (pb->geqs[e].coef[i] == -minC)
3875 max_splinters += -minC - 1;
3876 else
3877 max_splinters +=
3878 pos_mul_hwi ((pb->geqs[e].coef[i] - 1),
3879 (-minC - 1)) / (-minC) + 1;
3880 }
3881
3882 /* #ifdef Omega3 */
3883 /* Trying to produce exact elimination by finding redundant
3884 constraints. */
3885 if (!exact && !tried_eliminating_redundant)
3886 {
3887 omega_eliminate_redundant (pb, false);
3888 tried_eliminating_redundant = true;
3889 eliminate_again = true;
3890 continue;
3891 }
3892 tried_eliminating_redundant = false;
3893 /* #endif */
3894
3895 if (return_single_result && desired_res == omega_simplify && !exact)
3896 {
3897 omega_problem_reduced (pb);
3898 return omega_true;
3899 }
3900
3901 /* #ifndef Omega3 */
3902 /* Trying to produce exact elimination by finding redundant
3903 constraints. */
3904 if (!exact && !tried_eliminating_redundant)
3905 {
3906 omega_eliminate_redundant (pb, false);
3907 tried_eliminating_redundant = true;
3908 continue;
3909 }
3910 tried_eliminating_redundant = false;
3911 /* #endif */
3912
3913 if (!exact)
3914 {
3915 int e1, e2;
3916
3917 for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3918 if (pb->geqs[e1].color == omega_black)
3919 for (e2 = e1 - 1; e2 >= 0; e2--)
3920 if (pb->geqs[e2].color == omega_black
3921 && pb->geqs[e1].key == -pb->geqs[e2].key
3922 && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3923 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3924 / 2 < parallel_difference))
3925 {
3926 parallel_difference =
3927 (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3928 * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3929 / 2;
3930 best_parallel_eqn = e1;
3931 }
3932
3933 if (dump_file && (dump_flags & TDF_DETAILS)
3934 && best_parallel_eqn >= 0)
3935 {
3936 fprintf (dump_file,
3937 "Possible parallel projection, diff = %d, in ",
3938 parallel_difference);
3939 omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3940 fprintf (dump_file, "\n");
3941 omega_print_problem (dump_file, pb);
3942 }
3943 }
3944
3945 if (dump_file && (dump_flags & TDF_DETAILS))
3946 {
3947 fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
3948 omega_variable_to_str (pb, i), i, minC,
3949 lower_bound_count);
3950 omega_print_problem (dump_file, pb);
3951
3952 if (lucky_exact)
3953 fprintf (dump_file, "(a lucky exact elimination)\n");
3954
3955 else if (exact)
3956 fprintf (dump_file, "(an exact elimination)\n");
3957
3958 fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
3959 }
3960
3961 gcc_assert (max_splinters >= 1);
3962
3963 if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
3964 && parallel_difference <= max_splinters)
3965 return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
3966 desired_res);
3967
3968 smoothed = false;
3969
3970 if (i != n_vars)
3971 {
3972 int t;
3973 int j = pb->num_vars;
3974
3975 if (dump_file && (dump_flags & TDF_DETAILS))
3976 {
3977 fprintf (dump_file, "Swapping %d and %d\n", i, j);
3978 omega_print_problem (dump_file, pb);
3979 }
3980
3981 swap (&pb->var[i], &pb->var[j]);
3982
3983 for (e = pb->num_geqs - 1; e >= 0; e--)
3984 if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
3985 {
3986 pb->geqs[e].touched = 1;
3987 t = pb->geqs[e].coef[i];
3988 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
3989 pb->geqs[e].coef[j] = t;
3990 }
3991
3992 for (e = pb->num_subs - 1; e >= 0; e--)
3993 if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
3994 {
3995 t = pb->subs[e].coef[i];
3996 pb->subs[e].coef[i] = pb->subs[e].coef[j];
3997 pb->subs[e].coef[j] = t;
3998 }
3999
4000 if (dump_file && (dump_flags & TDF_DETAILS))
4001 {
4002 fprintf (dump_file, "Swapping complete \n");
4003 omega_print_problem (dump_file, pb);
4004 fprintf (dump_file, "\n");
4005 }
4006
4007 i = j;
4008 }
4009
4010 else if (dump_file && (dump_flags & TDF_DETAILS))
4011 {
4012 fprintf (dump_file, "No swap needed\n");
4013 omega_print_problem (dump_file, pb);
4014 }
4015
4016 pb->num_vars--;
4017 n_vars = pb->num_vars;
4018
4019 if (exact)
4020 {
4021 if (n_vars == 1)
4022 {
4023 int upper_bound = pos_infinity;
4024 int lower_bound = neg_infinity;
4025 enum omega_eqn_color ub_color = omega_black;
4026 enum omega_eqn_color lb_color = omega_black;
4027 int topeqn = pb->num_geqs - 1;
4028 int Lc = pb->geqs[Le].coef[i];
4029
4030 for (Le = topeqn; Le >= 0; Le--)
4031 if ((Lc = pb->geqs[Le].coef[i]) == 0)
4032 {
4033 if (pb->geqs[Le].coef[1] == 1)
4034 {
4035 int constantTerm = -pb->geqs[Le].coef[0];
4036
4037 if (constantTerm > lower_bound ||
4038 (constantTerm == lower_bound &&
4039 !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
4040 {
4041 lower_bound = constantTerm;
4042 lb_color = pb->geqs[Le].color;
4043 }
4044
4045 if (dump_file && (dump_flags & TDF_DETAILS))
4046 {
4047 if (pb->geqs[Le].color == omega_black)
4048 fprintf (dump_file, " :::=> %s >= %d\n",
4049 omega_variable_to_str (pb, 1),
4050 constantTerm);
4051 else
4052 fprintf (dump_file,
4053 " :::=> [%s >= %d]\n",
4054 omega_variable_to_str (pb, 1),
4055 constantTerm);
4056 }
4057 }
4058 else
4059 {
4060 int constantTerm = pb->geqs[Le].coef[0];
4061 if (constantTerm < upper_bound ||
4062 (constantTerm == upper_bound
4063 && !omega_eqn_is_red (&pb->geqs[Le],
4064 desired_res)))
4065 {
4066 upper_bound = constantTerm;
4067 ub_color = pb->geqs[Le].color;
4068 }
4069
4070 if (dump_file && (dump_flags & TDF_DETAILS))
4071 {
4072 if (pb->geqs[Le].color == omega_black)
4073 fprintf (dump_file, " :::=> %s <= %d\n",
4074 omega_variable_to_str (pb, 1),
4075 constantTerm);
4076 else
4077 fprintf (dump_file,
4078 " :::=> [%s <= %d]\n",
4079 omega_variable_to_str (pb, 1),
4080 constantTerm);
4081 }
4082 }
4083 }
4084 else if (Lc > 0)
4085 for (Ue = topeqn; Ue >= 0; Ue--)
4086 if (pb->geqs[Ue].coef[i] < 0
4087 && pb->geqs[Le].key != -pb->geqs[Ue].key)
4088 {
4089 int Uc = -pb->geqs[Ue].coef[i];
4090 int coefficient = pb->geqs[Ue].coef[1] * Lc
4091 + pb->geqs[Le].coef[1] * Uc;
4092 int constantTerm = pb->geqs[Ue].coef[0] * Lc
4093 + pb->geqs[Le].coef[0] * Uc;
4094
4095 if (dump_file && (dump_flags & TDF_DETAILS))
4096 {
4097 omega_print_geq_extra (dump_file, pb,
4098 &(pb->geqs[Ue]));
4099 fprintf (dump_file, "\n");
4100 omega_print_geq_extra (dump_file, pb,
4101 &(pb->geqs[Le]));
4102 fprintf (dump_file, "\n");
4103 }
4104
4105 if (coefficient > 0)
4106 {
4107 constantTerm = -int_div (constantTerm, coefficient);
4108
4109 if (constantTerm > lower_bound
4110 || (constantTerm == lower_bound
4111 && (desired_res != omega_simplify
4112 || (pb->geqs[Ue].color == omega_black
4113 && pb->geqs[Le].color == omega_black))))
4114 {
4115 lower_bound = constantTerm;
4116 lb_color = (pb->geqs[Ue].color == omega_red
4117 || pb->geqs[Le].color == omega_red)
4118 ? omega_red : omega_black;
4119 }
4120
4121 if (dump_file && (dump_flags & TDF_DETAILS))
4122 {
4123 if (pb->geqs[Ue].color == omega_red
4124 || pb->geqs[Le].color == omega_red)
4125 fprintf (dump_file,
4126 " ::=> [%s >= %d]\n",
4127 omega_variable_to_str (pb, 1),
4128 constantTerm);
4129 else
4130 fprintf (dump_file,
4131 " ::=> %s >= %d\n",
4132 omega_variable_to_str (pb, 1),
4133 constantTerm);
4134 }
4135 }
4136 else
4137 {
4138 constantTerm = int_div (constantTerm, -coefficient);
4139 if (constantTerm < upper_bound
4140 || (constantTerm == upper_bound
4141 && pb->geqs[Ue].color == omega_black
4142 && pb->geqs[Le].color == omega_black))
4143 {
4144 upper_bound = constantTerm;
4145 ub_color = (pb->geqs[Ue].color == omega_red
4146 || pb->geqs[Le].color == omega_red)
4147 ? omega_red : omega_black;
4148 }
4149
4150 if (dump_file
4151 && (dump_flags & TDF_DETAILS))
4152 {
4153 if (pb->geqs[Ue].color == omega_red
4154 || pb->geqs[Le].color == omega_red)
4155 fprintf (dump_file,
4156 " ::=> [%s <= %d]\n",
4157 omega_variable_to_str (pb, 1),
4158 constantTerm);
4159 else
4160 fprintf (dump_file,
4161 " ::=> %s <= %d\n",
4162 omega_variable_to_str (pb, 1),
4163 constantTerm);
4164 }
4165 }
4166 }
4167
4168 pb->num_geqs = 0;
4169
4170 if (dump_file && (dump_flags & TDF_DETAILS))
4171 fprintf (dump_file,
4172 " therefore, %c%d <= %c%s%c <= %d%c\n",
4173 lb_color == omega_red ? '[' : ' ', lower_bound,
4174 (lb_color == omega_red && ub_color == omega_black)
4175 ? ']' : ' ',
4176 omega_variable_to_str (pb, 1),
4177 (lb_color == omega_black && ub_color == omega_red)
4178 ? '[' : ' ',
4179 upper_bound, ub_color == omega_red ? ']' : ' ');
4180
4181 if (lower_bound > upper_bound)
4182 return omega_false;
4183
4184 if (pb->safe_vars == 1)
4185 {
4186 if (upper_bound == lower_bound
4187 && !(ub_color == omega_red || lb_color == omega_red)
4188 && !please_no_equalities_in_simplified_problems)
4189 {
4190 pb->num_eqs++;
4191 pb->eqs[0].coef[1] = -1;
4192 pb->eqs[0].coef[0] = upper_bound;
4193
4194 if (ub_color == omega_red
4195 || lb_color == omega_red)
4196 pb->eqs[0].color = omega_red;
4197
4198 if (desired_res == omega_simplify
4199 && pb->eqs[0].color == omega_black)
4200 return omega_solve_problem (pb, desired_res);
4201 }
4202
4203 if (upper_bound != pos_infinity)
4204 {
4205 pb->geqs[0].coef[1] = -1;
4206 pb->geqs[0].coef[0] = upper_bound;
4207 pb->geqs[0].color = ub_color;
4208 pb->geqs[0].key = -1;
4209 pb->geqs[0].touched = 0;
4210 pb->num_geqs++;
4211 }
4212
4213 if (lower_bound != neg_infinity)
4214 {
4215 pb->geqs[pb->num_geqs].coef[1] = 1;
4216 pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
4217 pb->geqs[pb->num_geqs].color = lb_color;
4218 pb->geqs[pb->num_geqs].key = 1;
4219 pb->geqs[pb->num_geqs].touched = 0;
4220 pb->num_geqs++;
4221 }
4222 }
4223
4224 if (desired_res == omega_simplify)
4225 {
4226 omega_problem_reduced (pb);
4227 return omega_false;
4228 }
4229 else
4230 {
4231 if (!conservative
4232 && (desired_res != omega_simplify
4233 || (lb_color == omega_black
4234 && ub_color == omega_black))
4235 && original_problem != no_problem
4236 && lower_bound == upper_bound)
4237 {
4238 for (i = original_problem->num_vars; i >= 0; i--)
4239 if (original_problem->var[i] == pb->var[1])
4240 break;
4241
4242 if (i == 0)
4243 break;
4244
4245 e = original_problem->num_eqs++;
4246 omega_init_eqn_zero (&original_problem->eqs[e],
4247 original_problem->num_vars);
4248 original_problem->eqs[e].coef[i] = -1;
4249 original_problem->eqs[e].coef[0] = upper_bound;
4250
4251 if (dump_file && (dump_flags & TDF_DETAILS))
4252 {
4253 fprintf (dump_file,
4254 "adding equality %d to outer problem\n", e);
4255 omega_print_problem (dump_file, original_problem);
4256 }
4257 }
4258 return omega_true;
4259 }
4260 }
4261
4262 eliminate_again = true;
4263
4264 if (lower_bound_count == 1)
4265 {
4266 eqn lbeqn = omega_alloc_eqns (0, 1);
4267 int Lc = pb->geqs[Le].coef[i];
4268
4269 if (dump_file && (dump_flags & TDF_DETAILS))
4270 fprintf (dump_file, "an inplace elimination\n");
4271
4272 omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
4273 omega_delete_geq_extra (pb, Le, n_vars + 1);
4274
4275 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4276 if (pb->geqs[Ue].coef[i] < 0)
4277 {
4278 if (lbeqn->key == -pb->geqs[Ue].key)
4279 omega_delete_geq_extra (pb, Ue, n_vars + 1);
4280 else
4281 {
4282 int k;
4283 int Uc = -pb->geqs[Ue].coef[i];
4284 pb->geqs[Ue].touched = 1;
4285 eliminate_again = false;
4286
4287 if (lbeqn->color == omega_red)
4288 pb->geqs[Ue].color = omega_red;
4289
4290 for (k = 0; k <= n_vars; k++)
4291 pb->geqs[Ue].coef[k] =
4292 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4293 mul_hwi (lbeqn->coef[k], Uc);
4294
4295 if (dump_file && (dump_flags & TDF_DETAILS))
4296 {
4297 omega_print_geq (dump_file, pb,
4298 &(pb->geqs[Ue]));
4299 fprintf (dump_file, "\n");
4300 }
4301 }
4302 }
4303
4304 omega_free_eqns (lbeqn, 1);
4305 continue;
4306 }
4307 else
4308 {
4309 int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
4310 bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
4311 int num_dead = 0;
4312 int top_eqn = pb->num_geqs - 1;
4313 lower_bound_count--;
4314
4315 if (dump_file && (dump_flags & TDF_DETAILS))
4316 fprintf (dump_file, "lower bound count = %d\n",
4317 lower_bound_count);
4318
4319 for (Le = top_eqn; Le >= 0; Le--)
4320 if (pb->geqs[Le].coef[i] > 0)
4321 {
4322 int Lc = pb->geqs[Le].coef[i];
4323 for (Ue = top_eqn; Ue >= 0; Ue--)
4324 if (pb->geqs[Ue].coef[i] < 0)
4325 {
4326 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4327 {
4328 int k;
4329 int Uc = -pb->geqs[Ue].coef[i];
4330
4331 if (num_dead == 0)
4332 e2 = pb->num_geqs++;
4333 else
4334 e2 = dead_eqns[--num_dead];
4335
4336 gcc_assert (e2 < OMEGA_MAX_GEQS);
4337
4338 if (dump_file && (dump_flags & TDF_DETAILS))
4339 {
4340 fprintf (dump_file,
4341 "Le = %d, Ue = %d, gen = %d\n",
4342 Le, Ue, e2);
4343 omega_print_geq_extra (dump_file, pb,
4344 &(pb->geqs[Le]));
4345 fprintf (dump_file, "\n");
4346 omega_print_geq_extra (dump_file, pb,
4347 &(pb->geqs[Ue]));
4348 fprintf (dump_file, "\n");
4349 }
4350
4351 eliminate_again = false;
4352
4353 for (k = n_vars; k >= 0; k--)
4354 pb->geqs[e2].coef[k] =
4355 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4356 mul_hwi (pb->geqs[Le].coef[k], Uc);
4357
4358 pb->geqs[e2].coef[n_vars + 1] = 0;
4359 pb->geqs[e2].touched = 1;
4360
4361 if (pb->geqs[Ue].color == omega_red
4362 || pb->geqs[Le].color == omega_red)
4363 pb->geqs[e2].color = omega_red;
4364 else
4365 pb->geqs[e2].color = omega_black;
4366
4367 if (dump_file && (dump_flags & TDF_DETAILS))
4368 {
4369 omega_print_geq (dump_file, pb,
4370 &(pb->geqs[e2]));
4371 fprintf (dump_file, "\n");
4372 }
4373 }
4374
4375 if (lower_bound_count == 0)
4376 {
4377 dead_eqns[num_dead++] = Ue;
4378
4379 if (dump_file && (dump_flags & TDF_DETAILS))
4380 fprintf (dump_file, "Killed %d\n", Ue);
4381 }
4382 }
4383
4384 lower_bound_count--;
4385 dead_eqns[num_dead++] = Le;
4386
4387 if (dump_file && (dump_flags & TDF_DETAILS))
4388 fprintf (dump_file, "Killed %d\n", Le);
4389 }
4390
4391 for (e = pb->num_geqs - 1; e >= 0; e--)
4392 is_dead[e] = false;
4393
4394 while (num_dead > 0)
4395 is_dead[dead_eqns[--num_dead]] = true;
4396
4397 for (e = pb->num_geqs - 1; e >= 0; e--)
4398 if (is_dead[e])
4399 omega_delete_geq_extra (pb, e, n_vars + 1);
4400
4401 free (dead_eqns);
4402 free (is_dead);
4403 continue;
4404 }
4405 }
4406 else
4407 {
4408 omega_pb rS, iS;
4409
4410 rS = omega_alloc_problem (0, 0);
4411 iS = omega_alloc_problem (0, 0);
4412 e2 = 0;
4413 possible_easy_int_solution = true;
4414
4415 for (e = 0; e < pb->num_geqs; e++)
4416 if (pb->geqs[e].coef[i] == 0)
4417 {
4418 omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
4419 pb->num_vars);
4420 omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
4421 pb->num_vars);
4422
4423 if (dump_file && (dump_flags & TDF_DETAILS))
4424 {
4425 int t;
4426 fprintf (dump_file, "Copying (%d, %d): ", i,
4427 pb->geqs[e].coef[i]);
4428 omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
4429 fprintf (dump_file, "\n");
4430 for (t = 0; t <= n_vars + 1; t++)
4431 fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
4432 fprintf (dump_file, "\n");
4433
4434 }
4435 e2++;
4436 gcc_assert (e2 < OMEGA_MAX_GEQS);
4437 }
4438
4439 for (Le = pb->num_geqs - 1; Le >= 0; Le--)
4440 if (pb->geqs[Le].coef[i] > 0)
4441 for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4442 if (pb->geqs[Ue].coef[i] < 0)
4443 {
4444 int k;
4445 int Lc = pb->geqs[Le].coef[i];
4446 int Uc = -pb->geqs[Ue].coef[i];
4447
4448 if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4449 {
4450
4451 rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
4452
4453 if (dump_file && (dump_flags & TDF_DETAILS))
4454 {
4455 fprintf (dump_file, "---\n");
4456 fprintf (dump_file,
4457 "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4458 Le, Lc, Ue, Uc, e2);
4459 omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
4460 fprintf (dump_file, "\n");
4461 omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
4462 fprintf (dump_file, "\n");
4463 }
4464
4465 if (Uc == Lc)
4466 {
4467 for (k = n_vars; k >= 0; k--)
4468 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4469 pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
4470
4471 iS->geqs[e2].coef[0] -= (Uc - 1);
4472 }
4473 else
4474 {
4475 for (k = n_vars; k >= 0; k--)
4476 iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4477 mul_hwi (pb->geqs[Ue].coef[k], Lc) +
4478 mul_hwi (pb->geqs[Le].coef[k], Uc);
4479
4480 iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
4481 }
4482
4483 if (pb->geqs[Ue].color == omega_red
4484 || pb->geqs[Le].color == omega_red)
4485 iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
4486 else
4487 iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
4488
4489 if (dump_file && (dump_flags & TDF_DETAILS))
4490 {
4491 omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
4492 fprintf (dump_file, "\n");
4493 }
4494
4495 e2++;
4496 gcc_assert (e2 < OMEGA_MAX_GEQS);
4497 }
4498 else if (pb->geqs[Ue].coef[0] * Lc +
4499 pb->geqs[Le].coef[0] * Uc -
4500 (Uc - 1) * (Lc - 1) < 0)
4501 possible_easy_int_solution = false;
4502 }
4503
4504 iS->variables_initialized = rS->variables_initialized = true;
4505 iS->num_vars = rS->num_vars = pb->num_vars;
4506 iS->num_geqs = rS->num_geqs = e2;
4507 iS->num_eqs = rS->num_eqs = 0;
4508 iS->num_subs = rS->num_subs = pb->num_subs;
4509 iS->safe_vars = rS->safe_vars = pb->safe_vars;
4510
4511 for (e = n_vars; e >= 0; e--)
4512 rS->var[e] = pb->var[e];
4513
4514 for (e = n_vars; e >= 0; e--)
4515 iS->var[e] = pb->var[e];
4516
4517 for (e = pb->num_subs - 1; e >= 0; e--)
4518 {
4519 omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
4520 omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
4521 }
4522
4523 pb->num_vars++;
4524 n_vars = pb->num_vars;
4525
4526 if (desired_res != omega_true)
4527 {
4528 if (original_problem == no_problem)
4529 {
4530 original_problem = pb;
4531 result = omega_solve_geq (rS, omega_false);
4532 original_problem = no_problem;
4533 }
4534 else
4535 result = omega_solve_geq (rS, omega_false);
4536
4537 if (result == omega_false)
4538 {
4539 free (rS);
4540 free (iS);
4541 return result;
4542 }
4543
4544 if (pb->num_eqs > 0)
4545 {
4546 /* An equality constraint must have been found */
4547 free (rS);
4548 free (iS);
4549 return omega_solve_problem (pb, desired_res);
4550 }
4551 }
4552
4553 if (desired_res != omega_false)
4554 {
4555 int j;
4556 int lower_bounds = 0;
4557 int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
4558
4559 if (possible_easy_int_solution)
4560 {
4561 conservative++;
4562 result = omega_solve_geq (iS, desired_res);
4563 conservative--;
4564
4565 if (result != omega_false)
4566 {
4567 free (rS);
4568 free (iS);
4569 free (lower_bound);
4570 return result;
4571 }
4572 }
4573
4574 if (!exact && best_parallel_eqn >= 0
4575 && parallel_difference <= max_splinters)
4576 {
4577 free (rS);
4578 free (iS);
4579 free (lower_bound);
4580 return parallel_splinter (pb, best_parallel_eqn,
4581 parallel_difference,
4582 desired_res);
4583 }
4584
4585 if (dump_file && (dump_flags & TDF_DETAILS))
4586 fprintf (dump_file, "have to do exact analysis\n");
4587
4588 conservative++;
4589
4590 for (e = 0; e < pb->num_geqs; e++)
4591 if (pb->geqs[e].coef[i] > 1)
4592 lower_bound[lower_bounds++] = e;
4593
4594 /* Sort array LOWER_BOUND. */
4595 for (j = 0; j < lower_bounds; j++)
4596 {
4597 int k, smallest = j;
4598
4599 for (k = j + 1; k < lower_bounds; k++)
4600 if (pb->geqs[lower_bound[smallest]].coef[i] >
4601 pb->geqs[lower_bound[k]].coef[i])
4602 smallest = k;
4603
4604 k = lower_bound[smallest];
4605 lower_bound[smallest] = lower_bound[j];
4606 lower_bound[j] = k;
4607 }
4608
4609 if (dump_file && (dump_flags & TDF_DETAILS))
4610 {
4611 fprintf (dump_file, "lower bound coefficients = ");
4612
4613 for (j = 0; j < lower_bounds; j++)
4614 fprintf (dump_file, " %d",
4615 pb->geqs[lower_bound[j]].coef[i]);
4616
4617 fprintf (dump_file, "\n");
4618 }
4619
4620 for (j = 0; j < lower_bounds; j++)
4621 {
4622 int max_incr;
4623 int c;
4624 int worst_lower_bound_constant = -minC;
4625
4626 e = lower_bound[j];
4627 max_incr = (((pb->geqs[e].coef[i] - 1) *
4628 (worst_lower_bound_constant - 1) - 1)
4629 / worst_lower_bound_constant);
4630 /* max_incr += 2; */
4631
4632 if (dump_file && (dump_flags & TDF_DETAILS))
4633 {
4634 fprintf (dump_file, "for equation ");
4635 omega_print_geq (dump_file, pb, &pb->geqs[e]);
4636 fprintf (dump_file,
4637 "\ntry decrements from 0 to %d\n",
4638 max_incr);
4639 omega_print_problem (dump_file, pb);
4640 }
4641
4642 if (max_incr > 50 && !smoothed
4643 && smooth_weird_equations (pb))
4644 {
4645 conservative--;
4646 free (rS);
4647 free (iS);
4648 smoothed = true;
4649 goto solve_geq_start;
4650 }
4651
4652 omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4653 pb->num_vars);
4654 pb->eqs[0].color = omega_black;
4655 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4656 pb->geqs[e].touched = 1;
4657 pb->num_eqs = 1;
4658
4659 for (c = max_incr; c >= 0; c--)
4660 {
4661 if (dump_file && (dump_flags & TDF_DETAILS))
4662 {
4663 fprintf (dump_file,
4664 "trying next decrement of %d\n",
4665 max_incr - c);
4666 omega_print_problem (dump_file, pb);
4667 }
4668
4669 omega_copy_problem (rS, pb);
4670
4671 if (dump_file && (dump_flags & TDF_DETAILS))
4672 omega_print_problem (dump_file, rS);
4673
4674 result = omega_solve_problem (rS, desired_res);
4675
4676 if (result == omega_true)
4677 {
4678 free (rS);
4679 free (iS);
4680 free (lower_bound);
4681 conservative--;
4682 return omega_true;
4683 }
4684
4685 pb->eqs[0].coef[0]--;
4686 }
4687
4688 if (j + 1 < lower_bounds)
4689 {
4690 pb->num_eqs = 0;
4691 omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4692 pb->num_vars);
4693 pb->geqs[e].touched = 1;
4694 pb->geqs[e].color = omega_black;
4695 omega_copy_problem (rS, pb);
4696
4697 if (dump_file && (dump_flags & TDF_DETAILS))
4698 fprintf (dump_file,
4699 "exhausted lower bound, "
4700 "checking if still feasible ");
4701
4702 result = omega_solve_problem (rS, omega_false);
4703
4704 if (result == omega_false)
4705 break;
4706 }
4707 }
4708
4709 if (dump_file && (dump_flags & TDF_DETAILS))
4710 fprintf (dump_file, "fall-off the end\n");
4711
4712 free (rS);
4713 free (iS);
4714 free (lower_bound);
4715 conservative--;
4716 return omega_false;
4717 }
4718
4719 free (rS);
4720 free (iS);
4721 }
4722 return omega_unknown;
4723 } while (eliminate_again);
4724 } while (1);
4725 }
4726
4727 /* Because the omega solver is recursive, this counter limits the
4728 recursion depth. */
4729 static int omega_solve_depth = 0;
4730
4731 /* Return omega_true when the problem PB has a solution following the
4732 DESIRED_RES. */
4733
4734 enum omega_result
4735 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4736 {
4737 enum omega_result result;
4738
4739 gcc_assert (pb->num_vars >= pb->safe_vars);
4740 omega_solve_depth++;
4741
4742 if (desired_res != omega_simplify)
4743 pb->safe_vars = 0;
4744
4745 if (omega_solve_depth > 50)
4746 {
4747 if (dump_file && (dump_flags & TDF_DETAILS))
4748 {
4749 fprintf (dump_file,
4750 "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4751 omega_solve_depth, in_approximate_mode);
4752 omega_print_problem (dump_file, pb);
4753 }
4754 gcc_assert (0);
4755 }
4756
4757 if (omega_solve_eq (pb, desired_res) == omega_false)
4758 {
4759 omega_solve_depth--;
4760 return omega_false;
4761 }
4762
4763 if (in_approximate_mode && !pb->num_geqs)
4764 {
4765 result = omega_true;
4766 pb->num_vars = pb->safe_vars;
4767 omega_problem_reduced (pb);
4768 }
4769 else
4770 result = omega_solve_geq (pb, desired_res);
4771
4772 omega_solve_depth--;
4773
4774 if (!omega_reduce_with_subs)
4775 {
4776 resurrect_subs (pb);
4777 gcc_assert (please_no_equalities_in_simplified_problems
4778 || !result || pb->num_subs == 0);
4779 }
4780
4781 return result;
4782 }
4783
4784 /* Return true if red equations constrain the set of possible solutions.
4785 We assume that there are solutions to the black equations by
4786 themselves, so if there is no solution to the combined problem, we
4787 return true. */
4788
4789 bool
4790 omega_problem_has_red_equations (omega_pb pb)
4791 {
4792 bool result;
4793 int e;
4794 int i;
4795
4796 if (dump_file && (dump_flags & TDF_DETAILS))
4797 {
4798 fprintf (dump_file, "Checking for red equations:\n");
4799 omega_print_problem (dump_file, pb);
4800 }
4801
4802 please_no_equalities_in_simplified_problems++;
4803 may_be_red++;
4804
4805 if (omega_single_result)
4806 return_single_result++;
4807
4808 create_color = true;
4809 result = (omega_simplify_problem (pb) == omega_false);
4810
4811 if (omega_single_result)
4812 return_single_result--;
4813
4814 may_be_red--;
4815 please_no_equalities_in_simplified_problems--;
4816
4817 if (result)
4818 {
4819 if (dump_file && (dump_flags & TDF_DETAILS))
4820 fprintf (dump_file, "Gist is FALSE\n");
4821
4822 pb->num_subs = 0;
4823 pb->num_geqs = 0;
4824 pb->num_eqs = 1;
4825 pb->eqs[0].color = omega_red;
4826
4827 for (i = pb->num_vars; i > 0; i--)
4828 pb->eqs[0].coef[i] = 0;
4829
4830 pb->eqs[0].coef[0] = 1;
4831 return true;
4832 }
4833
4834 free_red_eliminations (pb);
4835 gcc_assert (pb->num_eqs == 0);
4836
4837 for (e = pb->num_geqs - 1; e >= 0; e--)
4838 if (pb->geqs[e].color == omega_red)
4839 result = true;
4840
4841 if (!result)
4842 return false;
4843
4844 for (i = pb->safe_vars; i >= 1; i--)
4845 {
4846 int ub = 0;
4847 int lb = 0;
4848
4849 for (e = pb->num_geqs - 1; e >= 0; e--)
4850 {
4851 if (pb->geqs[e].coef[i])
4852 {
4853 if (pb->geqs[e].coef[i] > 0)
4854 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4855
4856 else
4857 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4858 }
4859 }
4860
4861 if (ub == 2 || lb == 2)
4862 {
4863
4864 if (dump_file && (dump_flags & TDF_DETAILS))
4865 fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4866
4867 if (!omega_reduce_with_subs)
4868 {
4869 resurrect_subs (pb);
4870 gcc_assert (pb->num_subs == 0);
4871 }
4872
4873 return true;
4874 }
4875 }
4876
4877
4878 if (dump_file && (dump_flags & TDF_DETAILS))
4879 fprintf (dump_file,
4880 "*** Doing potentially expensive elimination tests "
4881 "for red equations\n");
4882
4883 please_no_equalities_in_simplified_problems++;
4884 omega_eliminate_red (pb, true);
4885 please_no_equalities_in_simplified_problems--;
4886
4887 result = false;
4888 gcc_assert (pb->num_eqs == 0);
4889
4890 for (e = pb->num_geqs - 1; e >= 0; e--)
4891 if (pb->geqs[e].color == omega_red)
4892 result = true;
4893
4894 if (dump_file && (dump_flags & TDF_DETAILS))
4895 {
4896 if (!result)
4897 fprintf (dump_file,
4898 "******************** Redundant Red Equations eliminated!!\n");
4899 else
4900 fprintf (dump_file,
4901 "******************** Red Equations remain\n");
4902
4903 omega_print_problem (dump_file, pb);
4904 }
4905
4906 if (!omega_reduce_with_subs)
4907 {
4908 normalize_return_type r;
4909
4910 resurrect_subs (pb);
4911 r = normalize_omega_problem (pb);
4912 gcc_assert (r != normalize_false);
4913
4914 coalesce (pb);
4915 cleanout_wildcards (pb);
4916 gcc_assert (pb->num_subs == 0);
4917 }
4918
4919 return result;
4920 }
4921
4922 /* Calls omega_simplify_problem in approximate mode. */
4923
4924 enum omega_result
4925 omega_simplify_approximate (omega_pb pb)
4926 {
4927 enum omega_result result;
4928
4929 if (dump_file && (dump_flags & TDF_DETAILS))
4930 fprintf (dump_file, "(Entering approximate mode\n");
4931
4932 in_approximate_mode = true;
4933 result = omega_simplify_problem (pb);
4934 in_approximate_mode = false;
4935
4936 gcc_assert (pb->num_vars == pb->safe_vars);
4937 if (!omega_reduce_with_subs)
4938 gcc_assert (pb->num_subs == 0);
4939
4940 if (dump_file && (dump_flags & TDF_DETAILS))
4941 fprintf (dump_file, "Leaving approximate mode)\n");
4942
4943 return result;
4944 }
4945
4946
4947 /* Simplifies problem PB by eliminating redundant constraints and
4948 reducing the constraints system to a minimal form. Returns
4949 omega_true when the problem was successfully reduced, omega_unknown
4950 when the solver is unable to determine an answer. */
4951
4952 enum omega_result
4953 omega_simplify_problem (omega_pb pb)
4954 {
4955 int i;
4956
4957 omega_found_reduction = omega_false;
4958
4959 if (!pb->variables_initialized)
4960 omega_initialize_variables (pb);
4961
4962 if (next_key * 3 > MAX_KEYS)
4963 {
4964 int e;
4965
4966 hash_version++;
4967 next_key = OMEGA_MAX_VARS + 1;
4968
4969 for (e = pb->num_geqs - 1; e >= 0; e--)
4970 pb->geqs[e].touched = 1;
4971
4972 for (i = 0; i < HASH_TABLE_SIZE; i++)
4973 hash_master[i].touched = -1;
4974
4975 pb->hash_version = hash_version;
4976 }
4977
4978 else if (pb->hash_version != hash_version)
4979 {
4980 int e;
4981
4982 for (e = pb->num_geqs - 1; e >= 0; e--)
4983 pb->geqs[e].touched = 1;
4984
4985 pb->hash_version = hash_version;
4986 }
4987
4988 if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
4989 omega_free_eliminations (pb, pb->safe_vars);
4990
4991 if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
4992 {
4993 omega_found_reduction = omega_solve_problem (pb, omega_unknown);
4994
4995 if (omega_found_reduction != omega_false
4996 && !return_single_result)
4997 {
4998 pb->num_geqs = 0;
4999 pb->num_eqs = 0;
5000 (*omega_when_reduced) (pb);
5001 }
5002
5003 return omega_found_reduction;
5004 }
5005
5006 omega_solve_problem (pb, omega_simplify);
5007
5008 if (omega_found_reduction != omega_false)
5009 {
5010 for (i = 1; omega_safe_var_p (pb, i); i++)
5011 pb->forwarding_address[pb->var[i]] = i;
5012
5013 for (i = 0; i < pb->num_subs; i++)
5014 pb->forwarding_address[pb->subs[i].key] = -i - 1;
5015 }
5016
5017 if (!omega_reduce_with_subs)
5018 gcc_assert (please_no_equalities_in_simplified_problems
5019 || omega_found_reduction == omega_false
5020 || pb->num_subs == 0);
5021
5022 return omega_found_reduction;
5023 }
5024
5025 /* Make variable VAR unprotected: it then can be eliminated. */
5026
5027 void
5028 omega_unprotect_variable (omega_pb pb, int var)
5029 {
5030 int e, idx;
5031 idx = pb->forwarding_address[var];
5032
5033 if (idx < 0)
5034 {
5035 idx = -1 - idx;
5036 pb->num_subs--;
5037
5038 if (idx < pb->num_subs)
5039 {
5040 omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5041 pb->num_vars);
5042 pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5043 }
5044 }
5045 else
5046 {
5047 int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5048 int e2;
5049
5050 for (e = pb->num_subs - 1; e >= 0; e--)
5051 bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5052
5053 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5054 if (bring_to_life[e2])
5055 {
5056 pb->num_vars++;
5057 pb->safe_vars++;
5058
5059 if (pb->safe_vars < pb->num_vars)
5060 {
5061 for (e = pb->num_geqs - 1; e >= 0; e--)
5062 {
5063 pb->geqs[e].coef[pb->num_vars] =
5064 pb->geqs[e].coef[pb->safe_vars];
5065
5066 pb->geqs[e].coef[pb->safe_vars] = 0;
5067 }
5068
5069 for (e = pb->num_eqs - 1; e >= 0; e--)
5070 {
5071 pb->eqs[e].coef[pb->num_vars] =
5072 pb->eqs[e].coef[pb->safe_vars];
5073
5074 pb->eqs[e].coef[pb->safe_vars] = 0;
5075 }
5076
5077 for (e = pb->num_subs - 1; e >= 0; e--)
5078 {
5079 pb->subs[e].coef[pb->num_vars] =
5080 pb->subs[e].coef[pb->safe_vars];
5081
5082 pb->subs[e].coef[pb->safe_vars] = 0;
5083 }
5084
5085 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5086 pb->forwarding_address[pb->var[pb->num_vars]] =
5087 pb->num_vars;
5088 }
5089 else
5090 {
5091 for (e = pb->num_geqs - 1; e >= 0; e--)
5092 pb->geqs[e].coef[pb->safe_vars] = 0;
5093
5094 for (e = pb->num_eqs - 1; e >= 0; e--)
5095 pb->eqs[e].coef[pb->safe_vars] = 0;
5096
5097 for (e = pb->num_subs - 1; e >= 0; e--)
5098 pb->subs[e].coef[pb->safe_vars] = 0;
5099 }
5100
5101 pb->var[pb->safe_vars] = pb->subs[e2].key;
5102 pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5103
5104 omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5105 pb->num_vars);
5106 pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5107 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5108
5109 if (e2 < pb->num_subs - 1)
5110 omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5111 pb->num_vars);
5112
5113 pb->num_subs--;
5114 }
5115
5116 omega_unprotect_1 (pb, &idx, NULL);
5117 free (bring_to_life);
5118 }
5119
5120 chain_unprotect (pb);
5121 }
5122
5123 /* Unprotects VAR and simplifies PB. */
5124
5125 enum omega_result
5126 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5127 int var, int sign)
5128 {
5129 int n_vars = pb->num_vars;
5130 int e, j;
5131 int k = pb->forwarding_address[var];
5132
5133 if (k < 0)
5134 {
5135 k = -1 - k;
5136
5137 if (sign != 0)
5138 {
5139 e = pb->num_geqs++;
5140 omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5141
5142 for (j = 0; j <= n_vars; j++)
5143 pb->geqs[e].coef[j] *= sign;
5144
5145 pb->geqs[e].coef[0]--;
5146 pb->geqs[e].touched = 1;
5147 pb->geqs[e].color = color;
5148 }
5149 else
5150 {
5151 e = pb->num_eqs++;
5152 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5153 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5154 pb->eqs[e].color = color;
5155 }
5156 }
5157 else if (sign != 0)
5158 {
5159 e = pb->num_geqs++;
5160 omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5161 pb->geqs[e].coef[k] = sign;
5162 pb->geqs[e].coef[0] = -1;
5163 pb->geqs[e].touched = 1;
5164 pb->geqs[e].color = color;
5165 }
5166 else
5167 {
5168 e = pb->num_eqs++;
5169 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5170 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5171 pb->eqs[e].coef[k] = 1;
5172 pb->eqs[e].color = color;
5173 }
5174
5175 omega_unprotect_variable (pb, var);
5176 return omega_simplify_problem (pb);
5177 }
5178
5179 /* Add an equation "VAR = VALUE" with COLOR to PB. */
5180
5181 void
5182 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5183 int var, int value)
5184 {
5185 int e;
5186 int k = pb->forwarding_address[var];
5187
5188 if (k < 0)
5189 {
5190 k = -1 - k;
5191 e = pb->num_eqs++;
5192 gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5193 omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5194 pb->eqs[e].coef[0] -= value;
5195 }
5196 else
5197 {
5198 e = pb->num_eqs++;
5199 omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5200 pb->eqs[e].coef[k] = 1;
5201 pb->eqs[e].coef[0] = -value;
5202 }
5203
5204 pb->eqs[e].color = color;
5205 }
5206
5207 /* Return false when the upper and lower bounds are not coupled.
5208 Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5209 variable I. */
5210
5211 bool
5212 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5213 {
5214 int n_vars = pb->num_vars;
5215 int e, j;
5216 bool is_simple;
5217 bool coupled = false;
5218
5219 *lower_bound = neg_infinity;
5220 *upper_bound = pos_infinity;
5221 i = pb->forwarding_address[i];
5222
5223 if (i < 0)
5224 {
5225 i = -i - 1;
5226
5227 for (j = 1; j <= n_vars; j++)
5228 if (pb->subs[i].coef[j] != 0)
5229 return true;
5230
5231 *upper_bound = *lower_bound = pb->subs[i].coef[0];
5232 return false;
5233 }
5234
5235 for (e = pb->num_subs - 1; e >= 0; e--)
5236 if (pb->subs[e].coef[i] != 0)
5237 coupled = true;
5238
5239 for (e = pb->num_eqs - 1; e >= 0; e--)
5240 if (pb->eqs[e].coef[i] != 0)
5241 {
5242 is_simple = true;
5243
5244 for (j = 1; j <= n_vars; j++)
5245 if (i != j && pb->eqs[e].coef[j] != 0)
5246 {
5247 is_simple = false;
5248 coupled = true;
5249 break;
5250 }
5251
5252 if (!is_simple)
5253 continue;
5254 else
5255 {
5256 *lower_bound = *upper_bound =
5257 -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5258 return false;
5259 }
5260 }
5261
5262 for (e = pb->num_geqs - 1; e >= 0; e--)
5263 if (pb->geqs[e].coef[i] != 0)
5264 {
5265 if (pb->geqs[e].key == i)
5266 *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5267
5268 else if (pb->geqs[e].key == -i)
5269 *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5270
5271 else
5272 coupled = true;
5273 }
5274
5275 return coupled;
5276 }
5277
5278 /* Sets the lower bound L and upper bound U for the values of variable
5279 I, and sets COULD_BE_ZERO to true if variable I might take value
5280 zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
5281 variable I. */
5282
5283 static void
5284 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5285 bool *could_be_zero, int lower_bound, int upper_bound)
5286 {
5287 int e, b1, b2;
5288 eqn eqn;
5289 int sign;
5290 int v;
5291
5292 /* Preconditions. */
5293 gcc_assert (abs (pb->forwarding_address[i]) == 1
5294 && pb->num_vars + pb->num_subs == 2
5295 && pb->num_eqs + pb->num_subs == 1);
5296
5297 /* Define variable I in terms of variable V. */
5298 if (pb->forwarding_address[i] == -1)
5299 {
5300 eqn = &pb->subs[0];
5301 sign = 1;
5302 v = 1;
5303 }
5304 else
5305 {
5306 eqn = &pb->eqs[0];
5307 sign = -eqn->coef[1];
5308 v = 2;
5309 }
5310
5311 for (e = pb->num_geqs - 1; e >= 0; e--)
5312 if (pb->geqs[e].coef[v] != 0)
5313 {
5314 if (pb->geqs[e].coef[v] == 1)
5315 lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5316
5317 else
5318 upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5319 }
5320
5321 if (lower_bound > upper_bound)
5322 {
5323 *l = pos_infinity;
5324 *u = neg_infinity;
5325 *could_be_zero = 0;
5326 return;
5327 }
5328
5329 if (lower_bound == neg_infinity)
5330 {
5331 if (eqn->coef[v] > 0)
5332 b1 = sign * neg_infinity;
5333
5334 else
5335 b1 = -sign * neg_infinity;
5336 }
5337 else
5338 b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5339
5340 if (upper_bound == pos_infinity)
5341 {
5342 if (eqn->coef[v] > 0)
5343 b2 = sign * pos_infinity;
5344
5345 else
5346 b2 = -sign * pos_infinity;
5347 }
5348 else
5349 b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5350
5351 *l = MAX (*l, b1 <= b2 ? b1 : b2);
5352 *u = MIN (*u, b1 <= b2 ? b2 : b1);
5353
5354 *could_be_zero = (*l <= 0 && 0 <= *u
5355 && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5356 }
5357
5358 /* Return false when a lower bound L and an upper bound U for variable
5359 I in problem PB have been initialized. */
5360
5361 bool
5362 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5363 {
5364 *l = neg_infinity;
5365 *u = pos_infinity;
5366
5367 if (!omega_query_variable (pb, i, l, u)
5368 || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5369 return false;
5370
5371 if (abs (pb->forwarding_address[i]) == 1
5372 && pb->num_vars + pb->num_subs == 2
5373 && pb->num_eqs + pb->num_subs == 1)
5374 {
5375 bool could_be_zero;
5376 query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5377 pos_infinity);
5378 return false;
5379 }
5380
5381 return true;
5382 }
5383
5384 /* For problem PB, return an integer that represents the classic data
5385 dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5386 masks that are added to the result. When DIST_KNOWN is true, DIST
5387 is set to the classic data dependence distance. LOWER_BOUND and
5388 UPPER_BOUND are bounds on the value of variable I, for example, it
5389 is possible to narrow the iteration domain with safe approximations
5390 of loop counts, and thus discard some data dependences that cannot
5391 occur. */
5392
5393 int
5394 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5395 int dd_eq, int dd_gt, int lower_bound,
5396 int upper_bound, bool *dist_known, int *dist)
5397 {
5398 int result;
5399 int l, u;
5400 bool could_be_zero;
5401
5402 l = neg_infinity;
5403 u = pos_infinity;
5404
5405 omega_query_variable (pb, i, &l, &u);
5406 query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5407 upper_bound);
5408 result = 0;
5409
5410 if (l < 0)
5411 result |= dd_gt;
5412
5413 if (u > 0)
5414 result |= dd_lt;
5415
5416 if (could_be_zero)
5417 result |= dd_eq;
5418
5419 if (l == u)
5420 {
5421 *dist_known = true;
5422 *dist = l;
5423 }
5424 else
5425 *dist_known = false;
5426
5427 return result;
5428 }
5429
5430 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5431 safe variables. Safe variables are not eliminated during the
5432 Fourier-Motzkin elimination. Safe variables are all those
5433 variables that are placed at the beginning of the array of
5434 variables: P->var[0, ..., NPROT - 1]. */
5435
5436 omega_pb
5437 omega_alloc_problem (int nvars, int nprot)
5438 {
5439 omega_pb pb;
5440
5441 gcc_assert (nvars <= OMEGA_MAX_VARS);
5442 omega_initialize ();
5443
5444 /* Allocate and initialize PB. */
5445 pb = XCNEW (struct omega_pb_d);
5446 pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5447 pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5448 pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5449 pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5450 pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5451
5452 pb->hash_version = hash_version;
5453 pb->num_vars = nvars;
5454 pb->safe_vars = nprot;
5455 pb->variables_initialized = false;
5456 pb->variables_freed = false;
5457 pb->num_eqs = 0;
5458 pb->num_geqs = 0;
5459 pb->num_subs = 0;
5460 return pb;
5461 }
5462
5463 /* Keeps the state of the initialization. */
5464 static bool omega_initialized = false;
5465
5466 /* Initialization of the Omega solver. */
5467
5468 void
5469 omega_initialize (void)
5470 {
5471 int i;
5472
5473 if (omega_initialized)
5474 return;
5475
5476 next_wild_card = 0;
5477 next_key = OMEGA_MAX_VARS + 1;
5478 packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5479 fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5480 fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5481 hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5482
5483 for (i = 0; i < HASH_TABLE_SIZE; i++)
5484 hash_master[i].touched = -1;
5485
5486 sprintf (wild_name[0], "1");
5487 sprintf (wild_name[1], "a");
5488 sprintf (wild_name[2], "b");
5489 sprintf (wild_name[3], "c");
5490 sprintf (wild_name[4], "d");
5491 sprintf (wild_name[5], "e");
5492 sprintf (wild_name[6], "f");
5493 sprintf (wild_name[7], "g");
5494 sprintf (wild_name[8], "h");
5495 sprintf (wild_name[9], "i");
5496 sprintf (wild_name[10], "j");
5497 sprintf (wild_name[11], "k");
5498 sprintf (wild_name[12], "l");
5499 sprintf (wild_name[13], "m");
5500 sprintf (wild_name[14], "n");
5501 sprintf (wild_name[15], "o");
5502 sprintf (wild_name[16], "p");
5503 sprintf (wild_name[17], "q");
5504 sprintf (wild_name[18], "r");
5505 sprintf (wild_name[19], "s");
5506 sprintf (wild_name[20], "t");
5507 sprintf (wild_name[40 - 1], "alpha");
5508 sprintf (wild_name[40 - 2], "beta");
5509 sprintf (wild_name[40 - 3], "gamma");
5510 sprintf (wild_name[40 - 4], "delta");
5511 sprintf (wild_name[40 - 5], "tau");
5512 sprintf (wild_name[40 - 6], "sigma");
5513 sprintf (wild_name[40 - 7], "chi");
5514 sprintf (wild_name[40 - 8], "omega");
5515 sprintf (wild_name[40 - 9], "pi");
5516 sprintf (wild_name[40 - 10], "ni");
5517 sprintf (wild_name[40 - 11], "Alpha");
5518 sprintf (wild_name[40 - 12], "Beta");
5519 sprintf (wild_name[40 - 13], "Gamma");
5520 sprintf (wild_name[40 - 14], "Delta");
5521 sprintf (wild_name[40 - 15], "Tau");
5522 sprintf (wild_name[40 - 16], "Sigma");
5523 sprintf (wild_name[40 - 17], "Chi");
5524 sprintf (wild_name[40 - 18], "Omega");
5525 sprintf (wild_name[40 - 19], "xxx");
5526
5527 omega_initialized = true;
5528 }