OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [omega.c] - Blame information for rev 778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.