OSDN Git Service

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