OSDN Git Service

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