OSDN Git Service

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