xref: /dragonfly/contrib/gcc-4.7/gcc/omega.h (revision e4b17023)
1*e4b17023SJohn Marino /* Source code for an implementation of the Omega test, an integer
2*e4b17023SJohn Marino    programming algorithm for dependence analysis, by William Pugh,
3*e4b17023SJohn Marino    appeared in Supercomputing '91 and CACM Aug 92.
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino    This code has no license restrictions, and is considered public
6*e4b17023SJohn Marino    domain.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino    Changes copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
9*e4b17023SJohn Marino    Contributed by Sebastian Pop <sebastian.pop@inria.fr>
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino This file is part of GCC.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
14*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
15*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
16*e4b17023SJohn Marino version.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
19*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
20*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21*e4b17023SJohn Marino for more details.
22*e4b17023SJohn Marino 
23*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
24*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
25*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
26*e4b17023SJohn Marino 
27*e4b17023SJohn Marino #include "config.h"
28*e4b17023SJohn Marino #include "params.h"
29*e4b17023SJohn Marino 
30*e4b17023SJohn Marino #ifndef GCC_OMEGA_H
31*e4b17023SJohn Marino #define GCC_OMEGA_H
32*e4b17023SJohn Marino 
33*e4b17023SJohn Marino #define OMEGA_MAX_VARS PARAM_VALUE (PARAM_OMEGA_MAX_VARS)
34*e4b17023SJohn Marino #define OMEGA_MAX_GEQS PARAM_VALUE (PARAM_OMEGA_MAX_GEQS)
35*e4b17023SJohn Marino #define OMEGA_MAX_EQS PARAM_VALUE (PARAM_OMEGA_MAX_EQS)
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino #define pos_infinity (0x7ffffff)
38*e4b17023SJohn Marino #define neg_infinity (-0x7ffffff)
39*e4b17023SJohn Marino 
40*e4b17023SJohn Marino /* Results of the Omega solver.  */
41*e4b17023SJohn Marino enum omega_result {
42*e4b17023SJohn Marino   omega_false = 0,
43*e4b17023SJohn Marino   omega_true = 1,
44*e4b17023SJohn Marino 
45*e4b17023SJohn Marino   /* Value returned when the solver is unable to determine an
46*e4b17023SJohn Marino      answer.  */
47*e4b17023SJohn Marino   omega_unknown = 2,
48*e4b17023SJohn Marino 
49*e4b17023SJohn Marino   /* Value used for asking the solver to simplify the system.  */
50*e4b17023SJohn Marino   omega_simplify = 3
51*e4b17023SJohn Marino };
52*e4b17023SJohn Marino 
53*e4b17023SJohn Marino /* Values used for labeling equations.  Private (not used outside the
54*e4b17023SJohn Marino    solver).  */
55*e4b17023SJohn Marino enum omega_eqn_color {
56*e4b17023SJohn Marino   omega_black = 0,
57*e4b17023SJohn Marino   omega_red = 1
58*e4b17023SJohn Marino };
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino /* Structure for equations.  */
61*e4b17023SJohn Marino typedef struct eqn_d
62*e4b17023SJohn Marino {
63*e4b17023SJohn Marino   int key;
64*e4b17023SJohn Marino   int touched;
65*e4b17023SJohn Marino   enum omega_eqn_color color;
66*e4b17023SJohn Marino 
67*e4b17023SJohn Marino   /* Array of coefficients for the equation.  The layout of the data
68*e4b17023SJohn Marino      is as follows: coef[0] is the constant, coef[i] for 1 <= i <=
69*e4b17023SJohn Marino      OMEGA_MAX_VARS, are the coefficients for each dimension.  Examples:
70*e4b17023SJohn Marino      the equation 0 = 9 + x + 0y + 5z is encoded as [9 1 0 5], the
71*e4b17023SJohn Marino      inequality 0 <= -8 + x + 2y + 3z is encoded as [-8 1 2 3].  */
72*e4b17023SJohn Marino   int *coef;
73*e4b17023SJohn Marino } *eqn;
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino typedef struct omega_pb_d
76*e4b17023SJohn Marino {
77*e4b17023SJohn Marino   /* The number of variables in the system of equations.  */
78*e4b17023SJohn Marino   int num_vars;
79*e4b17023SJohn Marino 
80*e4b17023SJohn Marino   /* Safe variables are not eliminated during the Fourier-Motzkin
81*e4b17023SJohn Marino      simplification of the system.  Safe variables are all those
82*e4b17023SJohn Marino      variables that are placed at the beginning of the array of
83*e4b17023SJohn Marino      variables: PB->var[1, ..., SAFE_VARS].  PB->var[0] is not used,
84*e4b17023SJohn Marino      as PB->eqs[x]->coef[0] represents the constant of the equation.  */
85*e4b17023SJohn Marino   int safe_vars;
86*e4b17023SJohn Marino 
87*e4b17023SJohn Marino   /* Number of elements in eqs[].  */
88*e4b17023SJohn Marino   int num_eqs;
89*e4b17023SJohn Marino   /* Number of elements in geqs[].  */
90*e4b17023SJohn Marino   int num_geqs;
91*e4b17023SJohn Marino   /* Number of elements in subs[].  */
92*e4b17023SJohn Marino   int num_subs;
93*e4b17023SJohn Marino 
94*e4b17023SJohn Marino   int hash_version;
95*e4b17023SJohn Marino   bool variables_initialized;
96*e4b17023SJohn Marino   bool variables_freed;
97*e4b17023SJohn Marino 
98*e4b17023SJohn Marino   /* Index or name of variables.  Negative integers are reserved for
99*e4b17023SJohn Marino      wildcard variables.  Maps the index of variables in the original
100*e4b17023SJohn Marino      problem to the new index of the variable.  The index for a
101*e4b17023SJohn Marino      variable in the coef array of an equation can change as some
102*e4b17023SJohn Marino      variables are eliminated.  */
103*e4b17023SJohn Marino   int *var;
104*e4b17023SJohn Marino 
105*e4b17023SJohn Marino   int *forwarding_address;
106*e4b17023SJohn Marino 
107*e4b17023SJohn Marino   /* Inequalities in the system of constraints.  */
108*e4b17023SJohn Marino   eqn geqs;
109*e4b17023SJohn Marino 
110*e4b17023SJohn Marino   /* Equations in the system of constraints.  */
111*e4b17023SJohn Marino   eqn eqs;
112*e4b17023SJohn Marino 
113*e4b17023SJohn Marino   /* A map of substituted variables.  */
114*e4b17023SJohn Marino   eqn subs;
115*e4b17023SJohn Marino } *omega_pb;
116*e4b17023SJohn Marino 
117*e4b17023SJohn Marino extern void omega_initialize (void);
118*e4b17023SJohn Marino extern omega_pb omega_alloc_problem (int, int);
119*e4b17023SJohn Marino extern enum omega_result omega_solve_problem (omega_pb, enum omega_result);
120*e4b17023SJohn Marino extern enum omega_result omega_simplify_problem (omega_pb);
121*e4b17023SJohn Marino extern enum omega_result omega_simplify_approximate (omega_pb);
122*e4b17023SJohn Marino extern enum omega_result omega_constrain_variable_sign (omega_pb,
123*e4b17023SJohn Marino 							enum omega_eqn_color,
124*e4b17023SJohn Marino 							int, int);
125*e4b17023SJohn Marino extern void debug_omega_problem (omega_pb);
126*e4b17023SJohn Marino extern void omega_print_problem (FILE *, omega_pb);
127*e4b17023SJohn Marino extern void omega_print_red_equations (FILE *, omega_pb);
128*e4b17023SJohn Marino extern int omega_count_red_equations (omega_pb);
129*e4b17023SJohn Marino extern void omega_pretty_print_problem (FILE *, omega_pb);
130*e4b17023SJohn Marino extern void omega_unprotect_variable (omega_pb, int var);
131*e4b17023SJohn Marino extern void omega_negate_geq (omega_pb, int);
132*e4b17023SJohn Marino extern void omega_convert_eq_to_geqs (omega_pb, int eq);
133*e4b17023SJohn Marino extern void omega_print_eqn (FILE *, omega_pb, eqn, bool, int);
134*e4b17023SJohn Marino extern bool omega_problem_has_red_equations (omega_pb);
135*e4b17023SJohn Marino extern enum omega_result omega_eliminate_redundant (omega_pb, bool);
136*e4b17023SJohn Marino extern void omega_eliminate_red (omega_pb, bool);
137*e4b17023SJohn Marino extern void omega_constrain_variable_value (omega_pb, enum omega_eqn_color,
138*e4b17023SJohn Marino 					    int, int);
139*e4b17023SJohn Marino extern bool omega_query_variable (omega_pb, int, int *, int *);
140*e4b17023SJohn Marino extern int omega_query_variable_signs (omega_pb, int, int, int, int,
141*e4b17023SJohn Marino 				       int, int, bool *, int *);
142*e4b17023SJohn Marino extern bool omega_query_variable_bounds (omega_pb, int, int *, int *);
143*e4b17023SJohn Marino extern void (*omega_when_reduced) (omega_pb);
144*e4b17023SJohn Marino extern void omega_no_procedure (omega_pb);
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino /* Return true when variable I in problem PB is a wildcard.  */
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino static inline bool
omega_wildcard_p(omega_pb pb,int i)149*e4b17023SJohn Marino omega_wildcard_p (omega_pb pb, int i)
150*e4b17023SJohn Marino {
151*e4b17023SJohn Marino   return (pb->var[i] < 0);
152*e4b17023SJohn Marino }
153*e4b17023SJohn Marino 
154*e4b17023SJohn Marino /* Return true when variable I in problem PB is a safe variable.  */
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino static inline bool
omega_safe_var_p(omega_pb pb,int i)157*e4b17023SJohn Marino omega_safe_var_p (omega_pb pb, int i)
158*e4b17023SJohn Marino {
159*e4b17023SJohn Marino   /* The constant of an equation is not a variable.  */
160*e4b17023SJohn Marino   gcc_assert (0 < i);
161*e4b17023SJohn Marino   return (i <= pb->safe_vars);
162*e4b17023SJohn Marino }
163*e4b17023SJohn Marino 
164*e4b17023SJohn Marino /* Print to FILE equality E from PB.  */
165*e4b17023SJohn Marino 
166*e4b17023SJohn Marino static inline void
omega_print_eq(FILE * file,omega_pb pb,eqn e)167*e4b17023SJohn Marino omega_print_eq (FILE *file, omega_pb pb, eqn e)
168*e4b17023SJohn Marino {
169*e4b17023SJohn Marino   omega_print_eqn (file, pb, e, false, 0);
170*e4b17023SJohn Marino }
171*e4b17023SJohn Marino 
172*e4b17023SJohn Marino /* Print to FILE inequality E from PB.  */
173*e4b17023SJohn Marino 
174*e4b17023SJohn Marino static inline void
omega_print_geq(FILE * file,omega_pb pb,eqn e)175*e4b17023SJohn Marino omega_print_geq (FILE *file, omega_pb pb, eqn e)
176*e4b17023SJohn Marino {
177*e4b17023SJohn Marino   omega_print_eqn (file, pb, e, true, 0);
178*e4b17023SJohn Marino }
179*e4b17023SJohn Marino 
180*e4b17023SJohn Marino /* Print to FILE inequality E from PB.  */
181*e4b17023SJohn Marino 
182*e4b17023SJohn Marino static inline void
omega_print_geq_extra(FILE * file,omega_pb pb,eqn e)183*e4b17023SJohn Marino omega_print_geq_extra (FILE *file, omega_pb pb, eqn e)
184*e4b17023SJohn Marino {
185*e4b17023SJohn Marino   omega_print_eqn (file, pb, e, true, 1);
186*e4b17023SJohn Marino }
187*e4b17023SJohn Marino 
188*e4b17023SJohn Marino /* E1 = E2, make a copy of E2 into E1.  Equations contain S variables.  */
189*e4b17023SJohn Marino 
190*e4b17023SJohn Marino static inline void
omega_copy_eqn(eqn e1,eqn e2,int s)191*e4b17023SJohn Marino omega_copy_eqn (eqn e1, eqn e2, int s)
192*e4b17023SJohn Marino {
193*e4b17023SJohn Marino   e1->key = e2->key;
194*e4b17023SJohn Marino   e1->touched = e2->touched;
195*e4b17023SJohn Marino   e1->color = e2->color;
196*e4b17023SJohn Marino 
197*e4b17023SJohn Marino   memcpy (e1->coef, e2->coef, (s + 1) * sizeof (int));
198*e4b17023SJohn Marino }
199*e4b17023SJohn Marino 
200*e4b17023SJohn Marino /* Initialize E = 0.  Equation E contains S variables.  */
201*e4b17023SJohn Marino 
202*e4b17023SJohn Marino static inline void
omega_init_eqn_zero(eqn e,int s)203*e4b17023SJohn Marino omega_init_eqn_zero (eqn e, int s)
204*e4b17023SJohn Marino {
205*e4b17023SJohn Marino   e->key = 0;
206*e4b17023SJohn Marino   e->touched = 0;
207*e4b17023SJohn Marino   e->color = omega_black;
208*e4b17023SJohn Marino 
209*e4b17023SJohn Marino   memset (e->coef, 0, (s + 1) * sizeof (int));
210*e4b17023SJohn Marino }
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino /* Allocate N equations with S variables.  */
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino static inline eqn
omega_alloc_eqns(int s,int n)215*e4b17023SJohn Marino omega_alloc_eqns (int s, int n)
216*e4b17023SJohn Marino {
217*e4b17023SJohn Marino   int i;
218*e4b17023SJohn Marino   eqn res = (eqn) (xcalloc (n, sizeof (struct eqn_d)));
219*e4b17023SJohn Marino 
220*e4b17023SJohn Marino   for (i = n - 1; i >= 0; i--)
221*e4b17023SJohn Marino     {
222*e4b17023SJohn Marino       res[i].coef = (int *) (xcalloc (OMEGA_MAX_VARS + 1, sizeof (int)));
223*e4b17023SJohn Marino       omega_init_eqn_zero (&res[i], s);
224*e4b17023SJohn Marino     }
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino   return res;
227*e4b17023SJohn Marino }
228*e4b17023SJohn Marino 
229*e4b17023SJohn Marino /* Free N equations from array EQ.  */
230*e4b17023SJohn Marino 
231*e4b17023SJohn Marino static inline void
omega_free_eqns(eqn eq,int n)232*e4b17023SJohn Marino omega_free_eqns (eqn eq, int n)
233*e4b17023SJohn Marino {
234*e4b17023SJohn Marino   int i;
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino   for (i = n - 1; i >= 0; i--)
237*e4b17023SJohn Marino     free (eq[i].coef);
238*e4b17023SJohn Marino 
239*e4b17023SJohn Marino   free (eq);
240*e4b17023SJohn Marino }
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino /* Returns true when E is an inequality with a single variable.  */
243*e4b17023SJohn Marino 
244*e4b17023SJohn Marino static inline bool
single_var_geq(eqn e,int nv ATTRIBUTE_UNUSED)245*e4b17023SJohn Marino single_var_geq (eqn e, int nv ATTRIBUTE_UNUSED)
246*e4b17023SJohn Marino {
247*e4b17023SJohn Marino   return (e->key != 0
248*e4b17023SJohn Marino 	  && -OMEGA_MAX_VARS <= e->key && e->key <= OMEGA_MAX_VARS);
249*e4b17023SJohn Marino }
250*e4b17023SJohn Marino 
251*e4b17023SJohn Marino /* Allocate a new equality with all coefficients 0, and tagged with
252*e4b17023SJohn Marino    COLOR.  Return the index of this equality in problem PB.  */
253*e4b17023SJohn Marino 
254*e4b17023SJohn Marino static inline int
omega_add_zero_eq(omega_pb pb,enum omega_eqn_color color)255*e4b17023SJohn Marino omega_add_zero_eq (omega_pb pb, enum omega_eqn_color color)
256*e4b17023SJohn Marino {
257*e4b17023SJohn Marino   int idx = pb->num_eqs++;
258*e4b17023SJohn Marino 
259*e4b17023SJohn Marino   gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
260*e4b17023SJohn Marino   omega_init_eqn_zero (&pb->eqs[idx], pb->num_vars);
261*e4b17023SJohn Marino   pb->eqs[idx].color = color;
262*e4b17023SJohn Marino   return idx;
263*e4b17023SJohn Marino }
264*e4b17023SJohn Marino 
265*e4b17023SJohn Marino /* Allocate a new inequality with all coefficients 0, and tagged with
266*e4b17023SJohn Marino    COLOR.  Return the index of this inequality in problem PB.  */
267*e4b17023SJohn Marino 
268*e4b17023SJohn Marino static inline int
omega_add_zero_geq(omega_pb pb,enum omega_eqn_color color)269*e4b17023SJohn Marino omega_add_zero_geq (omega_pb pb, enum omega_eqn_color color)
270*e4b17023SJohn Marino {
271*e4b17023SJohn Marino   int idx = pb->num_geqs;
272*e4b17023SJohn Marino 
273*e4b17023SJohn Marino   pb->num_geqs++;
274*e4b17023SJohn Marino   gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
275*e4b17023SJohn Marino   omega_init_eqn_zero (&pb->geqs[idx], pb->num_vars);
276*e4b17023SJohn Marino   pb->geqs[idx].touched = 1;
277*e4b17023SJohn Marino   pb->geqs[idx].color = color;
278*e4b17023SJohn Marino   return idx;
279*e4b17023SJohn Marino }
280*e4b17023SJohn Marino 
281*e4b17023SJohn Marino /* Initialize variables for problem PB.  */
282*e4b17023SJohn Marino 
283*e4b17023SJohn Marino static inline void
omega_initialize_variables(omega_pb pb)284*e4b17023SJohn Marino omega_initialize_variables (omega_pb pb)
285*e4b17023SJohn Marino {
286*e4b17023SJohn Marino   int i;
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino   for (i = pb->num_vars; i >= 0; i--)
289*e4b17023SJohn Marino     pb->forwarding_address[i] = pb->var[i] = i;
290*e4b17023SJohn Marino 
291*e4b17023SJohn Marino   pb->variables_initialized = true;
292*e4b17023SJohn Marino }
293*e4b17023SJohn Marino 
294*e4b17023SJohn Marino /* Free problem PB.  */
295*e4b17023SJohn Marino 
296*e4b17023SJohn Marino static inline void
omega_free_problem(omega_pb pb)297*e4b17023SJohn Marino omega_free_problem (omega_pb pb)
298*e4b17023SJohn Marino {
299*e4b17023SJohn Marino   free (pb->var);
300*e4b17023SJohn Marino   free (pb->forwarding_address);
301*e4b17023SJohn Marino   omega_free_eqns (pb->geqs, OMEGA_MAX_GEQS);
302*e4b17023SJohn Marino   omega_free_eqns (pb->eqs, OMEGA_MAX_EQS);
303*e4b17023SJohn Marino   omega_free_eqns (pb->subs, OMEGA_MAX_VARS + 1);
304*e4b17023SJohn Marino   free (pb);
305*e4b17023SJohn Marino }
306*e4b17023SJohn Marino 
307*e4b17023SJohn Marino /* Copy omega problems: P1 = P2.  */
308*e4b17023SJohn Marino 
309*e4b17023SJohn Marino static inline void
omega_copy_problem(omega_pb p1,omega_pb p2)310*e4b17023SJohn Marino omega_copy_problem (omega_pb p1, omega_pb p2)
311*e4b17023SJohn Marino {
312*e4b17023SJohn Marino   int e, i;
313*e4b17023SJohn Marino 
314*e4b17023SJohn Marino   p1->num_vars = p2->num_vars;
315*e4b17023SJohn Marino   p1->hash_version = p2->hash_version;
316*e4b17023SJohn Marino   p1->variables_initialized = p2->variables_initialized;
317*e4b17023SJohn Marino   p1->variables_freed = p2->variables_freed;
318*e4b17023SJohn Marino   p1->safe_vars = p2->safe_vars;
319*e4b17023SJohn Marino   p1->num_eqs = p2->num_eqs;
320*e4b17023SJohn Marino   p1->num_subs = p2->num_subs;
321*e4b17023SJohn Marino   p1->num_geqs = p2->num_geqs;
322*e4b17023SJohn Marino 
323*e4b17023SJohn Marino   for (e = p2->num_eqs - 1; e >= 0; e--)
324*e4b17023SJohn Marino     omega_copy_eqn (&(p1->eqs[e]), &(p2->eqs[e]), p2->num_vars);
325*e4b17023SJohn Marino 
326*e4b17023SJohn Marino   for (e = p2->num_geqs - 1; e >= 0; e--)
327*e4b17023SJohn Marino     omega_copy_eqn (&(p1->geqs[e]), &(p2->geqs[e]), p2->num_vars);
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino   for (e = p2->num_subs - 1; e >= 0; e--)
330*e4b17023SJohn Marino     omega_copy_eqn (&(p1->subs[e]), &(p2->subs[e]), p2->num_vars);
331*e4b17023SJohn Marino 
332*e4b17023SJohn Marino   for (i = p2->num_vars; i >= 0; i--)
333*e4b17023SJohn Marino     p1->var[i] = p2->var[i];
334*e4b17023SJohn Marino 
335*e4b17023SJohn Marino   for (i = OMEGA_MAX_VARS; i >= 0; i--)
336*e4b17023SJohn Marino     p1->forwarding_address[i] = p2->forwarding_address[i];
337*e4b17023SJohn Marino }
338*e4b17023SJohn Marino 
339*e4b17023SJohn Marino #endif /* GCC_OMEGA_H */
340