OSDN Git Service

* gcc.dg/funcorder.c: Remove XFAIL for hppa*64*-*-*.
[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,
9    2010 Free Software Foundation, 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-core.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 DEBUG_FUNCTION 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                       /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
2217                       for (k = pb->num_vars; k >= 1; k--)
2218                         if (alpha3 * pb->geqs[e3].coef[k]
2219                             != (alpha1 * pb->geqs[e1].coef[k]
2220                                 + alpha2 * pb->geqs[e2].coef[k]))
2221                           goto nextE3;
2222
2223                       c = (alpha1 * pb->geqs[e1].coef[0]
2224                            + alpha2 * pb->geqs[e2].coef[0]);
2225
2226                       if (c < alpha3 * (pb->geqs[e3].coef[0]))
2227                         {
2228                           /* We just proved e3 < 0, so no solutions exist.  */
2229                           if (dump_file && (dump_flags & TDF_DETAILS))
2230                             {
2231                               fprintf (dump_file,
2232                                        "found implied over tight inequality\n");
2233                               fprintf (dump_file,
2234                                        "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2235                                        alpha1, alpha2, -alpha3);
2236                               omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2237                               fprintf (dump_file, "\n");
2238                               omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2239                               fprintf (dump_file, "\n=> not ");
2240                               omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2241                               fprintf (dump_file, "\n\n");
2242                             }
2243                           free (is_dead);
2244                           free (peqs);
2245                           free (zeqs);
2246                           free (neqs);
2247                           return omega_false;
2248                         }
2249                       else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
2250                         {
2251                           /* We just proved that e3 <=0, so e3 = 0.  */
2252                           if (dump_file && (dump_flags & TDF_DETAILS))
2253                             {
2254                               fprintf (dump_file,
2255                                        "found implied tight inequality\n");
2256                               fprintf (dump_file,
2257                                        "alpha1, alpha2, alpha3 = %d,%d,%d\n",
2258                                        alpha1, alpha2, -alpha3);
2259                               omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
2260                               fprintf (dump_file, "\n");
2261                               omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2262                               fprintf (dump_file, "\n=> inverse ");
2263                               omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2264                               fprintf (dump_file, "\n\n");
2265                             }
2266
2267                           omega_copy_eqn (&pb->eqs[pb->num_eqs++],
2268                                           &pb->geqs[e3], pb->num_vars);
2269                           gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2270                           adding_equality_constraint (pb, pb->num_eqs - 1);
2271                           is_dead[e3] = true;
2272                         }
2273                     }
2274                 nextE3:;
2275                 }
2276           }
2277
2278   /* Delete the inequalities that were marked as dead.  */
2279   for (e = pb->num_geqs - 1; e >= 0; e--)
2280     if (is_dead[e])
2281       omega_delete_geq (pb, e, pb->num_vars);
2282
2283   if (!expensive)
2284     goto eliminate_redundant_done;
2285
2286   tmp_problem = XNEW (struct omega_pb_d);
2287   conservative++;
2288
2289   for (e = pb->num_geqs - 1; e >= 0; e--)
2290     {
2291       if (dump_file && (dump_flags & TDF_DETAILS))
2292         {
2293           fprintf (dump_file,
2294                    "checking equation %d to see if it is redundant: ", e);
2295           omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2296           fprintf (dump_file, "\n");
2297         }
2298
2299       omega_copy_problem (tmp_problem, pb);
2300       omega_negate_geq (tmp_problem, e);
2301       tmp_problem->safe_vars = 0;
2302       tmp_problem->variables_freed = false;
2303
2304       if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2305         omega_delete_geq (pb, e, pb->num_vars);
2306     }
2307
2308   free (tmp_problem);
2309   conservative--;
2310
2311   if (!omega_reduce_with_subs)
2312     {
2313       resurrect_subs (pb);
2314       gcc_assert (please_no_equalities_in_simplified_problems
2315                   || pb->num_subs == 0);
2316     }
2317
2318  eliminate_redundant_done:
2319   free (is_dead);
2320   free (peqs);
2321   free (zeqs);
2322   free (neqs);
2323   return omega_true;
2324 }
2325
2326 /* For each inequality that has coefficients bigger than 20, try to
2327    create a new constraint that cannot be derived from the original
2328    constraint and that has smaller coefficients.  Add the new
2329    constraint at the end of geqs.  Return the number of inequalities
2330    that have been added to PB.  */
2331
2332 static int
2333 smooth_weird_equations (omega_pb pb)
2334 {
2335   int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
2336   int c;
2337   int v;
2338   int result = 0;
2339
2340   for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
2341     if (pb->geqs[e1].color == omega_black)
2342       {
2343         int g = 999999;
2344
2345         for (v = pb->num_vars; v >= 1; v--)
2346           if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
2347             g = abs (pb->geqs[e1].coef[v]);
2348
2349         /* Magic number.  */
2350         if (g > 20)
2351           {
2352             e3 = pb->num_geqs;
2353
2354             for (v = pb->num_vars; v >= 1; v--)
2355               pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
2356                                               g);
2357
2358             pb->geqs[e3].color = omega_black;
2359             pb->geqs[e3].touched = 1;
2360             /* Magic number.  */
2361             pb->geqs[e3].coef[0] = 9997;
2362
2363             if (dump_file && (dump_flags & TDF_DETAILS))
2364               {
2365                 fprintf (dump_file, "Checking to see if we can derive: ");
2366                 omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2367                 fprintf (dump_file, "\n from: ");
2368                 omega_print_geq (dump_file, pb, &pb->geqs[e1]);
2369                 fprintf (dump_file, "\n");
2370               }
2371
2372             for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
2373               if (e1 != e2 && pb->geqs[e2].color == omega_black)
2374                 {
2375                   for (p = pb->num_vars; p > 1; p--)
2376                     {
2377                       for (q = p - 1; q > 0; q--)
2378                         {
2379                           alpha =
2380                             (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
2381                              pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
2382                           if (alpha != 0)
2383                             goto foundPQ;
2384                         }
2385                     }
2386                   continue;
2387
2388                 foundPQ:
2389
2390                   alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
2391                             - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
2392                   alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
2393                              - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
2394                   alpha3 = alpha;
2395
2396                   if (alpha1 * alpha2 <= 0)
2397                     continue;
2398
2399                   if (alpha1 < 0)
2400                     {
2401                       alpha1 = -alpha1;
2402                       alpha2 = -alpha2;
2403                       alpha3 = -alpha3;
2404                     }
2405
2406                   if (alpha3 > 0)
2407                     {
2408                       /* Try to prove e3 is redundant: verify
2409                          alpha1*v1 + alpha2*v2 = alpha3*v3.  */
2410                       for (k = pb->num_vars; k >= 1; k--)
2411                         if (alpha3 * pb->geqs[e3].coef[k]
2412                             != (alpha1 * pb->geqs[e1].coef[k]
2413                                 + alpha2 * pb->geqs[e2].coef[k]))
2414                           goto nextE2;
2415
2416                       c = alpha1 * pb->geqs[e1].coef[0]
2417                         + alpha2 * pb->geqs[e2].coef[0];
2418
2419                       if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
2420                         pb->geqs[e3].coef[0] = int_div (c, alpha3);
2421                     }
2422                 nextE2:;
2423                 }
2424
2425             if (pb->geqs[e3].coef[0] < 9997)
2426               {
2427                 result++;
2428                 pb->num_geqs++;
2429
2430                 if (dump_file && (dump_flags & TDF_DETAILS))
2431                   {
2432                     fprintf (dump_file,
2433                              "Smoothing weird equations; adding:\n");
2434                     omega_print_geq (dump_file, pb, &pb->geqs[e3]);
2435                     fprintf (dump_file, "\nto:\n");
2436                     omega_print_problem (dump_file, pb);
2437                     fprintf (dump_file, "\n\n");
2438                   }
2439               }
2440           }
2441       }
2442   return result;
2443 }
2444
2445 /* Replace tuples of inequalities, that define upper and lower half
2446    spaces, with an equation.  */
2447
2448 static void
2449 coalesce (omega_pb pb)
2450 {
2451   int e, e2;
2452   int colors = 0;
2453   bool *is_dead;
2454   int found_something = 0;
2455
2456   for (e = 0; e < pb->num_geqs; e++)
2457     if (pb->geqs[e].color == omega_red)
2458       colors++;
2459
2460   if (colors < 2)
2461     return;
2462
2463   is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2464
2465   for (e = 0; e < pb->num_geqs; e++)
2466     is_dead[e] = false;
2467
2468   for (e = 0; e < pb->num_geqs; e++)
2469     if (pb->geqs[e].color == omega_red
2470         && !pb->geqs[e].touched)
2471       for (e2 = e + 1; e2 < pb->num_geqs; e2++)
2472         if (!pb->geqs[e2].touched
2473             && pb->geqs[e].key == -pb->geqs[e2].key
2474             && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
2475             && pb->geqs[e2].color == omega_red)
2476           {
2477             omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
2478                             pb->num_vars);
2479             gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
2480             found_something++;
2481             is_dead[e] = true;
2482             is_dead[e2] = true;
2483           }
2484
2485   for (e = pb->num_geqs - 1; e >= 0; e--)
2486     if (is_dead[e])
2487       omega_delete_geq (pb, e, pb->num_vars);
2488
2489   if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
2490     {
2491       fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
2492                found_something);
2493       omega_print_problem (dump_file, pb);
2494     }
2495
2496   free (is_dead);
2497 }
2498
2499 /* Eliminate red inequalities from PB.  When ELIMINATE_ALL is
2500    true, continue to eliminate all the red inequalities.  */
2501
2502 void
2503 omega_eliminate_red (omega_pb pb, bool eliminate_all)
2504 {
2505   int e, e2, e3, i, j, k, a, alpha1, alpha2;
2506   int c = 0;
2507   bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
2508   int dead_count = 0;
2509   int red_found;
2510   omega_pb tmp_problem;
2511
2512   if (dump_file && (dump_flags & TDF_DETAILS))
2513     {
2514       fprintf (dump_file, "in eliminate RED:\n");
2515       omega_print_problem (dump_file, pb);
2516     }
2517
2518   if (pb->num_eqs > 0)
2519     omega_simplify_problem (pb);
2520
2521   for (e = pb->num_geqs - 1; e >= 0; e--)
2522     is_dead[e] = false;
2523
2524   for (e = pb->num_geqs - 1; e >= 0; e--)
2525     if (pb->geqs[e].color == omega_black && !is_dead[e])
2526       for (e2 = e - 1; e2 >= 0; e2--)
2527         if (pb->geqs[e2].color == omega_black
2528             && !is_dead[e2])
2529           {
2530             a = 0;
2531
2532             for (i = pb->num_vars; i > 1; i--)
2533               for (j = i - 1; j > 0; j--)
2534                 if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
2535                           - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
2536                   goto found_pair;
2537
2538             continue;
2539
2540           found_pair:
2541             if (dump_file && (dump_flags & TDF_DETAILS))
2542               {
2543                 fprintf (dump_file,
2544                          "found two equations to combine, i = %s, ",
2545                          omega_variable_to_str (pb, i));
2546                 fprintf (dump_file, "j = %s, alpha = %d\n",
2547                          omega_variable_to_str (pb, j), a);
2548                 omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2549                 fprintf (dump_file, "\n");
2550                 omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2551                 fprintf (dump_file, "\n");
2552               }
2553
2554             for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
2555               if (pb->geqs[e3].color == omega_red)
2556                 {
2557                   alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
2558                             - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
2559                   alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
2560                              - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
2561
2562                   if ((a > 0 && alpha1 > 0 && alpha2 > 0)
2563                       || (a < 0 && alpha1 < 0 && alpha2 < 0))
2564                     {
2565                       if (dump_file && (dump_flags & TDF_DETAILS))
2566                         {
2567                           fprintf (dump_file,
2568                                    "alpha1 = %d, alpha2 = %d;"
2569                                    "comparing against: ",
2570                                    alpha1, alpha2);
2571                           omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2572                           fprintf (dump_file, "\n");
2573                         }
2574
2575                       for (k = pb->num_vars; k >= 0; k--)
2576                         {
2577                           c = (alpha1 * pb->geqs[e].coef[k]
2578                                + alpha2 * pb->geqs[e2].coef[k]);
2579
2580                           if (c != a * pb->geqs[e3].coef[k])
2581                             break;
2582
2583                           if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
2584                             fprintf (dump_file, " %s: %d, %d\n",
2585                                      omega_variable_to_str (pb, k), c,
2586                                      a * pb->geqs[e3].coef[k]);
2587                         }
2588
2589                       if (k < 0
2590                           || (k == 0 &&
2591                               ((a > 0 && c < a * pb->geqs[e3].coef[k])
2592                                || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
2593                         {
2594                           if (dump_file && (dump_flags & TDF_DETAILS))
2595                             {
2596                               dead_count++;
2597                               fprintf (dump_file,
2598                                        "red equation#%d is dead "
2599                                        "(%d dead so far, %d remain)\n",
2600                                        e3, dead_count,
2601                                        pb->num_geqs - dead_count);
2602                               omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2603                               fprintf (dump_file, "\n");
2604                               omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
2605                               fprintf (dump_file, "\n");
2606                               omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
2607                               fprintf (dump_file, "\n");
2608                             }
2609                           is_dead[e3] = true;
2610                         }
2611                     }
2612                 }
2613           }
2614
2615   for (e = pb->num_geqs - 1; e >= 0; e--)
2616     if (is_dead[e])
2617       omega_delete_geq (pb, e, pb->num_vars);
2618
2619   free (is_dead);
2620
2621   if (dump_file && (dump_flags & TDF_DETAILS))
2622     {
2623       fprintf (dump_file, "in eliminate RED, easy tests done:\n");
2624       omega_print_problem (dump_file, pb);
2625     }
2626
2627   for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
2628     if (pb->geqs[e].color == omega_red)
2629       red_found = 1;
2630
2631   if (!red_found)
2632     {
2633       if (dump_file && (dump_flags & TDF_DETAILS))
2634         fprintf (dump_file, "fast checks worked\n");
2635
2636       if (!omega_reduce_with_subs)
2637         gcc_assert (please_no_equalities_in_simplified_problems
2638                     || pb->num_subs == 0);
2639
2640       return;
2641     }
2642
2643   if (!omega_verify_simplification
2644       && verify_omega_pb (pb) == omega_false)
2645     return;
2646
2647   conservative++;
2648   tmp_problem = XNEW (struct omega_pb_d);
2649
2650   for (e = pb->num_geqs - 1; e >= 0; e--)
2651     if (pb->geqs[e].color == omega_red)
2652       {
2653         if (dump_file && (dump_flags & TDF_DETAILS))
2654           {
2655             fprintf (dump_file,
2656                      "checking equation %d to see if it is redundant: ", e);
2657             omega_print_geq (dump_file, pb, &(pb->geqs[e]));
2658             fprintf (dump_file, "\n");
2659           }
2660
2661         omega_copy_problem (tmp_problem, pb);
2662         omega_negate_geq (tmp_problem, e);
2663         tmp_problem->safe_vars = 0;
2664         tmp_problem->variables_freed = false;
2665         tmp_problem->num_subs = 0;
2666
2667         if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
2668           {
2669             if (dump_file && (dump_flags & TDF_DETAILS))
2670               fprintf (dump_file, "it is redundant\n");
2671             omega_delete_geq (pb, e, pb->num_vars);
2672           }
2673         else
2674           {
2675             if (dump_file && (dump_flags & TDF_DETAILS))
2676               fprintf (dump_file, "it is not redundant\n");
2677
2678             if (!eliminate_all)
2679               {
2680                 if (dump_file && (dump_flags & TDF_DETAILS))
2681                   fprintf (dump_file, "no need to check other red equations\n");
2682                 break;
2683               }
2684           }
2685       }
2686
2687   conservative--;
2688   free (tmp_problem);
2689   /* omega_simplify_problem (pb); */
2690
2691   if (!omega_reduce_with_subs)
2692     gcc_assert (please_no_equalities_in_simplified_problems
2693                 || pb->num_subs == 0);
2694 }
2695
2696 /* Transform some wildcard variables to non-safe variables.  */
2697
2698 static void
2699 chain_unprotect (omega_pb pb)
2700 {
2701   int i, e;
2702   bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
2703
2704   for (i = 1; omega_safe_var_p (pb, i); i++)
2705     {
2706       unprotect[i] = omega_wildcard_p (pb, i);
2707
2708       for (e = pb->num_subs - 1; e >= 0; e--)
2709         if (pb->subs[e].coef[i])
2710           unprotect[i] = false;
2711     }
2712
2713   if (dump_file && (dump_flags & TDF_DETAILS))
2714     {
2715       fprintf (dump_file, "Doing chain reaction unprotection\n");
2716       omega_print_problem (dump_file, pb);
2717
2718       for (i = 1; omega_safe_var_p (pb, i); i++)
2719         if (unprotect[i])
2720           fprintf (dump_file, "unprotecting %s\n",
2721                    omega_variable_to_str (pb, i));
2722     }
2723
2724   for (i = 1; omega_safe_var_p (pb, i); i++)
2725     if (unprotect[i])
2726       omega_unprotect_1 (pb, &i, unprotect);
2727
2728   if (dump_file && (dump_flags & TDF_DETAILS))
2729     {
2730       fprintf (dump_file, "After chain reactions\n");
2731       omega_print_problem (dump_file, pb);
2732     }
2733
2734   free (unprotect);
2735 }
2736
2737 /* Reduce problem PB.  */
2738
2739 static void
2740 omega_problem_reduced (omega_pb pb)
2741 {
2742   if (omega_verify_simplification
2743       && !in_approximate_mode
2744       && verify_omega_pb (pb) == omega_false)
2745     return;
2746
2747   if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
2748       && !omega_eliminate_redundant (pb, true))
2749     return;
2750
2751   omega_found_reduction = omega_true;
2752
2753   if (!please_no_equalities_in_simplified_problems)
2754     coalesce (pb);
2755
2756   if (omega_reduce_with_subs
2757       || please_no_equalities_in_simplified_problems)
2758     chain_unprotect (pb);
2759   else
2760     resurrect_subs (pb);
2761
2762   if (!return_single_result)
2763     {
2764       int i;
2765
2766       for (i = 1; omega_safe_var_p (pb, i); i++)
2767         pb->forwarding_address[pb->var[i]] = i;
2768
2769       for (i = 0; i < pb->num_subs; i++)
2770         pb->forwarding_address[pb->subs[i].key] = -i - 1;
2771
2772       (*omega_when_reduced) (pb);
2773     }
2774
2775   if (dump_file && (dump_flags & TDF_DETAILS))
2776     {
2777       fprintf (dump_file, "-------------------------------------------\n");
2778       fprintf (dump_file, "problem reduced:\n");
2779       omega_print_problem (dump_file, pb);
2780       fprintf (dump_file, "-------------------------------------------\n");
2781     }
2782 }
2783
2784 /* Eliminates all the free variables for problem PB, that is all the
2785    variables from FV to PB->NUM_VARS.  */
2786
2787 static void
2788 omega_free_eliminations (omega_pb pb, int fv)
2789 {
2790   bool try_again = true;
2791   int i, e, e2;
2792   int n_vars = pb->num_vars;
2793
2794   while (try_again)
2795     {
2796       try_again = false;
2797
2798       for (i = n_vars; i > fv; i--)
2799         {
2800           for (e = pb->num_geqs - 1; e >= 0; e--)
2801             if (pb->geqs[e].coef[i])
2802               break;
2803
2804           if (e < 0)
2805             e2 = e;
2806           else if (pb->geqs[e].coef[i] > 0)
2807             {
2808               for (e2 = e - 1; e2 >= 0; e2--)
2809                 if (pb->geqs[e2].coef[i] < 0)
2810                   break;
2811             }
2812           else
2813             {
2814               for (e2 = e - 1; e2 >= 0; e2--)
2815                 if (pb->geqs[e2].coef[i] > 0)
2816                   break;
2817             }
2818
2819           if (e2 < 0)
2820             {
2821               int e3;
2822               for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2823                 if (pb->subs[e3].coef[i])
2824                   break;
2825
2826               if (e3 >= 0)
2827                 continue;
2828
2829               for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2830                 if (pb->eqs[e3].coef[i])
2831                   break;
2832
2833               if (e3 >= 0)
2834                 continue;
2835
2836               if (dump_file && (dump_flags & TDF_DETAILS))
2837                 fprintf (dump_file, "a free elimination of %s\n",
2838                          omega_variable_to_str (pb, i));
2839
2840               if (e >= 0)
2841                 {
2842                   omega_delete_geq (pb, e, n_vars);
2843
2844                   for (e--; e >= 0; e--)
2845                     if (pb->geqs[e].coef[i])
2846                       omega_delete_geq (pb, e, n_vars);
2847
2848                   try_again = (i < n_vars);
2849                 }
2850
2851               omega_delete_variable (pb, i);
2852               n_vars = pb->num_vars;
2853             }
2854         }
2855     }
2856
2857   if (dump_file && (dump_flags & TDF_DETAILS))
2858     {
2859       fprintf (dump_file, "\nafter free eliminations:\n");
2860       omega_print_problem (dump_file, pb);
2861       fprintf (dump_file, "\n");
2862     }
2863 }
2864
2865 /* Do free red eliminations.  */
2866
2867 static void
2868 free_red_eliminations (omega_pb pb)
2869 {
2870   bool try_again = true;
2871   int i, e, e2;
2872   int n_vars = pb->num_vars;
2873   bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2874   bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
2875   bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
2876
2877   for (i = n_vars; i > 0; i--)
2878     {
2879       is_red_var[i] = false;
2880       is_dead_var[i] = false;
2881     }
2882
2883   for (e = pb->num_geqs - 1; e >= 0; e--)
2884     {
2885       is_dead_geq[e] = false;
2886
2887       if (pb->geqs[e].color == omega_red)
2888         for (i = n_vars; i > 0; i--)
2889           if (pb->geqs[e].coef[i] != 0)
2890             is_red_var[i] = true;
2891     }
2892
2893   while (try_again)
2894     {
2895       try_again = false;
2896       for (i = n_vars; i > 0; i--)
2897         if (!is_red_var[i] && !is_dead_var[i])
2898           {
2899             for (e = pb->num_geqs - 1; e >= 0; e--)
2900               if (!is_dead_geq[e] && pb->geqs[e].coef[i])
2901                 break;
2902
2903             if (e < 0)
2904               e2 = e;
2905             else if (pb->geqs[e].coef[i] > 0)
2906               {
2907                 for (e2 = e - 1; e2 >= 0; e2--)
2908                   if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
2909                     break;
2910               }
2911             else
2912               {
2913                 for (e2 = e - 1; e2 >= 0; e2--)
2914                   if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
2915                     break;
2916               }
2917
2918             if (e2 < 0)
2919               {
2920                 int e3;
2921                 for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
2922                   if (pb->subs[e3].coef[i])
2923                     break;
2924
2925                 if (e3 >= 0)
2926                   continue;
2927
2928                 for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
2929                   if (pb->eqs[e3].coef[i])
2930                     break;
2931
2932                 if (e3 >= 0)
2933                   continue;
2934
2935                 if (dump_file && (dump_flags & TDF_DETAILS))
2936                   fprintf (dump_file, "a free red elimination of %s\n",
2937                            omega_variable_to_str (pb, i));
2938
2939                 for (; e >= 0; e--)
2940                   if (pb->geqs[e].coef[i])
2941                     is_dead_geq[e] = true;
2942
2943                 try_again = true;
2944                 is_dead_var[i] = true;
2945               }
2946           }
2947     }
2948
2949   for (e = pb->num_geqs - 1; e >= 0; e--)
2950     if (is_dead_geq[e])
2951       omega_delete_geq (pb, e, n_vars);
2952
2953   for (i = n_vars; i > 0; i--)
2954     if (is_dead_var[i])
2955       omega_delete_variable (pb, i);
2956
2957   if (dump_file && (dump_flags & TDF_DETAILS))
2958     {
2959       fprintf (dump_file, "\nafter free red eliminations:\n");
2960       omega_print_problem (dump_file, pb);
2961       fprintf (dump_file, "\n");
2962     }
2963
2964   free (is_red_var);
2965   free (is_dead_var);
2966   free (is_dead_geq);
2967 }
2968
2969 /* For equation EQ of the form "0 = EQN", insert in PB two
2970    inequalities "0 <= EQN" and "0 <= -EQN".  */
2971
2972 void
2973 omega_convert_eq_to_geqs (omega_pb pb, int eq)
2974 {
2975   int i;
2976
2977   if (dump_file && (dump_flags & TDF_DETAILS))
2978     fprintf (dump_file, "Converting Eq to Geqs\n");
2979
2980   /* Insert "0 <= EQN".  */
2981   omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2982   pb->geqs[pb->num_geqs].touched = 1;
2983   pb->num_geqs++;
2984
2985   /* Insert "0 <= -EQN".  */
2986   omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
2987   pb->geqs[pb->num_geqs].touched = 1;
2988
2989   for (i = 0; i <= pb->num_vars; i++)
2990     pb->geqs[pb->num_geqs].coef[i] *= -1;
2991
2992   pb->num_geqs++;
2993
2994   if (dump_file && (dump_flags & TDF_DETAILS))
2995     omega_print_problem (dump_file, pb);
2996 }
2997
2998 /* Eliminates variable I from PB.  */
2999
3000 static void
3001 omega_do_elimination (omega_pb pb, int e, int i)
3002 {
3003   eqn sub = omega_alloc_eqns (0, 1);
3004   int c;
3005   int n_vars = pb->num_vars;
3006
3007   if (dump_file && (dump_flags & TDF_DETAILS))
3008     fprintf (dump_file, "eliminating variable %s\n",
3009              omega_variable_to_str (pb, i));
3010
3011   omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
3012   c = sub->coef[i];
3013   sub->coef[i] = 0;
3014   if (c == 1 || c == -1)
3015     {
3016       if (pb->eqs[e].color == omega_red)
3017         {
3018           bool fB;
3019           omega_substitute_red (pb, sub, i, c, &fB);
3020           if (fB)
3021             omega_convert_eq_to_geqs (pb, e);
3022           else
3023             omega_delete_variable (pb, i);
3024         }
3025       else
3026         {
3027           omega_substitute (pb, sub, i, c);
3028           omega_delete_variable (pb, i);
3029         }
3030     }
3031   else
3032     {
3033       int a = abs (c);
3034       int e2 = e;
3035
3036       if (dump_file && (dump_flags & TDF_DETAILS))
3037         fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
3038
3039       for (e = pb->num_eqs - 1; e >= 0; e--)
3040         if (pb->eqs[e].coef[i])
3041           {
3042             eqn eqn = &(pb->eqs[e]);
3043             int j, k;
3044             for (j = n_vars; j >= 0; j--)
3045               eqn->coef[j] *= a;
3046             k = eqn->coef[i];
3047             eqn->coef[i] = 0;
3048             if (sub->color == omega_red)
3049               eqn->color = omega_red;
3050             for (j = n_vars; j >= 0; j--)
3051               eqn->coef[j] -= sub->coef[j] * k / c;
3052           }
3053
3054       for (e = pb->num_geqs - 1; e >= 0; e--)
3055         if (pb->geqs[e].coef[i])
3056           {
3057             eqn eqn = &(pb->geqs[e]);
3058             int j, k;
3059
3060             if (sub->color == omega_red)
3061               eqn->color = omega_red;
3062
3063             for (j = n_vars; j >= 0; j--)
3064               eqn->coef[j] *= a;
3065
3066             eqn->touched = 1;
3067             k = eqn->coef[i];
3068             eqn->coef[i] = 0;
3069
3070             for (j = n_vars; j >= 0; j--)
3071               eqn->coef[j] -= sub->coef[j] * k / c;
3072
3073           }
3074
3075       for (e = pb->num_subs - 1; e >= 0; e--)
3076         if (pb->subs[e].coef[i])
3077           {
3078             eqn eqn = &(pb->subs[e]);
3079             int j, k;
3080             gcc_assert (0);
3081             gcc_assert (sub->color == omega_black);
3082             for (j = n_vars; j >= 0; j--)
3083               eqn->coef[j] *= a;
3084             k = eqn->coef[i];
3085             eqn->coef[i] = 0;
3086             for (j = n_vars; j >= 0; j--)
3087               eqn->coef[j] -= sub->coef[j] * k / c;
3088           }
3089
3090       if (in_approximate_mode)
3091         omega_delete_variable (pb, i);
3092       else
3093         omega_convert_eq_to_geqs (pb, e2);
3094     }
3095
3096   omega_free_eqns (sub, 1);
3097 }
3098
3099 /* Helper function for printing "sorry, no solution".  */
3100
3101 static inline enum omega_result
3102 omega_problem_has_no_solution (void)
3103 {
3104   if (dump_file && (dump_flags & TDF_DETAILS))
3105     fprintf (dump_file, "\nequations have no solution \n");
3106
3107   return omega_false;
3108 }
3109
3110 /* Helper function: solve equations in PB one at a time, following the
3111    DESIRED_RES result.  */
3112
3113 static enum omega_result
3114 omega_solve_eq (omega_pb pb, enum omega_result desired_res)
3115 {
3116   int i, j, e;
3117   int g, g2;
3118   g = 0;
3119
3120
3121   if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
3122     {
3123       fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
3124                desired_res, may_be_red);
3125       omega_print_problem (dump_file, pb);
3126       fprintf (dump_file, "\n");
3127     }
3128
3129   if (may_be_red)
3130     {
3131       i = 0;
3132       j = pb->num_eqs - 1;
3133
3134       while (1)
3135         {
3136           eqn eq;
3137
3138           while (i <= j && pb->eqs[i].color == omega_red)
3139             i++;
3140
3141           while (i <= j && pb->eqs[j].color == omega_black)
3142             j--;
3143
3144           if (i >= j)
3145             break;
3146
3147           eq = omega_alloc_eqns (0, 1);
3148           omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
3149           omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
3150           omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
3151           omega_free_eqns (eq, 1);
3152           i++;
3153           j--;
3154         }
3155     }
3156
3157   /* Eliminate all EQ equations */
3158   for (e = pb->num_eqs - 1; e >= 0; e--)
3159     {
3160       eqn eqn = &(pb->eqs[e]);
3161       int sv;
3162
3163       if (dump_file && (dump_flags & TDF_DETAILS))
3164         fprintf (dump_file, "----\n");
3165
3166       for (i = pb->num_vars; i > 0; i--)
3167         if (eqn->coef[i])
3168           break;
3169
3170       g = eqn->coef[i];
3171
3172       for (j = i - 1; j > 0; j--)
3173         if (eqn->coef[j])
3174           break;
3175
3176       /* i is the position of last nonzero coefficient,
3177          g is the coefficient of i,
3178          j is the position of next nonzero coefficient.  */
3179
3180       if (j == 0)
3181         {
3182           if (eqn->coef[0] % g != 0)
3183             return omega_problem_has_no_solution ();
3184
3185           eqn->coef[0] = eqn->coef[0] / g;
3186           eqn->coef[i] = 1;
3187           pb->num_eqs--;
3188           omega_do_elimination (pb, e, i);
3189           continue;
3190         }
3191
3192       else if (j == -1)
3193         {
3194           if (eqn->coef[0] != 0)
3195             return omega_problem_has_no_solution ();
3196
3197           pb->num_eqs--;
3198           continue;
3199         }
3200
3201       if (g < 0)
3202         g = -g;
3203
3204       if (g == 1)
3205         {
3206           pb->num_eqs--;
3207           omega_do_elimination (pb, e, i);
3208         }
3209
3210       else
3211         {
3212           int k = j;
3213           bool promotion_possible =
3214             (omega_safe_var_p (pb, j)
3215              && pb->safe_vars + 1 == i
3216              && !omega_eqn_is_red (eqn, desired_res)
3217              && !in_approximate_mode);
3218
3219           if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
3220             fprintf (dump_file, " Promotion possible\n");
3221
3222         normalizeEQ:
3223           if (!omega_safe_var_p (pb, j))
3224             {
3225               for (; g != 1 && !omega_safe_var_p (pb, j); j--)
3226                 g = gcd (abs (eqn->coef[j]), g);
3227               g2 = g;
3228             }
3229           else if (!omega_safe_var_p (pb, i))
3230             g2 = g;
3231           else
3232             g2 = 0;
3233
3234           for (; g != 1 && j > 0; j--)
3235             g = gcd (abs (eqn->coef[j]), g);
3236
3237           if (g > 1)
3238             {
3239               if (eqn->coef[0] % g != 0)
3240                 return omega_problem_has_no_solution ();
3241
3242               for (j = 0; j <= pb->num_vars; j++)
3243                 eqn->coef[j] /= g;
3244
3245               g2 = g2 / g;
3246             }
3247
3248           if (g2 > 1)
3249             {
3250               int e2;
3251
3252               for (e2 = e - 1; e2 >= 0; e2--)
3253                 if (pb->eqs[e2].coef[i])
3254                   break;
3255
3256               if (e2 == -1)
3257                 for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
3258                   if (pb->geqs[e2].coef[i])
3259                     break;
3260
3261               if (e2 == -1)
3262                 for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
3263                   if (pb->subs[e2].coef[i])
3264                     break;
3265
3266               if (e2 == -1)
3267                 {
3268                   bool change = false;
3269
3270                   if (dump_file && (dump_flags & TDF_DETAILS))
3271                     {
3272                       fprintf (dump_file, "Ha! We own it! \n");
3273                       omega_print_eq (dump_file, pb, eqn);
3274                       fprintf (dump_file, " \n");
3275                     }
3276
3277                   g = eqn->coef[i];
3278                   g = abs (g);
3279
3280                   for (j = i - 1; j >= 0; j--)
3281                     {
3282                       int t = int_mod (eqn->coef[j], g);
3283
3284                       if (2 * t >= g)
3285                         t -= g;
3286
3287                       if (t != eqn->coef[j])
3288                         {
3289                           eqn->coef[j] = t;
3290                           change = true;
3291                         }
3292                     }
3293
3294                   if (!change)
3295                     {
3296                       if (dump_file && (dump_flags & TDF_DETAILS))
3297                         fprintf (dump_file, "So what?\n");
3298                     }
3299
3300                   else
3301                     {
3302                       omega_name_wild_card (pb, i);
3303
3304                       if (dump_file && (dump_flags & TDF_DETAILS))
3305                         {
3306                           omega_print_eq (dump_file, pb, eqn);
3307                           fprintf (dump_file, " \n");
3308                         }
3309
3310                       e++;
3311                       continue;
3312                     }
3313                 }
3314             }
3315
3316           if (promotion_possible)
3317             {
3318               if (dump_file && (dump_flags & TDF_DETAILS))
3319                 {
3320                   fprintf (dump_file, "promoting %s to safety\n",
3321                            omega_variable_to_str (pb, i));
3322                   omega_print_vars (dump_file, pb);
3323                 }
3324
3325               pb->safe_vars++;
3326
3327               if (!omega_wildcard_p (pb, i))
3328                 omega_name_wild_card (pb, i);
3329
3330               promotion_possible = false;
3331               j = k;
3332               goto normalizeEQ;
3333             }
3334
3335           if (g2 > 1 && !in_approximate_mode)
3336             {
3337               if (pb->eqs[e].color == omega_red)
3338                 {
3339                   if (dump_file && (dump_flags & TDF_DETAILS))
3340                     fprintf (dump_file, "handling red equality\n");
3341
3342                   pb->num_eqs--;
3343                   omega_do_elimination (pb, e, i);
3344                   continue;
3345                 }
3346
3347               if (dump_file && (dump_flags & TDF_DETAILS))
3348                 {
3349                   fprintf (dump_file,
3350                            "adding equation to handle safe variable \n");
3351                   omega_print_eq (dump_file, pb, eqn);
3352                   fprintf (dump_file, "\n----\n");
3353                   omega_print_problem (dump_file, pb);
3354                   fprintf (dump_file, "\n----\n");
3355                   fprintf (dump_file, "\n----\n");
3356                 }
3357
3358               i = omega_add_new_wild_card (pb);
3359               pb->num_eqs++;
3360               gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
3361               omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
3362               omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
3363
3364               for (j = pb->num_vars; j >= 0; j--)
3365                 {
3366                   pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
3367
3368                   if (2 * pb->eqs[e + 1].coef[j] >= g2)
3369                     pb->eqs[e + 1].coef[j] -= g2;
3370                 }
3371
3372               pb->eqs[e + 1].coef[i] = g2;
3373               e += 2;
3374
3375               if (dump_file && (dump_flags & TDF_DETAILS))
3376                 omega_print_problem (dump_file, pb);
3377
3378               continue;
3379             }
3380
3381           sv = pb->safe_vars;
3382           if (g2 == 0)
3383             sv = 0;
3384
3385           /* Find variable to eliminate.  */
3386           if (g2 > 1)
3387             {
3388               gcc_assert (in_approximate_mode);
3389
3390               if (dump_file && (dump_flags & TDF_DETAILS))
3391                 {
3392                   fprintf (dump_file, "non-exact elimination: ");
3393                   omega_print_eq (dump_file, pb, eqn);
3394                   fprintf (dump_file, "\n");
3395                   omega_print_problem (dump_file, pb);
3396                 }
3397
3398               for (i = pb->num_vars; i > sv; i--)
3399                 if (pb->eqs[e].coef[i] != 0)
3400                   break;
3401             }
3402           else
3403             for (i = pb->num_vars; i > sv; i--)
3404               if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
3405                 break;
3406
3407           if (i > sv)
3408             {
3409               pb->num_eqs--;
3410               omega_do_elimination (pb, e, i);
3411
3412               if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
3413                 {
3414                   fprintf (dump_file, "result of non-exact elimination:\n");
3415                   omega_print_problem (dump_file, pb);
3416                 }
3417             }
3418           else
3419             {
3420               int factor = (INT_MAX);
3421               j = 0;
3422
3423               if (dump_file && (dump_flags & TDF_DETAILS))
3424                 fprintf (dump_file, "doing moding\n");
3425
3426               for (i = pb->num_vars; i != sv; i--)
3427                 if ((pb->eqs[e].coef[i] & 1) != 0)
3428                   {
3429                     j = i;
3430                     i--;
3431
3432                     for (; i != sv; i--)
3433                       if ((pb->eqs[e].coef[i] & 1) != 0)
3434                         break;
3435
3436                     break;
3437                   }
3438
3439               if (j != 0 && i == sv)
3440                 {
3441                   omega_do_mod (pb, 2, e, j);
3442                   e++;
3443                   continue;
3444                 }
3445
3446               j = 0;
3447               for (i = pb->num_vars; i != sv; i--)
3448                 if (pb->eqs[e].coef[i] != 0
3449                     && factor > abs (pb->eqs[e].coef[i]) + 1)
3450                   {
3451                     factor = abs (pb->eqs[e].coef[i]) + 1;
3452                     j = i;
3453                   }
3454
3455               if (j == sv)
3456                 {
3457                   if (dump_file && (dump_flags & TDF_DETAILS))
3458                     fprintf (dump_file, "should not have happened\n");
3459                   gcc_assert (0);
3460                 }
3461
3462               omega_do_mod (pb, factor, e, j);
3463               /* Go back and try this equation again.  */
3464               e++;
3465             }
3466         }
3467     }
3468
3469   pb->num_eqs = 0;
3470   return omega_unknown;
3471 }
3472
3473 /* Transform an inequation E to an equality, then solve DIFF problems
3474    based on PB, and only differing by the constant part that is
3475    diminished by one, trying to figure out which of the constants
3476    satisfies PB.    */
3477
3478 static enum omega_result
3479 parallel_splinter (omega_pb pb, int e, int diff,
3480                    enum omega_result desired_res)
3481 {
3482   omega_pb tmp_problem;
3483   int i;
3484
3485   if (dump_file && (dump_flags & TDF_DETAILS))
3486     {
3487       fprintf (dump_file, "Using parallel splintering\n");
3488       omega_print_problem (dump_file, pb);
3489     }
3490
3491   tmp_problem = XNEW (struct omega_pb_d);
3492   omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
3493   pb->num_eqs = 1;
3494
3495   for (i = 0; i <= diff; i++)
3496     {
3497       omega_copy_problem (tmp_problem, pb);
3498
3499       if (dump_file && (dump_flags & TDF_DETAILS))
3500         {
3501           fprintf (dump_file, "Splinter # %i\n", i);
3502           omega_print_problem (dump_file, pb);
3503         }
3504
3505       if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
3506         {
3507           free (tmp_problem);
3508           return omega_true;
3509         }
3510
3511       pb->eqs[0].coef[0]--;
3512     }
3513
3514   free (tmp_problem);
3515   return omega_false;
3516 }
3517
3518 /* Helper function: solve equations one at a time.  */
3519
3520 static enum omega_result
3521 omega_solve_geq (omega_pb pb, enum omega_result desired_res)
3522 {
3523   int i, e;
3524   int n_vars, fv;
3525   enum omega_result result;
3526   bool coupled_subscripts = false;
3527   bool smoothed = false;
3528   bool eliminate_again;
3529   bool tried_eliminating_redundant = false;
3530
3531   if (desired_res != omega_simplify)
3532     {
3533       pb->num_subs = 0;
3534       pb->safe_vars = 0;
3535     }
3536
3537  solve_geq_start:
3538   do {
3539     gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
3540
3541     /* Verify that there are not too many inequalities.  */
3542     gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
3543
3544     if (dump_file && (dump_flags & TDF_DETAILS))
3545       {
3546         fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
3547                  desired_res, please_no_equalities_in_simplified_problems);
3548         omega_print_problem (dump_file, pb);
3549         fprintf (dump_file, "\n");
3550       }
3551
3552     n_vars = pb->num_vars;
3553
3554     if (n_vars == 1)
3555       {
3556         enum omega_eqn_color u_color = omega_black;
3557         enum omega_eqn_color l_color = omega_black;
3558         int upper_bound = pos_infinity;
3559         int lower_bound = neg_infinity;
3560
3561         for (e = pb->num_geqs - 1; e >= 0; e--)
3562           {
3563             int a = pb->geqs[e].coef[1];
3564             int c = pb->geqs[e].coef[0];
3565
3566             /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax.  */
3567             if (a == 0)
3568               {
3569                 if (c < 0)
3570                   return omega_problem_has_no_solution ();
3571               }
3572             else if (a > 0)
3573               {
3574                 if (a != 1)
3575                   c = int_div (c, a);
3576
3577                 if (lower_bound < -c
3578                     || (lower_bound == -c
3579                         && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3580                   {
3581                     lower_bound = -c;
3582                     l_color = pb->geqs[e].color;
3583                   }
3584               }
3585             else
3586               {
3587                 if (a != -1)
3588                   c = int_div (c, -a);
3589
3590                 if (upper_bound > c
3591                     || (upper_bound == c
3592                         && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
3593                   {
3594                     upper_bound = c;
3595                     u_color = pb->geqs[e].color;
3596                   }
3597               }
3598           }
3599
3600         if (dump_file && (dump_flags & TDF_DETAILS))
3601           {
3602             fprintf (dump_file, "upper bound = %d\n", upper_bound);
3603             fprintf (dump_file, "lower bound = %d\n", lower_bound);
3604           }
3605
3606         if (lower_bound > upper_bound)
3607           return omega_problem_has_no_solution ();
3608
3609         if (desired_res == omega_simplify)
3610           {
3611             pb->num_geqs = 0;
3612             if (pb->safe_vars == 1)
3613               {
3614
3615                 if (lower_bound == upper_bound
3616                     && u_color == omega_black
3617                     && l_color == omega_black)
3618                   {
3619                     pb->eqs[0].coef[0] = -lower_bound;
3620                     pb->eqs[0].coef[1] = 1;
3621                     pb->eqs[0].color = omega_black;
3622                     pb->num_eqs = 1;
3623                     return omega_solve_problem (pb, desired_res);
3624                   }
3625                 else
3626                   {
3627                     if (lower_bound > neg_infinity)
3628                       {
3629                         pb->geqs[0].coef[0] = -lower_bound;
3630                         pb->geqs[0].coef[1] = 1;
3631                         pb->geqs[0].key = 1;
3632                         pb->geqs[0].color = l_color;
3633                         pb->geqs[0].touched = 0;
3634                         pb->num_geqs = 1;
3635                       }
3636
3637                     if (upper_bound < pos_infinity)
3638                       {
3639                         pb->geqs[pb->num_geqs].coef[0] = upper_bound;
3640                         pb->geqs[pb->num_geqs].coef[1] = -1;
3641                         pb->geqs[pb->num_geqs].key = -1;
3642                         pb->geqs[pb->num_geqs].color = u_color;
3643                         pb->geqs[pb->num_geqs].touched = 0;
3644                         pb->num_geqs++;
3645                       }
3646                   }
3647               }
3648             else
3649               pb->num_vars = 0;
3650
3651             omega_problem_reduced (pb);
3652             return omega_false;
3653           }
3654
3655         if (original_problem != no_problem
3656             && l_color == omega_black
3657             && u_color == omega_black
3658             && !conservative
3659             && lower_bound == upper_bound)
3660           {
3661             pb->eqs[0].coef[0] = -lower_bound;
3662             pb->eqs[0].coef[1] = 1;
3663             pb->num_eqs = 1;
3664             adding_equality_constraint (pb, 0);
3665           }
3666
3667         return omega_true;
3668       }
3669
3670     if (!pb->variables_freed)
3671       {
3672         pb->variables_freed = true;
3673
3674         if (desired_res != omega_simplify)
3675           omega_free_eliminations (pb, 0);
3676         else
3677           omega_free_eliminations (pb, pb->safe_vars);
3678
3679         n_vars = pb->num_vars;
3680
3681         if (n_vars == 1)
3682           continue;
3683       }
3684
3685     switch (normalize_omega_problem (pb))
3686       {
3687       case normalize_false:
3688         return omega_false;
3689         break;
3690
3691       case normalize_coupled:
3692         coupled_subscripts = true;
3693         break;
3694
3695       case normalize_uncoupled:
3696         coupled_subscripts = false;
3697         break;
3698
3699       default:
3700         gcc_unreachable ();
3701       }
3702
3703     n_vars = pb->num_vars;
3704
3705     if (dump_file && (dump_flags & TDF_DETAILS))
3706       {
3707         fprintf (dump_file, "\nafter normalization:\n");
3708         omega_print_problem (dump_file, pb);
3709         fprintf (dump_file, "\n");
3710         fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
3711       }
3712
3713     do {
3714       int parallel_difference = INT_MAX;
3715       int best_parallel_eqn = -1;
3716       int minC, maxC, minCj = 0;
3717       int lower_bound_count = 0;
3718       int e2, Le = 0, Ue;
3719       bool possible_easy_int_solution;
3720       int max_splinters = 1;
3721       bool exact = false;
3722       bool lucky_exact = false;
3723       int best = (INT_MAX);
3724       int j = 0, jLe = 0, jLowerBoundCount = 0;
3725
3726
3727       eliminate_again = false;
3728
3729       if (pb->num_eqs > 0)
3730         return omega_solve_problem (pb, desired_res);
3731
3732       if (!coupled_subscripts)
3733         {
3734           if (pb->safe_vars == 0)
3735             pb->num_geqs = 0;
3736           else
3737             for (e = pb->num_geqs - 1; e >= 0; e--)
3738               if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
3739                 omega_delete_geq (pb, e, n_vars);
3740
3741           pb->num_vars = pb->safe_vars;
3742
3743           if (desired_res == omega_simplify)
3744             {
3745               omega_problem_reduced (pb);
3746               return omega_false;
3747             }
3748
3749           return omega_true;
3750         }
3751
3752       if (desired_res != omega_simplify)
3753         fv = 0;
3754       else
3755         fv = pb->safe_vars;
3756
3757       if (pb->num_geqs == 0)
3758         {
3759           if (desired_res == omega_simplify)
3760             {
3761               pb->num_vars = pb->safe_vars;
3762               omega_problem_reduced (pb);
3763               return omega_false;
3764             }
3765           return omega_true;
3766         }
3767
3768       if (desired_res == omega_simplify && n_vars == pb->safe_vars)
3769         {
3770           omega_problem_reduced (pb);
3771           return omega_false;
3772         }
3773
3774       if (pb->num_geqs > OMEGA_MAX_GEQS - 30
3775           || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
3776         {
3777           if (dump_file && (dump_flags & TDF_DETAILS))
3778             fprintf (dump_file,
3779                      "TOO MANY EQUATIONS; "
3780                      "%d equations, %d variables, "
3781                      "ELIMINATING REDUNDANT ONES\n",
3782                      pb->num_geqs, n_vars);
3783
3784           if (!omega_eliminate_redundant (pb, false))
3785             return omega_false;
3786
3787           n_vars = pb->num_vars;
3788
3789           if (pb->num_eqs > 0)
3790             return omega_solve_problem (pb, desired_res);
3791
3792           if (dump_file && (dump_flags & TDF_DETAILS))
3793             fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
3794         }
3795
3796       if (desired_res != omega_simplify)
3797         fv = 0;
3798       else
3799         fv = pb->safe_vars;
3800
3801       for (i = n_vars; i != fv; i--)
3802         {
3803           int score;
3804           int ub = -2;
3805           int lb = -2;
3806           bool lucky = false;
3807           int upper_bound_count = 0;
3808
3809           lower_bound_count = 0;
3810           minC = maxC = 0;
3811
3812           for (e = pb->num_geqs - 1; e >= 0; e--)
3813             if (pb->geqs[e].coef[i] < 0)
3814               {
3815                 minC = MIN (minC, pb->geqs[e].coef[i]);
3816                 upper_bound_count++;
3817                 if (pb->geqs[e].coef[i] < -1)
3818                   {
3819                     if (ub == -2)
3820                       ub = e;
3821                     else
3822                       ub = -1;
3823                   }
3824               }
3825             else if (pb->geqs[e].coef[i] > 0)
3826               {
3827                 maxC = MAX (maxC, pb->geqs[e].coef[i]);
3828                 lower_bound_count++;
3829                 Le = e;
3830                 if (pb->geqs[e].coef[i] > 1)
3831                   {
3832                     if (lb == -2)
3833                       lb = e;
3834                     else
3835                       lb = -1;
3836                   }
3837               }
3838
3839           if (lower_bound_count == 0
3840               || upper_bound_count == 0)
3841             {
3842               lower_bound_count = 0;
3843               break;
3844             }
3845
3846           if (ub >= 0 && lb >= 0
3847               && pb->geqs[lb].key == -pb->geqs[ub].key)
3848             {
3849               int Lc = pb->geqs[lb].coef[i];
3850               int Uc = -pb->geqs[ub].coef[i];
3851               int diff =
3852                 Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
3853               lucky = (diff >= (Uc - 1) * (Lc - 1));
3854             }
3855
3856           if (maxC == 1
3857               || minC == -1
3858               || lucky
3859               || in_approximate_mode)
3860             {
3861               score = upper_bound_count * lower_bound_count;
3862
3863               if (dump_file && (dump_flags & TDF_DETAILS))
3864                 fprintf (dump_file,
3865                          "For %s, exact, score = %d*%d, range = %d ... %d,"
3866                          "\nlucky = %d, in_approximate_mode=%d \n",
3867                          omega_variable_to_str (pb, i),
3868                          upper_bound_count,
3869                          lower_bound_count, minC, maxC, lucky,
3870                          in_approximate_mode);
3871
3872               if (!exact
3873                   || score < best)
3874                 {
3875
3876                   best = score;
3877                   j = i;
3878                   minCj = minC;
3879                   jLe = Le;
3880                   jLowerBoundCount = lower_bound_count;
3881                   exact = true;
3882                   lucky_exact = lucky;
3883                   if (score == 1)
3884                     break;
3885                 }
3886             }
3887           else if (!exact)
3888             {
3889               if (dump_file && (dump_flags & TDF_DETAILS))
3890                 fprintf (dump_file,
3891                          "For %s, non-exact, score = %d*%d,"
3892                          "range = %d ... %d \n",
3893                          omega_variable_to_str (pb, i),
3894                          upper_bound_count,
3895                          lower_bound_count, minC, maxC);
3896
3897               score = maxC - minC;
3898
3899               if (best > score)
3900                 {
3901                   best = score;
3902                   j = i;
3903                   minCj = minC;
3904                   jLe = Le;
3905                   jLowerBoundCount = lower_bound_count;
3906                 }
3907             }
3908         }
3909
3910       if (lower_bound_count == 0)
3911         {
3912           omega_free_eliminations (pb, pb->safe_vars);
3913           n_vars = pb->num_vars;
3914           eliminate_again = true;
3915           continue;
3916         }
3917
3918       i = j;
3919       minC = minCj;
3920       Le = jLe;
3921       lower_bound_count = jLowerBoundCount;
3922
3923       for (e = pb->num_geqs - 1; e >= 0; e--)
3924         if (pb->geqs[e].coef[i] > 0)
3925           {
3926             if (pb->geqs[e].coef[i] == -minC)
3927               max_splinters += -minC - 1;
3928             else
3929               max_splinters +=
3930                 check_pos_mul ((pb->geqs[e].coef[i] - 1),
3931                                (-minC - 1)) / (-minC) + 1;
3932           }
3933
3934       /* #ifdef Omega3 */
3935       /* Trying to produce exact elimination by finding redundant
3936          constraints.  */
3937       if (!exact && !tried_eliminating_redundant)
3938         {
3939           omega_eliminate_redundant (pb, false);
3940           tried_eliminating_redundant = true;
3941           eliminate_again = true;
3942           continue;
3943         }
3944       tried_eliminating_redundant = false;
3945       /* #endif */
3946
3947       if (return_single_result && desired_res == omega_simplify && !exact)
3948         {
3949           omega_problem_reduced (pb);
3950           return omega_true;
3951         }
3952
3953       /* #ifndef Omega3 */
3954       /* Trying to produce exact elimination by finding redundant
3955          constraints.  */
3956       if (!exact && !tried_eliminating_redundant)
3957         {
3958           omega_eliminate_redundant (pb, false);
3959           tried_eliminating_redundant = true;
3960           continue;
3961         }
3962       tried_eliminating_redundant = false;
3963       /* #endif */
3964
3965       if (!exact)
3966         {
3967           int e1, e2;
3968
3969           for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
3970             if (pb->geqs[e1].color == omega_black)
3971               for (e2 = e1 - 1; e2 >= 0; e2--)
3972                 if (pb->geqs[e2].color == omega_black
3973                     && pb->geqs[e1].key == -pb->geqs[e2].key
3974                     && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3975                         * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3976                         / 2 < parallel_difference))
3977                   {
3978                     parallel_difference =
3979                       (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
3980                       * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
3981                       / 2;
3982                     best_parallel_eqn = e1;
3983                   }
3984
3985           if (dump_file && (dump_flags & TDF_DETAILS)
3986               && best_parallel_eqn >= 0)
3987             {
3988               fprintf (dump_file,
3989                        "Possible parallel projection, diff = %d, in ",
3990                        parallel_difference);
3991               omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
3992               fprintf (dump_file, "\n");
3993               omega_print_problem (dump_file, pb);
3994             }
3995         }
3996
3997       if (dump_file && (dump_flags & TDF_DETAILS))
3998         {
3999           fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
4000                    omega_variable_to_str (pb, i), i, minC,
4001                    lower_bound_count);
4002           omega_print_problem (dump_file, pb);
4003
4004           if (lucky_exact)
4005             fprintf (dump_file, "(a lucky exact elimination)\n");
4006
4007           else if (exact)
4008             fprintf (dump_file, "(an exact elimination)\n");
4009
4010           fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
4011         }
4012
4013       gcc_assert (max_splinters >= 1);
4014
4015       if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
4016           && parallel_difference <= max_splinters)
4017         return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
4018                                   desired_res);
4019
4020       smoothed = false;
4021
4022       if (i != n_vars)
4023         {
4024           int t;
4025           int j = pb->num_vars;
4026
4027           if (dump_file && (dump_flags & TDF_DETAILS))
4028             {
4029               fprintf (dump_file, "Swapping %d and %d\n", i, j);
4030               omega_print_problem (dump_file, pb);
4031             }
4032
4033           swap (&pb->var[i], &pb->var[j]);
4034
4035           for (e = pb->num_geqs - 1; e >= 0; e--)
4036             if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
4037               {
4038                 pb->geqs[e].touched = 1;
4039                 t = pb->geqs[e].coef[i];
4040                 pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
4041                 pb->geqs[e].coef[j] = t;
4042               }
4043
4044           for (e = pb->num_subs - 1; e >= 0; e--)
4045             if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
4046               {
4047                 t = pb->subs[e].coef[i];
4048                 pb->subs[e].coef[i] = pb->subs[e].coef[j];
4049                 pb->subs[e].coef[j] = t;
4050               }
4051
4052           if (dump_file && (dump_flags & TDF_DETAILS))
4053             {
4054               fprintf (dump_file, "Swapping complete \n");
4055               omega_print_problem (dump_file, pb);
4056               fprintf (dump_file, "\n");
4057             }
4058
4059           i = j;
4060         }
4061
4062       else if (dump_file && (dump_flags & TDF_DETAILS))
4063         {
4064           fprintf (dump_file, "No swap needed\n");
4065           omega_print_problem (dump_file, pb);
4066         }
4067
4068       pb->num_vars--;
4069       n_vars = pb->num_vars;
4070
4071       if (exact)
4072         {
4073           if (n_vars == 1)
4074             {
4075               int upper_bound = pos_infinity;
4076               int lower_bound = neg_infinity;
4077               enum omega_eqn_color ub_color = omega_black;
4078               enum omega_eqn_color lb_color = omega_black;
4079               int topeqn = pb->num_geqs - 1;
4080               int Lc = pb->geqs[Le].coef[i];
4081
4082               for (Le = topeqn; Le >= 0; Le--)
4083                 if ((Lc = pb->geqs[Le].coef[i]) == 0)
4084                   {
4085                     if (pb->geqs[Le].coef[1] == 1)
4086                       {
4087                         int constantTerm = -pb->geqs[Le].coef[0];
4088
4089                         if (constantTerm > lower_bound ||
4090                             (constantTerm == lower_bound &&
4091                              !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
4092                           {
4093                             lower_bound = constantTerm;
4094                             lb_color = pb->geqs[Le].color;
4095                           }
4096
4097                         if (dump_file && (dump_flags & TDF_DETAILS))
4098                           {
4099                             if (pb->geqs[Le].color == omega_black)
4100                               fprintf (dump_file, " :::=> %s >= %d\n",
4101                                        omega_variable_to_str (pb, 1),
4102                                        constantTerm);
4103                             else
4104                               fprintf (dump_file,
4105                                        " :::=> [%s >= %d]\n",
4106                                        omega_variable_to_str (pb, 1),
4107                                        constantTerm);
4108                           }
4109                       }
4110                     else
4111                       {
4112                         int constantTerm = pb->geqs[Le].coef[0];
4113                         if (constantTerm < upper_bound ||
4114                             (constantTerm == upper_bound
4115                              && !omega_eqn_is_red (&pb->geqs[Le],
4116                                                    desired_res)))
4117                           {
4118                             upper_bound = constantTerm;
4119                             ub_color = pb->geqs[Le].color;
4120                           }
4121
4122                         if (dump_file && (dump_flags & TDF_DETAILS))
4123                           {
4124                             if (pb->geqs[Le].color == omega_black)
4125                               fprintf (dump_file, " :::=> %s <= %d\n",
4126                                        omega_variable_to_str (pb, 1),
4127                                        constantTerm);
4128                             else
4129                               fprintf (dump_file,
4130                                        " :::=> [%s <= %d]\n",
4131                                        omega_variable_to_str (pb, 1),
4132                                        constantTerm);
4133                           }
4134                       }
4135                   }
4136                 else if (Lc > 0)
4137                   for (Ue = topeqn; Ue >= 0; Ue--)
4138                     if (pb->geqs[Ue].coef[i] < 0
4139                         && pb->geqs[Le].key != -pb->geqs[Ue].key)
4140                       {
4141                         int Uc = -pb->geqs[Ue].coef[i];
4142                         int coefficient = pb->geqs[Ue].coef[1] * Lc
4143                           + pb->geqs[Le].coef[1] * Uc;
4144                         int constantTerm = pb->geqs[Ue].coef[0] * Lc
4145                           + pb->geqs[Le].coef[0] * Uc;
4146
4147                         if (dump_file && (dump_flags & TDF_DETAILS))
4148                           {
4149                             omega_print_geq_extra (dump_file, pb,
4150                                                    &(pb->geqs[Ue]));
4151                             fprintf (dump_file, "\n");
4152                             omega_print_geq_extra (dump_file, pb,
4153                                                    &(pb->geqs[Le]));
4154                             fprintf (dump_file, "\n");
4155                           }
4156
4157                         if (coefficient > 0)
4158                           {
4159                             constantTerm = -int_div (constantTerm, coefficient);
4160
4161                             if (constantTerm > lower_bound
4162                                 || (constantTerm == lower_bound
4163                                     && (desired_res != omega_simplify
4164                                         || (pb->geqs[Ue].color == omega_black
4165                                             && pb->geqs[Le].color == omega_black))))
4166                               {
4167                                 lower_bound = constantTerm;
4168                                 lb_color = (pb->geqs[Ue].color == omega_red
4169                                             || pb->geqs[Le].color == omega_red)
4170                                   ? omega_red : omega_black;
4171                               }
4172
4173                             if (dump_file && (dump_flags & TDF_DETAILS))
4174                               {
4175                                 if (pb->geqs[Ue].color == omega_red
4176                                     || pb->geqs[Le].color == omega_red)
4177                                   fprintf (dump_file,
4178                                            " ::=> [%s >= %d]\n",
4179                                            omega_variable_to_str (pb, 1),
4180                                            constantTerm);
4181                                 else
4182                                   fprintf (dump_file,
4183                                            " ::=> %s >= %d\n",
4184                                            omega_variable_to_str (pb, 1),
4185                                            constantTerm);
4186                               }
4187                           }
4188                         else
4189                           {
4190                             constantTerm = int_div (constantTerm, -coefficient);
4191                             if (constantTerm < upper_bound
4192                                 || (constantTerm == upper_bound
4193                                     && pb->geqs[Ue].color == omega_black
4194                                     && pb->geqs[Le].color == omega_black))
4195                               {
4196                                 upper_bound = constantTerm;
4197                                 ub_color = (pb->geqs[Ue].color == omega_red
4198                                             || pb->geqs[Le].color == omega_red)
4199                                   ? omega_red : omega_black;
4200                               }
4201
4202                             if (dump_file
4203                                 && (dump_flags & TDF_DETAILS))
4204                               {
4205                                 if (pb->geqs[Ue].color == omega_red
4206                                     || pb->geqs[Le].color == omega_red)
4207                                   fprintf (dump_file,
4208                                            " ::=> [%s <= %d]\n",
4209                                            omega_variable_to_str (pb, 1),
4210                                            constantTerm);
4211                                 else
4212                                   fprintf (dump_file,
4213                                            " ::=> %s <= %d\n",
4214                                            omega_variable_to_str (pb, 1),
4215                                            constantTerm);
4216                               }
4217                           }
4218                       }
4219
4220               pb->num_geqs = 0;
4221
4222               if (dump_file && (dump_flags & TDF_DETAILS))
4223                 fprintf (dump_file,
4224                          " therefore, %c%d <= %c%s%c <= %d%c\n",
4225                          lb_color == omega_red ? '[' : ' ', lower_bound,
4226                          (lb_color == omega_red && ub_color == omega_black)
4227                          ? ']' : ' ',
4228                          omega_variable_to_str (pb, 1),
4229                          (lb_color == omega_black && ub_color == omega_red)
4230                          ? '[' : ' ',
4231                          upper_bound, ub_color == omega_red ? ']' : ' ');
4232
4233               if (lower_bound > upper_bound)
4234                 return omega_false;
4235
4236               if (pb->safe_vars == 1)
4237                 {
4238                   if (upper_bound == lower_bound
4239                       && !(ub_color == omega_red || lb_color == omega_red)
4240                       && !please_no_equalities_in_simplified_problems)
4241                     {
4242                       pb->num_eqs++;
4243                       pb->eqs[0].coef[1] = -1;
4244                       pb->eqs[0].coef[0] = upper_bound;
4245
4246                       if (ub_color == omega_red
4247                           || lb_color == omega_red)
4248                         pb->eqs[0].color = omega_red;
4249
4250                       if (desired_res == omega_simplify
4251                           && pb->eqs[0].color == omega_black)
4252                         return omega_solve_problem (pb, desired_res);
4253                     }
4254
4255                   if (upper_bound != pos_infinity)
4256                     {
4257                       pb->geqs[0].coef[1] = -1;
4258                       pb->geqs[0].coef[0] = upper_bound;
4259                       pb->geqs[0].color = ub_color;
4260                       pb->geqs[0].key = -1;
4261                       pb->geqs[0].touched = 0;
4262                       pb->num_geqs++;
4263                     }
4264
4265                   if (lower_bound != neg_infinity)
4266                     {
4267                       pb->geqs[pb->num_geqs].coef[1] = 1;
4268                       pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
4269                       pb->geqs[pb->num_geqs].color = lb_color;
4270                       pb->geqs[pb->num_geqs].key = 1;
4271                       pb->geqs[pb->num_geqs].touched = 0;
4272                       pb->num_geqs++;
4273                     }
4274                 }
4275
4276               if (desired_res == omega_simplify)
4277                 {
4278                   omega_problem_reduced (pb);
4279                   return omega_false;
4280                 }
4281               else
4282                 {
4283                   if (!conservative
4284                       && (desired_res != omega_simplify
4285                           || (lb_color == omega_black
4286                               && ub_color == omega_black))
4287                       && original_problem != no_problem
4288                       && lower_bound == upper_bound)
4289                     {
4290                       for (i = original_problem->num_vars; i >= 0; i--)
4291                         if (original_problem->var[i] == pb->var[1])
4292                           break;
4293
4294                       if (i == 0)
4295                         break;
4296
4297                       e = original_problem->num_eqs++;
4298                       omega_init_eqn_zero (&original_problem->eqs[e],
4299                                            original_problem->num_vars);
4300                       original_problem->eqs[e].coef[i] = -1;
4301                       original_problem->eqs[e].coef[0] = upper_bound;
4302
4303                       if (dump_file && (dump_flags & TDF_DETAILS))
4304                         {
4305                           fprintf (dump_file,
4306                                    "adding equality %d to outer problem\n", e);
4307                           omega_print_problem (dump_file, original_problem);
4308                         }
4309                     }
4310                   return omega_true;
4311                 }
4312             }
4313
4314           eliminate_again = true;
4315
4316           if (lower_bound_count == 1)
4317             {
4318               eqn lbeqn = omega_alloc_eqns (0, 1);
4319               int Lc = pb->geqs[Le].coef[i];
4320
4321               if (dump_file && (dump_flags & TDF_DETAILS))
4322                 fprintf (dump_file, "an inplace elimination\n");
4323
4324               omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
4325               omega_delete_geq_extra (pb, Le, n_vars + 1);
4326
4327               for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4328                 if (pb->geqs[Ue].coef[i] < 0)
4329                   {
4330                     if (lbeqn->key == -pb->geqs[Ue].key)
4331                       omega_delete_geq_extra (pb, Ue, n_vars + 1);
4332                     else
4333                       {
4334                         int k;
4335                         int Uc = -pb->geqs[Ue].coef[i];
4336                         pb->geqs[Ue].touched = 1;
4337                         eliminate_again = false;
4338
4339                         if (lbeqn->color == omega_red)
4340                           pb->geqs[Ue].color = omega_red;
4341
4342                         for (k = 0; k <= n_vars; k++)
4343                           pb->geqs[Ue].coef[k] =
4344                             check_mul (pb->geqs[Ue].coef[k], Lc) +
4345                             check_mul (lbeqn->coef[k], Uc);
4346
4347                         if (dump_file && (dump_flags & TDF_DETAILS))
4348                           {
4349                             omega_print_geq (dump_file, pb,
4350                                              &(pb->geqs[Ue]));
4351                             fprintf (dump_file, "\n");
4352                           }
4353                       }
4354                   }
4355
4356               omega_free_eqns (lbeqn, 1);
4357               continue;
4358             }
4359           else
4360             {
4361               int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
4362               bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
4363               int num_dead = 0;
4364               int top_eqn = pb->num_geqs - 1;
4365               lower_bound_count--;
4366
4367               if (dump_file && (dump_flags & TDF_DETAILS))
4368                 fprintf (dump_file, "lower bound count = %d\n",
4369                          lower_bound_count);
4370
4371               for (Le = top_eqn; Le >= 0; Le--)
4372                 if (pb->geqs[Le].coef[i] > 0)
4373                   {
4374                     int Lc = pb->geqs[Le].coef[i];
4375                     for (Ue = top_eqn; Ue >= 0; Ue--)
4376                       if (pb->geqs[Ue].coef[i] < 0)
4377                         {
4378                           if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4379                             {
4380                               int k;
4381                               int Uc = -pb->geqs[Ue].coef[i];
4382
4383                               if (num_dead == 0)
4384                                 e2 = pb->num_geqs++;
4385                               else
4386                                 e2 = dead_eqns[--num_dead];
4387
4388                               gcc_assert (e2 < OMEGA_MAX_GEQS);
4389
4390                               if (dump_file && (dump_flags & TDF_DETAILS))
4391                                 {
4392                                   fprintf (dump_file,
4393                                            "Le = %d, Ue = %d, gen = %d\n",
4394                                            Le, Ue, e2);
4395                                   omega_print_geq_extra (dump_file, pb,
4396                                                          &(pb->geqs[Le]));
4397                                   fprintf (dump_file, "\n");
4398                                   omega_print_geq_extra (dump_file, pb,
4399                                                          &(pb->geqs[Ue]));
4400                                   fprintf (dump_file, "\n");
4401                                 }
4402
4403                               eliminate_again = false;
4404
4405                               for (k = n_vars; k >= 0; k--)
4406                                 pb->geqs[e2].coef[k] =
4407                                   check_mul (pb->geqs[Ue].coef[k], Lc) +
4408                                   check_mul (pb->geqs[Le].coef[k], Uc);
4409
4410                               pb->geqs[e2].coef[n_vars + 1] = 0;
4411                               pb->geqs[e2].touched = 1;
4412
4413                               if (pb->geqs[Ue].color == omega_red
4414                                   || pb->geqs[Le].color == omega_red)
4415                                 pb->geqs[e2].color = omega_red;
4416                               else
4417                                 pb->geqs[e2].color = omega_black;
4418
4419                               if (dump_file && (dump_flags & TDF_DETAILS))
4420                                 {
4421                                   omega_print_geq (dump_file, pb,
4422                                                    &(pb->geqs[e2]));
4423                                   fprintf (dump_file, "\n");
4424                                 }
4425                             }
4426
4427                           if (lower_bound_count == 0)
4428                             {
4429                               dead_eqns[num_dead++] = Ue;
4430
4431                               if (dump_file && (dump_flags & TDF_DETAILS))
4432                                 fprintf (dump_file, "Killed %d\n", Ue);
4433                             }
4434                         }
4435
4436                     lower_bound_count--;
4437                     dead_eqns[num_dead++] = Le;
4438
4439                     if (dump_file && (dump_flags & TDF_DETAILS))
4440                       fprintf (dump_file, "Killed %d\n", Le);
4441                   }
4442
4443               for (e = pb->num_geqs - 1; e >= 0; e--)
4444                 is_dead[e] = false;
4445
4446               while (num_dead > 0)
4447                 is_dead[dead_eqns[--num_dead]] = true;
4448
4449               for (e = pb->num_geqs - 1; e >= 0; e--)
4450                 if (is_dead[e])
4451                   omega_delete_geq_extra (pb, e, n_vars + 1);
4452
4453               free (dead_eqns);
4454               free (is_dead);
4455               continue;
4456             }
4457         }
4458       else
4459         {
4460           omega_pb rS, iS;
4461
4462           rS = omega_alloc_problem (0, 0);
4463           iS = omega_alloc_problem (0, 0);
4464           e2 = 0;
4465           possible_easy_int_solution = true;
4466
4467           for (e = 0; e < pb->num_geqs; e++)
4468             if (pb->geqs[e].coef[i] == 0)
4469               {
4470                 omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
4471                                 pb->num_vars);
4472                 omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
4473                                 pb->num_vars);
4474
4475                 if (dump_file && (dump_flags & TDF_DETAILS))
4476                   {
4477                     int t;
4478                     fprintf (dump_file, "Copying (%d, %d): ", i,
4479                              pb->geqs[e].coef[i]);
4480                     omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
4481                     fprintf (dump_file, "\n");
4482                     for (t = 0; t <= n_vars + 1; t++)
4483                       fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
4484                     fprintf (dump_file, "\n");
4485
4486                   }
4487                 e2++;
4488                 gcc_assert (e2 < OMEGA_MAX_GEQS);
4489               }
4490
4491           for (Le = pb->num_geqs - 1; Le >= 0; Le--)
4492             if (pb->geqs[Le].coef[i] > 0)
4493               for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
4494                 if (pb->geqs[Ue].coef[i] < 0)
4495                   {
4496                     int k;
4497                     int Lc = pb->geqs[Le].coef[i];
4498                     int Uc = -pb->geqs[Ue].coef[i];
4499
4500                     if (pb->geqs[Le].key != -pb->geqs[Ue].key)
4501                       {
4502
4503                         rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
4504
4505                         if (dump_file && (dump_flags & TDF_DETAILS))
4506                           {
4507                             fprintf (dump_file, "---\n");
4508                             fprintf (dump_file,
4509                                      "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
4510                                      Le, Lc, Ue, Uc, e2);
4511                             omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
4512                             fprintf (dump_file, "\n");
4513                             omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
4514                             fprintf (dump_file, "\n");
4515                           }
4516
4517                         if (Uc == Lc)
4518                           {
4519                             for (k = n_vars; k >= 0; k--)
4520                               iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4521                                 pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
4522
4523                             iS->geqs[e2].coef[0] -= (Uc - 1);
4524                           }
4525                         else
4526                           {
4527                             for (k = n_vars; k >= 0; k--)
4528                               iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
4529                                 check_mul (pb->geqs[Ue].coef[k], Lc) +
4530                                 check_mul (pb->geqs[Le].coef[k], Uc);
4531
4532                             iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
4533                           }
4534
4535                         if (pb->geqs[Ue].color == omega_red
4536                             || pb->geqs[Le].color == omega_red)
4537                           iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
4538                         else
4539                           iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
4540
4541                         if (dump_file && (dump_flags & TDF_DETAILS))
4542                           {
4543                             omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
4544                             fprintf (dump_file, "\n");
4545                           }
4546
4547                         e2++;
4548                         gcc_assert (e2 < OMEGA_MAX_GEQS);
4549                       }
4550                     else if (pb->geqs[Ue].coef[0] * Lc +
4551                              pb->geqs[Le].coef[0] * Uc -
4552                              (Uc - 1) * (Lc - 1) < 0)
4553                       possible_easy_int_solution = false;
4554                   }
4555
4556           iS->variables_initialized = rS->variables_initialized = true;
4557           iS->num_vars = rS->num_vars = pb->num_vars;
4558           iS->num_geqs = rS->num_geqs = e2;
4559           iS->num_eqs = rS->num_eqs = 0;
4560           iS->num_subs = rS->num_subs = pb->num_subs;
4561           iS->safe_vars = rS->safe_vars = pb->safe_vars;
4562
4563           for (e = n_vars; e >= 0; e--)
4564             rS->var[e] = pb->var[e];
4565
4566           for (e = n_vars; e >= 0; e--)
4567             iS->var[e] = pb->var[e];
4568
4569           for (e = pb->num_subs - 1; e >= 0; e--)
4570             {
4571               omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
4572               omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
4573             }
4574
4575           pb->num_vars++;
4576           n_vars = pb->num_vars;
4577
4578           if (desired_res != omega_true)
4579             {
4580               if (original_problem == no_problem)
4581                 {
4582                   original_problem = pb;
4583                   result = omega_solve_geq (rS, omega_false);
4584                   original_problem = no_problem;
4585                 }
4586               else
4587                 result = omega_solve_geq (rS, omega_false);
4588
4589               if (result == omega_false)
4590                 {
4591                   free (rS);
4592                   free (iS);
4593                   return result;
4594                 }
4595
4596               if (pb->num_eqs > 0)
4597                 {
4598                   /* An equality constraint must have been found */
4599                   free (rS);
4600                   free (iS);
4601                   return omega_solve_problem (pb, desired_res);
4602                 }
4603             }
4604
4605           if (desired_res != omega_false)
4606             {
4607               int j;
4608               int lower_bounds = 0;
4609               int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
4610
4611               if (possible_easy_int_solution)
4612                 {
4613                   conservative++;
4614                   result = omega_solve_geq (iS, desired_res);
4615                   conservative--;
4616
4617                   if (result != omega_false)
4618                     {
4619                       free (rS);
4620                       free (iS);
4621                       free (lower_bound);
4622                       return result;
4623                     }
4624                 }
4625
4626               if (!exact && best_parallel_eqn >= 0
4627                   && parallel_difference <= max_splinters)
4628                 {
4629                   free (rS);
4630                   free (iS);
4631                   free (lower_bound);
4632                   return parallel_splinter (pb, best_parallel_eqn,
4633                                             parallel_difference,
4634                                             desired_res);
4635                 }
4636
4637               if (dump_file && (dump_flags & TDF_DETAILS))
4638                 fprintf (dump_file, "have to do exact analysis\n");
4639
4640               conservative++;
4641
4642               for (e = 0; e < pb->num_geqs; e++)
4643                 if (pb->geqs[e].coef[i] > 1)
4644                   lower_bound[lower_bounds++] = e;
4645
4646               /* Sort array LOWER_BOUND.  */
4647               for (j = 0; j < lower_bounds; j++)
4648                 {
4649                   int k, smallest = j;
4650
4651                   for (k = j + 1; k < lower_bounds; k++)
4652                     if (pb->geqs[lower_bound[smallest]].coef[i] >
4653                         pb->geqs[lower_bound[k]].coef[i])
4654                       smallest = k;
4655
4656                   k = lower_bound[smallest];
4657                   lower_bound[smallest] = lower_bound[j];
4658                   lower_bound[j] = k;
4659                 }
4660
4661               if (dump_file && (dump_flags & TDF_DETAILS))
4662                 {
4663                   fprintf (dump_file, "lower bound coefficients = ");
4664
4665                   for (j = 0; j < lower_bounds; j++)
4666                     fprintf (dump_file, " %d",
4667                              pb->geqs[lower_bound[j]].coef[i]);
4668
4669                   fprintf (dump_file, "\n");
4670                 }
4671
4672               for (j = 0; j < lower_bounds; j++)
4673                 {
4674                   int max_incr;
4675                   int c;
4676                   int worst_lower_bound_constant = -minC;
4677
4678                   e = lower_bound[j];
4679                   max_incr = (((pb->geqs[e].coef[i] - 1) *
4680                                (worst_lower_bound_constant - 1) - 1)
4681                               / worst_lower_bound_constant);
4682                   /* max_incr += 2; */
4683
4684                   if (dump_file && (dump_flags & TDF_DETAILS))
4685                     {
4686                       fprintf (dump_file, "for equation ");
4687                       omega_print_geq (dump_file, pb, &pb->geqs[e]);
4688                       fprintf (dump_file,
4689                                "\ntry decrements from 0 to %d\n",
4690                                max_incr);
4691                       omega_print_problem (dump_file, pb);
4692                     }
4693
4694                   if (max_incr > 50 && !smoothed
4695                       && smooth_weird_equations (pb))
4696                     {
4697                       conservative--;
4698                       free (rS);
4699                       free (iS);
4700                       smoothed = true;
4701                       goto solve_geq_start;
4702                     }
4703
4704                   omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
4705                                   pb->num_vars);
4706                   pb->eqs[0].color = omega_black;
4707                   omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
4708                   pb->geqs[e].touched = 1;
4709                   pb->num_eqs = 1;
4710
4711                   for (c = max_incr; c >= 0; c--)
4712                     {
4713                       if (dump_file && (dump_flags & TDF_DETAILS))
4714                         {
4715                           fprintf (dump_file,
4716                                    "trying next decrement of %d\n",
4717                                    max_incr - c);
4718                           omega_print_problem (dump_file, pb);
4719                         }
4720
4721                       omega_copy_problem (rS, pb);
4722
4723                       if (dump_file && (dump_flags & TDF_DETAILS))
4724                         omega_print_problem (dump_file, rS);
4725
4726                       result = omega_solve_problem (rS, desired_res);
4727
4728                       if (result == omega_true)
4729                         {
4730                           free (rS);
4731                           free (iS);
4732                           free (lower_bound);
4733                           conservative--;
4734                           return omega_true;
4735                         }
4736
4737                       pb->eqs[0].coef[0]--;
4738                     }
4739
4740                   if (j + 1 < lower_bounds)
4741                     {
4742                       pb->num_eqs = 0;
4743                       omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
4744                                       pb->num_vars);
4745                       pb->geqs[e].touched = 1;
4746                       pb->geqs[e].color = omega_black;
4747                       omega_copy_problem (rS, pb);
4748
4749                       if (dump_file && (dump_flags & TDF_DETAILS))
4750                         fprintf (dump_file,
4751                                  "exhausted lower bound, "
4752                                  "checking if still feasible ");
4753
4754                       result = omega_solve_problem (rS, omega_false);
4755
4756                       if (result == omega_false)
4757                         break;
4758                     }
4759                 }
4760
4761               if (dump_file && (dump_flags & TDF_DETAILS))
4762                 fprintf (dump_file, "fall-off the end\n");
4763
4764               free (rS);
4765               free (iS);
4766               free (lower_bound);
4767               conservative--;
4768               return omega_false;
4769             }
4770
4771           free (rS);
4772           free (iS);
4773         }
4774       return omega_unknown;
4775     } while (eliminate_again);
4776   } while (1);
4777 }
4778
4779 /* Because the omega solver is recursive, this counter limits the
4780    recursion depth.  */
4781 static int omega_solve_depth = 0;
4782
4783 /* Return omega_true when the problem PB has a solution following the
4784    DESIRED_RES.  */
4785
4786 enum omega_result
4787 omega_solve_problem (omega_pb pb, enum omega_result desired_res)
4788 {
4789   enum omega_result result;
4790
4791   gcc_assert (pb->num_vars >= pb->safe_vars);
4792   omega_solve_depth++;
4793
4794   if (desired_res != omega_simplify)
4795     pb->safe_vars = 0;
4796
4797   if (omega_solve_depth > 50)
4798     {
4799       if (dump_file && (dump_flags & TDF_DETAILS))
4800         {
4801           fprintf (dump_file,
4802                    "Solve depth = %d, in_approximate_mode = %d, aborting\n",
4803                    omega_solve_depth, in_approximate_mode);
4804           omega_print_problem (dump_file, pb);
4805         }
4806       gcc_assert (0);
4807     }
4808
4809   if (omega_solve_eq (pb, desired_res) == omega_false)
4810     {
4811       omega_solve_depth--;
4812       return omega_false;
4813     }
4814
4815   if (in_approximate_mode && !pb->num_geqs)
4816     {
4817       result = omega_true;
4818       pb->num_vars = pb->safe_vars;
4819       omega_problem_reduced (pb);
4820     }
4821   else
4822     result = omega_solve_geq (pb, desired_res);
4823
4824   omega_solve_depth--;
4825
4826   if (!omega_reduce_with_subs)
4827     {
4828       resurrect_subs (pb);
4829       gcc_assert (please_no_equalities_in_simplified_problems
4830                   || !result || pb->num_subs == 0);
4831     }
4832
4833   return result;
4834 }
4835
4836 /* Return true if red equations constrain the set of possible solutions.
4837    We assume that there are solutions to the black equations by
4838    themselves, so if there is no solution to the combined problem, we
4839    return true.  */
4840
4841 bool
4842 omega_problem_has_red_equations (omega_pb pb)
4843 {
4844   bool result;
4845   int e;
4846   int i;
4847
4848   if (dump_file && (dump_flags & TDF_DETAILS))
4849     {
4850       fprintf (dump_file, "Checking for red equations:\n");
4851       omega_print_problem (dump_file, pb);
4852     }
4853
4854   please_no_equalities_in_simplified_problems++;
4855   may_be_red++;
4856
4857   if (omega_single_result)
4858     return_single_result++;
4859
4860   create_color = true;
4861   result = (omega_simplify_problem (pb) == omega_false);
4862
4863   if (omega_single_result)
4864     return_single_result--;
4865
4866   may_be_red--;
4867   please_no_equalities_in_simplified_problems--;
4868
4869   if (result)
4870     {
4871       if (dump_file && (dump_flags & TDF_DETAILS))
4872         fprintf (dump_file, "Gist is FALSE\n");
4873
4874       pb->num_subs = 0;
4875       pb->num_geqs = 0;
4876       pb->num_eqs = 1;
4877       pb->eqs[0].color = omega_red;
4878
4879       for (i = pb->num_vars; i > 0; i--)
4880         pb->eqs[0].coef[i] = 0;
4881
4882       pb->eqs[0].coef[0] = 1;
4883       return true;
4884     }
4885
4886   free_red_eliminations (pb);
4887   gcc_assert (pb->num_eqs == 0);
4888
4889   for (e = pb->num_geqs - 1; e >= 0; e--)
4890     if (pb->geqs[e].color == omega_red)
4891       result = true;
4892
4893   if (!result)
4894     return false;
4895
4896   for (i = pb->safe_vars; i >= 1; i--)
4897     {
4898       int ub = 0;
4899       int lb = 0;
4900
4901       for (e = pb->num_geqs - 1; e >= 0; e--)
4902         {
4903           if (pb->geqs[e].coef[i])
4904             {
4905               if (pb->geqs[e].coef[i] > 0)
4906                 lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4907
4908               else
4909                 ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
4910             }
4911         }
4912
4913       if (ub == 2 || lb == 2)
4914         {
4915
4916           if (dump_file && (dump_flags & TDF_DETAILS))
4917             fprintf (dump_file, "checks for upper/lower bounds worked!\n");
4918
4919           if (!omega_reduce_with_subs)
4920             {
4921               resurrect_subs (pb);
4922               gcc_assert (pb->num_subs == 0);
4923             }
4924
4925           return true;
4926         }
4927     }
4928
4929
4930   if (dump_file && (dump_flags & TDF_DETAILS))
4931     fprintf (dump_file,
4932              "*** Doing potentially expensive elimination tests "
4933              "for red equations\n");
4934
4935   please_no_equalities_in_simplified_problems++;
4936   omega_eliminate_red (pb, true);
4937   please_no_equalities_in_simplified_problems--;
4938
4939   result = false;
4940   gcc_assert (pb->num_eqs == 0);
4941
4942   for (e = pb->num_geqs - 1; e >= 0; e--)
4943     if (pb->geqs[e].color == omega_red)
4944       result = true;
4945
4946   if (dump_file && (dump_flags & TDF_DETAILS))
4947     {
4948       if (!result)
4949         fprintf (dump_file,
4950                  "******************** Redundant Red Equations eliminated!!\n");
4951       else
4952         fprintf (dump_file,
4953                  "******************** Red Equations remain\n");
4954
4955       omega_print_problem (dump_file, pb);
4956     }
4957
4958   if (!omega_reduce_with_subs)
4959     {
4960       normalize_return_type r;
4961
4962       resurrect_subs (pb);
4963       r = normalize_omega_problem (pb);
4964       gcc_assert (r != normalize_false);
4965
4966       coalesce (pb);
4967       cleanout_wildcards (pb);
4968       gcc_assert (pb->num_subs == 0);
4969     }
4970
4971   return result;
4972 }
4973
4974 /* Calls omega_simplify_problem in approximate mode.  */
4975
4976 enum omega_result
4977 omega_simplify_approximate (omega_pb pb)
4978 {
4979   enum omega_result result;
4980
4981   if (dump_file && (dump_flags & TDF_DETAILS))
4982     fprintf (dump_file, "(Entering approximate mode\n");
4983
4984   in_approximate_mode = true;
4985   result = omega_simplify_problem (pb);
4986   in_approximate_mode = false;
4987
4988   gcc_assert (pb->num_vars == pb->safe_vars);
4989   if (!omega_reduce_with_subs)
4990     gcc_assert (pb->num_subs == 0);
4991
4992   if (dump_file && (dump_flags & TDF_DETAILS))
4993     fprintf (dump_file, "Leaving approximate mode)\n");
4994
4995   return result;
4996 }
4997
4998
4999 /* Simplifies problem PB by eliminating redundant constraints and
5000    reducing the constraints system to a minimal form.  Returns
5001    omega_true when the problem was successfully reduced, omega_unknown
5002    when the solver is unable to determine an answer.  */
5003
5004 enum omega_result
5005 omega_simplify_problem (omega_pb pb)
5006 {
5007   int i;
5008
5009   omega_found_reduction = omega_false;
5010
5011   if (!pb->variables_initialized)
5012     omega_initialize_variables (pb);
5013
5014   if (next_key * 3 > MAX_KEYS)
5015     {
5016       int e;
5017
5018       hash_version++;
5019       next_key = OMEGA_MAX_VARS + 1;
5020
5021       for (e = pb->num_geqs - 1; e >= 0; e--)
5022         pb->geqs[e].touched = 1;
5023
5024       for (i = 0; i < HASH_TABLE_SIZE; i++)
5025         hash_master[i].touched = -1;
5026
5027       pb->hash_version = hash_version;
5028     }
5029
5030   else if (pb->hash_version != hash_version)
5031     {
5032       int e;
5033
5034       for (e = pb->num_geqs - 1; e >= 0; e--)
5035         pb->geqs[e].touched = 1;
5036
5037       pb->hash_version = hash_version;
5038     }
5039
5040   if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
5041     omega_free_eliminations (pb, pb->safe_vars);
5042
5043   if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
5044     {
5045       omega_found_reduction = omega_solve_problem (pb, omega_unknown);
5046
5047       if (omega_found_reduction != omega_false
5048           && !return_single_result)
5049         {
5050           pb->num_geqs = 0;
5051           pb->num_eqs = 0;
5052           (*omega_when_reduced) (pb);
5053         }
5054
5055       return omega_found_reduction;
5056     }
5057
5058   omega_solve_problem (pb, omega_simplify);
5059
5060   if (omega_found_reduction != omega_false)
5061     {
5062       for (i = 1; omega_safe_var_p (pb, i); i++)
5063         pb->forwarding_address[pb->var[i]] = i;
5064
5065       for (i = 0; i < pb->num_subs; i++)
5066         pb->forwarding_address[pb->subs[i].key] = -i - 1;
5067     }
5068
5069   if (!omega_reduce_with_subs)
5070     gcc_assert (please_no_equalities_in_simplified_problems
5071                 || omega_found_reduction == omega_false
5072                 || pb->num_subs == 0);
5073
5074   return omega_found_reduction;
5075 }
5076
5077 /* Make variable VAR unprotected: it then can be eliminated.  */
5078
5079 void
5080 omega_unprotect_variable (omega_pb pb, int var)
5081 {
5082   int e, idx;
5083   idx = pb->forwarding_address[var];
5084
5085   if (idx < 0)
5086     {
5087       idx = -1 - idx;
5088       pb->num_subs--;
5089
5090       if (idx < pb->num_subs)
5091         {
5092           omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
5093                           pb->num_vars);
5094           pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
5095         }
5096     }
5097   else
5098     {
5099       int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
5100       int e2;
5101
5102       for (e = pb->num_subs - 1; e >= 0; e--)
5103         bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
5104
5105       for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
5106         if (bring_to_life[e2])
5107           {
5108             pb->num_vars++;
5109             pb->safe_vars++;
5110
5111             if (pb->safe_vars < pb->num_vars)
5112               {
5113                 for (e = pb->num_geqs - 1; e >= 0; e--)
5114                   {
5115                     pb->geqs[e].coef[pb->num_vars] =
5116                       pb->geqs[e].coef[pb->safe_vars];
5117
5118                     pb->geqs[e].coef[pb->safe_vars] = 0;
5119                   }
5120
5121                 for (e = pb->num_eqs - 1; e >= 0; e--)
5122                   {
5123                     pb->eqs[e].coef[pb->num_vars] =
5124                       pb->eqs[e].coef[pb->safe_vars];
5125
5126                     pb->eqs[e].coef[pb->safe_vars] = 0;
5127                   }
5128
5129                 for (e = pb->num_subs - 1; e >= 0; e--)
5130                   {
5131                     pb->subs[e].coef[pb->num_vars] =
5132                       pb->subs[e].coef[pb->safe_vars];
5133
5134                     pb->subs[e].coef[pb->safe_vars] = 0;
5135                   }
5136
5137                 pb->var[pb->num_vars] = pb->var[pb->safe_vars];
5138                 pb->forwarding_address[pb->var[pb->num_vars]] =
5139                   pb->num_vars;
5140               }
5141             else
5142               {
5143                 for (e = pb->num_geqs - 1; e >= 0; e--)
5144                   pb->geqs[e].coef[pb->safe_vars] = 0;
5145
5146                 for (e = pb->num_eqs - 1; e >= 0; e--)
5147                   pb->eqs[e].coef[pb->safe_vars] = 0;
5148
5149                 for (e = pb->num_subs - 1; e >= 0; e--)
5150                   pb->subs[e].coef[pb->safe_vars] = 0;
5151               }
5152
5153             pb->var[pb->safe_vars] = pb->subs[e2].key;
5154             pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
5155
5156             omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
5157                             pb->num_vars);
5158             pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
5159             gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5160
5161             if (e2 < pb->num_subs - 1)
5162               omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
5163                               pb->num_vars);
5164
5165             pb->num_subs--;
5166           }
5167
5168       omega_unprotect_1 (pb, &idx, NULL);
5169       free (bring_to_life);
5170     }
5171
5172   chain_unprotect (pb);
5173 }
5174
5175 /* Unprotects VAR and simplifies PB.  */
5176
5177 enum omega_result
5178 omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
5179                                int var, int sign)
5180 {
5181   int n_vars = pb->num_vars;
5182   int e, j;
5183   int k = pb->forwarding_address[var];
5184
5185   if (k < 0)
5186     {
5187       k = -1 - k;
5188
5189       if (sign != 0)
5190         {
5191           e = pb->num_geqs++;
5192           omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
5193
5194           for (j = 0; j <= n_vars; j++)
5195             pb->geqs[e].coef[j] *= sign;
5196
5197           pb->geqs[e].coef[0]--;
5198           pb->geqs[e].touched = 1;
5199           pb->geqs[e].color = color;
5200         }
5201       else
5202         {
5203           e = pb->num_eqs++;
5204           gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5205           omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5206           pb->eqs[e].color = color;
5207         }
5208     }
5209   else if (sign != 0)
5210     {
5211       e = pb->num_geqs++;
5212       omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
5213       pb->geqs[e].coef[k] = sign;
5214       pb->geqs[e].coef[0] = -1;
5215       pb->geqs[e].touched = 1;
5216       pb->geqs[e].color = color;
5217     }
5218   else
5219     {
5220       e = pb->num_eqs++;
5221       gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5222       omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5223       pb->eqs[e].coef[k] = 1;
5224       pb->eqs[e].color = color;
5225     }
5226
5227   omega_unprotect_variable (pb, var);
5228   return omega_simplify_problem (pb);
5229 }
5230
5231 /* Add an equation "VAR = VALUE" with COLOR to PB.  */
5232
5233 void
5234 omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
5235                                 int var, int value)
5236 {
5237   int e;
5238   int k = pb->forwarding_address[var];
5239
5240   if (k < 0)
5241     {
5242       k = -1 - k;
5243       e = pb->num_eqs++;
5244       gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
5245       omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
5246       pb->eqs[e].coef[0] -= value;
5247     }
5248   else
5249     {
5250       e = pb->num_eqs++;
5251       omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
5252       pb->eqs[e].coef[k] = 1;
5253       pb->eqs[e].coef[0] = -value;
5254     }
5255
5256   pb->eqs[e].color = color;
5257 }
5258
5259 /* Return false when the upper and lower bounds are not coupled.
5260    Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
5261    variable I.  */
5262
5263 bool
5264 omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
5265 {
5266   int n_vars = pb->num_vars;
5267   int e, j;
5268   bool is_simple;
5269   bool coupled = false;
5270
5271   *lower_bound = neg_infinity;
5272   *upper_bound = pos_infinity;
5273   i = pb->forwarding_address[i];
5274
5275   if (i < 0)
5276     {
5277       i = -i - 1;
5278
5279       for (j = 1; j <= n_vars; j++)
5280         if (pb->subs[i].coef[j] != 0)
5281           return true;
5282
5283       *upper_bound = *lower_bound = pb->subs[i].coef[0];
5284       return false;
5285     }
5286
5287   for (e = pb->num_subs - 1; e >= 0; e--)
5288     if (pb->subs[e].coef[i] != 0)
5289       coupled = true;
5290
5291   for (e = pb->num_eqs - 1; e >= 0; e--)
5292     if (pb->eqs[e].coef[i] != 0)
5293       {
5294         is_simple = true;
5295
5296         for (j = 1; j <= n_vars; j++)
5297           if (i != j && pb->eqs[e].coef[j] != 0)
5298             {
5299               is_simple = false;
5300               coupled = true;
5301               break;
5302             }
5303
5304         if (!is_simple)
5305           continue;
5306         else
5307           {
5308             *lower_bound = *upper_bound =
5309               -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
5310             return false;
5311           }
5312       }
5313
5314   for (e = pb->num_geqs - 1; e >= 0; e--)
5315     if (pb->geqs[e].coef[i] != 0)
5316       {
5317         if (pb->geqs[e].key == i)
5318           *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
5319
5320         else if (pb->geqs[e].key == -i)
5321           *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
5322
5323         else
5324           coupled = true;
5325       }
5326
5327   return coupled;
5328 }
5329
5330 /* Sets the lower bound L and upper bound U for the values of variable
5331    I, and sets COULD_BE_ZERO to true if variable I might take value
5332    zero.  LOWER_BOUND and UPPER_BOUND are bounds on the values of
5333    variable I.  */
5334
5335 static void
5336 query_coupled_variable (omega_pb pb, int i, int *l, int *u,
5337                         bool *could_be_zero, int lower_bound, int upper_bound)
5338 {
5339   int e, b1, b2;
5340   eqn eqn;
5341   int sign;
5342   int v;
5343
5344   /* Preconditions.  */
5345   gcc_assert (abs (pb->forwarding_address[i]) == 1
5346               && pb->num_vars + pb->num_subs == 2
5347               && pb->num_eqs + pb->num_subs == 1);
5348
5349   /* Define variable I in terms of variable V.  */
5350   if (pb->forwarding_address[i] == -1)
5351     {
5352       eqn = &pb->subs[0];
5353       sign = 1;
5354       v = 1;
5355     }
5356   else
5357     {
5358       eqn = &pb->eqs[0];
5359       sign = -eqn->coef[1];
5360       v = 2;
5361     }
5362
5363   for (e = pb->num_geqs - 1; e >= 0; e--)
5364     if (pb->geqs[e].coef[v] != 0)
5365       {
5366         if (pb->geqs[e].coef[v] == 1)
5367           lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
5368
5369         else
5370           upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
5371       }
5372
5373   if (lower_bound > upper_bound)
5374     {
5375       *l = pos_infinity;
5376       *u = neg_infinity;
5377       *could_be_zero = 0;
5378       return;
5379     }
5380
5381   if (lower_bound == neg_infinity)
5382     {
5383       if (eqn->coef[v] > 0)
5384         b1 = sign * neg_infinity;
5385
5386       else
5387         b1 = -sign * neg_infinity;
5388     }
5389   else
5390     b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
5391
5392   if (upper_bound == pos_infinity)
5393     {
5394       if (eqn->coef[v] > 0)
5395         b2 = sign * pos_infinity;
5396
5397       else
5398         b2 = -sign * pos_infinity;
5399     }
5400   else
5401     b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
5402
5403   *l = MAX (*l, b1 <= b2 ? b1 : b2);
5404   *u = MIN (*u, b1 <= b2 ? b2 : b1);
5405
5406   *could_be_zero = (*l <= 0 && 0 <= *u
5407                     && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
5408 }
5409
5410 /* Return false when a lower bound L and an upper bound U for variable
5411    I in problem PB have been initialized.  */
5412
5413 bool
5414 omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
5415 {
5416   *l = neg_infinity;
5417   *u = pos_infinity;
5418
5419   if (!omega_query_variable (pb, i, l, u)
5420       || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
5421     return false;
5422
5423   if (abs (pb->forwarding_address[i]) == 1
5424       && pb->num_vars + pb->num_subs == 2
5425       && pb->num_eqs + pb->num_subs == 1)
5426     {
5427       bool could_be_zero;
5428       query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
5429                               pos_infinity);
5430       return false;
5431     }
5432
5433   return true;
5434 }
5435
5436 /* For problem PB, return an integer that represents the classic data
5437    dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
5438    masks that are added to the result.  When DIST_KNOWN is true, DIST
5439    is set to the classic data dependence distance.  LOWER_BOUND and
5440    UPPER_BOUND are bounds on the value of variable I, for example, it
5441    is possible to narrow the iteration domain with safe approximations
5442    of loop counts, and thus discard some data dependences that cannot
5443    occur.  */
5444
5445 int
5446 omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
5447                             int dd_eq, int dd_gt, int lower_bound,
5448                             int upper_bound, bool *dist_known, int *dist)
5449 {
5450   int result;
5451   int l, u;
5452   bool could_be_zero;
5453
5454   l = neg_infinity;
5455   u = pos_infinity;
5456
5457   omega_query_variable (pb, i, &l, &u);
5458   query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
5459                           upper_bound);
5460   result = 0;
5461
5462   if (l < 0)
5463     result |= dd_gt;
5464
5465   if (u > 0)
5466     result |= dd_lt;
5467
5468   if (could_be_zero)
5469     result |= dd_eq;
5470
5471   if (l == u)
5472     {
5473       *dist_known = true;
5474       *dist = l;
5475     }
5476   else
5477     *dist_known = false;
5478
5479   return result;
5480 }
5481
5482 /* Initialize PB as an Omega problem with NVARS variables and NPROT
5483    safe variables.  Safe variables are not eliminated during the
5484    Fourier-Motzkin elimination.  Safe variables are all those
5485    variables that are placed at the beginning of the array of
5486    variables: P->var[0, ..., NPROT - 1].  */
5487
5488 omega_pb
5489 omega_alloc_problem (int nvars, int nprot)
5490 {
5491   omega_pb pb;
5492
5493   gcc_assert (nvars <= OMEGA_MAX_VARS);
5494   omega_initialize ();
5495
5496   /* Allocate and initialize PB.  */
5497   pb = XCNEW (struct omega_pb_d);
5498   pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5499   pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
5500   pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
5501   pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
5502   pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
5503
5504   pb->hash_version = hash_version;
5505   pb->num_vars = nvars;
5506   pb->safe_vars = nprot;
5507   pb->variables_initialized = false;
5508   pb->variables_freed = false;
5509   pb->num_eqs = 0;
5510   pb->num_geqs = 0;
5511   pb->num_subs = 0;
5512   return pb;
5513 }
5514
5515 /* Keeps the state of the initialization.  */
5516 static bool omega_initialized = false;
5517
5518 /* Initialization of the Omega solver.  */
5519
5520 void
5521 omega_initialize (void)
5522 {
5523   int i;
5524
5525   if (omega_initialized)
5526     return;
5527
5528   next_wild_card = 0;
5529   next_key = OMEGA_MAX_VARS + 1;
5530   packing = XCNEWVEC (int, OMEGA_MAX_VARS);
5531   fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
5532   fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
5533   hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
5534
5535   for (i = 0; i < HASH_TABLE_SIZE; i++)
5536     hash_master[i].touched = -1;
5537
5538   sprintf (wild_name[0], "1");
5539   sprintf (wild_name[1], "a");
5540   sprintf (wild_name[2], "b");
5541   sprintf (wild_name[3], "c");
5542   sprintf (wild_name[4], "d");
5543   sprintf (wild_name[5], "e");
5544   sprintf (wild_name[6], "f");
5545   sprintf (wild_name[7], "g");
5546   sprintf (wild_name[8], "h");
5547   sprintf (wild_name[9], "i");
5548   sprintf (wild_name[10], "j");
5549   sprintf (wild_name[11], "k");
5550   sprintf (wild_name[12], "l");
5551   sprintf (wild_name[13], "m");
5552   sprintf (wild_name[14], "n");
5553   sprintf (wild_name[15], "o");
5554   sprintf (wild_name[16], "p");
5555   sprintf (wild_name[17], "q");
5556   sprintf (wild_name[18], "r");
5557   sprintf (wild_name[19], "s");
5558   sprintf (wild_name[20], "t");
5559   sprintf (wild_name[40 - 1], "alpha");
5560   sprintf (wild_name[40 - 2], "beta");
5561   sprintf (wild_name[40 - 3], "gamma");
5562   sprintf (wild_name[40 - 4], "delta");
5563   sprintf (wild_name[40 - 5], "tau");
5564   sprintf (wild_name[40 - 6], "sigma");
5565   sprintf (wild_name[40 - 7], "chi");
5566   sprintf (wild_name[40 - 8], "omega");
5567   sprintf (wild_name[40 - 9], "pi");
5568   sprintf (wild_name[40 - 10], "ni");
5569   sprintf (wild_name[40 - 11], "Alpha");
5570   sprintf (wild_name[40 - 12], "Beta");
5571   sprintf (wild_name[40 - 13], "Gamma");
5572   sprintf (wild_name[40 - 14], "Delta");
5573   sprintf (wild_name[40 - 15], "Tau");
5574   sprintf (wild_name[40 - 16], "Sigma");
5575   sprintf (wild_name[40 - 17], "Chi");
5576   sprintf (wild_name[40 - 18], "Omega");
5577   sprintf (wild_name[40 - 19], "xxx");
5578
5579   omega_initialized = true;
5580 }