1/* Lambda matrix and vector interface.
2   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3   Contributed by Daniel Berlin <dberlin@dberlin.org>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301, USA.  */
21
22#ifndef LAMBDA_H
23#define LAMBDA_H
24
25#include "vec.h"
26
27/* An integer vector.  A vector formally consists of an element of a vector
28   space. A vector space is a set that is closed under vector addition
29   and scalar multiplication.  In this vector space, an element is a list of
30   integers.  */
31typedef int *lambda_vector;
32
33DEF_VEC_P(lambda_vector);
34DEF_VEC_ALLOC_P(lambda_vector,heap);
35
36/* An integer matrix.  A matrix consists of m vectors of length n (IE
37   all vectors are the same length).  */
38typedef lambda_vector *lambda_matrix;
39
40/* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE
41   matrix.  Rather than use floats, we simply keep a single DENOMINATOR that
42   represents the denominator for every element in the matrix.  */
43typedef struct
44{
45  lambda_matrix matrix;
46  int rowsize;
47  int colsize;
48  int denominator;
49} *lambda_trans_matrix;
50#define LTM_MATRIX(T) ((T)->matrix)
51#define LTM_ROWSIZE(T) ((T)->rowsize)
52#define LTM_COLSIZE(T) ((T)->colsize)
53#define LTM_DENOMINATOR(T) ((T)->denominator)
54
55/* A vector representing a statement in the body of a loop.
56   The COEFFICIENTS vector contains a coefficient for each induction variable
57   in the loop nest containing the statement.
58   The DENOMINATOR represents the denominator for each coefficient in the
59   COEFFICIENT vector.
60
61   This structure is used during code generation in order to rewrite the old
62   induction variable uses in a statement in terms of the newly created
63   induction variables.  */
64typedef struct
65{
66  lambda_vector coefficients;
67  int size;
68  int denominator;
69} *lambda_body_vector;
70#define LBV_COEFFICIENTS(T) ((T)->coefficients)
71#define LBV_SIZE(T) ((T)->size)
72#define LBV_DENOMINATOR(T) ((T)->denominator)
73
74/* Piecewise linear expression.
75   This structure represents a linear expression with terms for the invariants
76   and induction variables of a loop.
77   COEFFICIENTS is a vector of coefficients for the induction variables, one
78   per loop in the loop nest.
79   CONSTANT is the constant portion of the linear expression
80   INVARIANT_COEFFICIENTS is a vector of coefficients for the loop invariants,
81   one per invariant.
82   DENOMINATOR is the denominator for all of the coefficients and constants in
83   the expression.
84   The linear expressions can be linked together using the NEXT field, in
85   order to represent MAX or MIN of a group of linear expressions.  */
86typedef struct lambda_linear_expression_s
87{
88  lambda_vector coefficients;
89  int constant;
90  lambda_vector invariant_coefficients;
91  int denominator;
92  struct lambda_linear_expression_s *next;
93} *lambda_linear_expression;
94
95#define LLE_COEFFICIENTS(T) ((T)->coefficients)
96#define LLE_CONSTANT(T) ((T)->constant)
97#define LLE_INVARIANT_COEFFICIENTS(T) ((T)->invariant_coefficients)
98#define LLE_DENOMINATOR(T) ((T)->denominator)
99#define LLE_NEXT(T) ((T)->next)
100
101lambda_linear_expression lambda_linear_expression_new (int, int);
102void print_lambda_linear_expression (FILE *, lambda_linear_expression, int,
103				     int, char);
104
105/* Loop structure.  Our loop structure consists of a constant representing the
106   STEP of the loop, a set of linear expressions representing the LOWER_BOUND
107   of the loop, a set of linear expressions representing the UPPER_BOUND of
108   the loop, and a set of linear expressions representing the LINEAR_OFFSET of
109   the loop.  The linear offset is a set of linear expressions that are
110   applied to *both* the lower bound, and the upper bound.  */
111typedef struct lambda_loop_s
112{
113  lambda_linear_expression lower_bound;
114  lambda_linear_expression upper_bound;
115  lambda_linear_expression linear_offset;
116  int step;
117} *lambda_loop;
118
119#define LL_LOWER_BOUND(T) ((T)->lower_bound)
120#define LL_UPPER_BOUND(T) ((T)->upper_bound)
121#define LL_LINEAR_OFFSET(T) ((T)->linear_offset)
122#define LL_STEP(T)   ((T)->step)
123
124/* Loop nest structure.
125   The loop nest structure consists of a set of loop structures (defined
126   above) in LOOPS, along with an integer representing the DEPTH of the loop,
127   and an integer representing the number of INVARIANTS in the loop.  Both of
128   these integers are used to size the associated coefficient vectors in the
129   linear expression structures.  */
130typedef struct
131{
132  lambda_loop *loops;
133  int depth;
134  int invariants;
135} *lambda_loopnest;
136
137#define LN_LOOPS(T) ((T)->loops)
138#define LN_DEPTH(T) ((T)->depth)
139#define LN_INVARIANTS(T) ((T)->invariants)
140
141lambda_loopnest lambda_loopnest_new (int, int);
142lambda_loopnest lambda_loopnest_transform (lambda_loopnest, lambda_trans_matrix);
143struct loop;
144struct loops;
145bool perfect_nest_p (struct loop *);
146void print_lambda_loopnest (FILE *, lambda_loopnest, char);
147
148#define lambda_loop_new() (lambda_loop) ggc_alloc_cleared (sizeof (struct lambda_loop_s))
149
150void print_lambda_loop (FILE *, lambda_loop, int, int, char);
151
152lambda_matrix lambda_matrix_new (int, int);
153
154void lambda_matrix_id (lambda_matrix, int);
155bool lambda_matrix_id_p (lambda_matrix, int);
156void lambda_matrix_copy (lambda_matrix, lambda_matrix, int, int);
157void lambda_matrix_negate (lambda_matrix, lambda_matrix, int, int);
158void lambda_matrix_transpose (lambda_matrix, lambda_matrix, int, int);
159void lambda_matrix_add (lambda_matrix, lambda_matrix, lambda_matrix, int,
160			int);
161void lambda_matrix_add_mc (lambda_matrix, int, lambda_matrix, int,
162			   lambda_matrix, int, int);
163void lambda_matrix_mult (lambda_matrix, lambda_matrix, lambda_matrix,
164			 int, int, int);
165void lambda_matrix_delete_rows (lambda_matrix, int, int, int);
166void lambda_matrix_row_exchange (lambda_matrix, int, int);
167void lambda_matrix_row_add (lambda_matrix, int, int, int, int);
168void lambda_matrix_row_negate (lambda_matrix mat, int, int);
169void lambda_matrix_row_mc (lambda_matrix, int, int, int);
170void lambda_matrix_col_exchange (lambda_matrix, int, int, int);
171void lambda_matrix_col_add (lambda_matrix, int, int, int, int);
172void lambda_matrix_col_negate (lambda_matrix, int, int);
173void lambda_matrix_col_mc (lambda_matrix, int, int, int);
174int lambda_matrix_inverse (lambda_matrix, lambda_matrix, int);
175void lambda_matrix_hermite (lambda_matrix, int, lambda_matrix, lambda_matrix);
176void lambda_matrix_left_hermite (lambda_matrix, int, int, lambda_matrix, lambda_matrix);
177void lambda_matrix_right_hermite (lambda_matrix, int, int, lambda_matrix, lambda_matrix);
178int lambda_matrix_first_nz_vec (lambda_matrix, int, int, int);
179void lambda_matrix_project_to_null (lambda_matrix, int, int, int,
180				    lambda_vector);
181void print_lambda_matrix (FILE *, lambda_matrix, int, int);
182
183lambda_trans_matrix lambda_trans_matrix_new (int, int);
184bool lambda_trans_matrix_nonsingular_p (lambda_trans_matrix);
185bool lambda_trans_matrix_fullrank_p (lambda_trans_matrix);
186int lambda_trans_matrix_rank (lambda_trans_matrix);
187lambda_trans_matrix lambda_trans_matrix_basis (lambda_trans_matrix);
188lambda_trans_matrix lambda_trans_matrix_padding (lambda_trans_matrix);
189lambda_trans_matrix lambda_trans_matrix_inverse (lambda_trans_matrix);
190void print_lambda_trans_matrix (FILE *, lambda_trans_matrix);
191void lambda_matrix_vector_mult (lambda_matrix, int, int, lambda_vector,
192				lambda_vector);
193bool lambda_trans_matrix_id_p (lambda_trans_matrix);
194
195lambda_body_vector lambda_body_vector_new (int);
196lambda_body_vector lambda_body_vector_compute_new (lambda_trans_matrix,
197						   lambda_body_vector);
198void print_lambda_body_vector (FILE *, lambda_body_vector);
199lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loops *,
200						 struct loop *,
201						 VEC(tree,heap) **,
202						 VEC(tree,heap) **);
203void lambda_loopnest_to_gcc_loopnest (struct loop *,
204				      VEC(tree,heap) *, VEC(tree,heap) *,
205				      lambda_loopnest, lambda_trans_matrix);
206
207
208static inline void lambda_vector_negate (lambda_vector, lambda_vector, int);
209static inline void lambda_vector_mult_const (lambda_vector, lambda_vector, int, int);
210static inline void lambda_vector_add (lambda_vector, lambda_vector,
211				      lambda_vector, int);
212static inline void lambda_vector_add_mc (lambda_vector, int, lambda_vector, int,
213					 lambda_vector, int);
214static inline void lambda_vector_copy (lambda_vector, lambda_vector, int);
215static inline bool lambda_vector_zerop (lambda_vector, int);
216static inline void lambda_vector_clear (lambda_vector, int);
217static inline bool lambda_vector_equal (lambda_vector, lambda_vector, int);
218static inline int lambda_vector_min_nz (lambda_vector, int, int);
219static inline int lambda_vector_first_nz (lambda_vector, int, int);
220static inline void print_lambda_vector (FILE *, lambda_vector, int);
221
222/* Allocate a new vector of given SIZE.  */
223
224static inline lambda_vector
225lambda_vector_new (int size)
226{
227  return GGC_CNEWVEC (int, size);
228}
229
230
231
232/* Multiply vector VEC1 of length SIZE by a constant CONST1,
233   and store the result in VEC2.  */
234
235static inline void
236lambda_vector_mult_const (lambda_vector vec1, lambda_vector vec2,
237			  int size, int const1)
238{
239  int i;
240
241  if (const1 == 0)
242    lambda_vector_clear (vec2, size);
243  else
244    for (i = 0; i < size; i++)
245      vec2[i] = const1 * vec1[i];
246}
247
248/* Negate vector VEC1 with length SIZE and store it in VEC2.  */
249
250static inline void
251lambda_vector_negate (lambda_vector vec1, lambda_vector vec2,
252		      int size)
253{
254  lambda_vector_mult_const (vec1, vec2, size, -1);
255}
256
257/* VEC3 = VEC1+VEC2, where all three the vectors are of length SIZE.  */
258
259static inline void
260lambda_vector_add (lambda_vector vec1, lambda_vector vec2,
261		   lambda_vector vec3, int size)
262{
263  int i;
264  for (i = 0; i < size; i++)
265    vec3[i] = vec1[i] + vec2[i];
266}
267
268/* VEC3 = CONSTANT1*VEC1 + CONSTANT2*VEC2.  All vectors have length SIZE.  */
269
270static inline void
271lambda_vector_add_mc (lambda_vector vec1, int const1,
272		      lambda_vector vec2, int const2,
273		      lambda_vector vec3, int size)
274{
275  int i;
276  for (i = 0; i < size; i++)
277    vec3[i] = const1 * vec1[i] + const2 * vec2[i];
278}
279
280/* Copy the elements of vector VEC1 with length SIZE to VEC2.  */
281
282static inline void
283lambda_vector_copy (lambda_vector vec1, lambda_vector vec2,
284		    int size)
285{
286  memcpy (vec2, vec1, size * sizeof (*vec1));
287}
288
289/* Return true if vector VEC1 of length SIZE is the zero vector.  */
290
291static inline bool
292lambda_vector_zerop (lambda_vector vec1, int size)
293{
294  int i;
295  for (i = 0; i < size; i++)
296    if (vec1[i] != 0)
297      return false;
298  return true;
299}
300
301/* Clear out vector VEC1 of length SIZE.  */
302
303static inline void
304lambda_vector_clear (lambda_vector vec1, int size)
305{
306  memset (vec1, 0, size * sizeof (*vec1));
307}
308
309/* Return true if two vectors are equal.  */
310
311static inline bool
312lambda_vector_equal (lambda_vector vec1, lambda_vector vec2, int size)
313{
314  int i;
315  for (i = 0; i < size; i++)
316    if (vec1[i] != vec2[i])
317      return false;
318  return true;
319}
320
321/* Return the minimum nonzero element in vector VEC1 between START and N.
322   We must have START <= N.  */
323
324static inline int
325lambda_vector_min_nz (lambda_vector vec1, int n, int start)
326{
327  int j;
328  int min = -1;
329
330  gcc_assert (start <= n);
331  for (j = start; j < n; j++)
332    {
333      if (vec1[j])
334	if (min < 0 || vec1[j] < vec1[min])
335	  min = j;
336    }
337  gcc_assert (min >= 0);
338
339  return min;
340}
341
342/* Return the first nonzero element of vector VEC1 between START and N.
343   We must have START <= N.   Returns N if VEC1 is the zero vector.  */
344
345static inline int
346lambda_vector_first_nz (lambda_vector vec1, int n, int start)
347{
348  int j = start;
349  while (j < n && vec1[j] == 0)
350    j++;
351  return j;
352}
353
354
355/* Multiply a vector by a matrix.  */
356
357static inline void
358lambda_vector_matrix_mult (lambda_vector vect, int m, lambda_matrix mat,
359			   int n, lambda_vector dest)
360{
361  int i, j;
362  lambda_vector_clear (dest, n);
363  for (i = 0; i < n; i++)
364    for (j = 0; j < m; j++)
365      dest[i] += mat[j][i] * vect[j];
366}
367
368
369/* Print out a vector VEC of length N to OUTFILE.  */
370
371static inline void
372print_lambda_vector (FILE * outfile, lambda_vector vector, int n)
373{
374  int i;
375
376  for (i = 0; i < n; i++)
377    fprintf (outfile, "%3d ", vector[i]);
378  fprintf (outfile, "\n");
379}
380
381/* Compute the greatest common divisor of two numbers using
382   Euclid's algorithm.  */
383
384static inline int
385gcd (int a, int b)
386{
387  int x, y, z;
388
389  x = abs (a);
390  y = abs (b);
391
392  while (x > 0)
393    {
394      z = y % x;
395      y = x;
396      x = z;
397    }
398
399  return y;
400}
401
402/* Compute the greatest common divisor of a VECTOR of SIZE numbers.  */
403
404static inline int
405lambda_vector_gcd (lambda_vector vector, int size)
406{
407  int i;
408  int gcd1 = 0;
409
410  if (size > 0)
411    {
412      gcd1 = vector[0];
413      for (i = 1; i < size; i++)
414	gcd1 = gcd (gcd1, vector[i]);
415    }
416  return gcd1;
417}
418
419/* Returns true when the vector V is lexicographically positive, in
420   other words, when the first nonzero element is positive.  */
421
422static inline bool
423lambda_vector_lexico_pos (lambda_vector v,
424			  unsigned n)
425{
426  unsigned i;
427  for (i = 0; i < n; i++)
428    {
429      if (v[i] == 0)
430	continue;
431      if (v[i] < 0)
432	return false;
433      if (v[i] > 0)
434	return true;
435    }
436  return true;
437}
438
439#endif /* LAMBDA_H  */
440
441