1 /* Lambda matrix and vector interface.
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Daniel Berlin <dberlin@dberlin.org>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
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
31 typedef int *lambda_vector
;
32 /* An integer matrix. A matrix consists of m vectors of length n (IE
33 all vectors are the same length). */
34 typedef lambda_vector
*lambda_matrix
;
36 /* A transformation matrix. */
43 } *lambda_trans_matrix
;
44 #define LTM_MATRIX(T) ((T)->matrix)
45 #define LTM_ROWSIZE(T) ((T)->rowsize)
46 #define LTM_COLSIZE(T) ((T)->colsize)
47 #define LTM_DENOMINATOR(T) ((T)->denominator)
49 /* A vector representing a statement in the body of a loop. */
52 lambda_vector coefficients
;
55 } *lambda_body_vector
;
56 #define LBV_COEFFICIENTS(T) ((T)->coefficients)
57 #define LBV_SIZE(T) ((T)->size)
58 #define LBV_DENOMINATOR(T) ((T)->denominator)
60 /* Piecewise linear expression. */
61 typedef struct lambda_linear_expression_s
63 lambda_vector coefficients
;
65 lambda_vector invariant_coefficients
;
67 struct lambda_linear_expression_s
*next
;
68 } *lambda_linear_expression
;
70 #define LLE_COEFFICIENTS(T) ((T)->coefficients)
71 #define LLE_CONSTANT(T) ((T)->constant)
72 #define LLE_INVARIANT_COEFFICIENTS(T) ((T)->invariant_coefficients)
73 #define LLE_DENOMINATOR(T) ((T)->denominator)
74 #define LLE_NEXT(T) ((T)->next)
76 lambda_linear_expression
lambda_linear_expression_new (int, int);
77 void print_lambda_linear_expression (FILE *, lambda_linear_expression
, int,
81 typedef struct lambda_loop_s
83 lambda_linear_expression lower_bound
;
84 lambda_linear_expression upper_bound
;
85 lambda_linear_expression linear_offset
;
89 #define LL_LOWER_BOUND(T) ((T)->lower_bound)
90 #define LL_UPPER_BOUND(T) ((T)->upper_bound)
91 #define LL_LINEAR_OFFSET(T) ((T)->linear_offset)
92 #define LL_STEP(T) ((T)->step)
94 /* Loop nest structure. */
102 #define LN_LOOPS(T) ((T)->loops)
103 #define LN_DEPTH(T) ((T)->depth)
104 #define LN_INVARIANTS(T) ((T)->invariants)
106 lambda_loopnest
lambda_loopnest_new (int, int);
107 lambda_loopnest
lambda_loopnest_transform (lambda_loopnest
, lambda_trans_matrix
);
110 bool perfect_nest_p (struct loop
*);
111 bool lambda_transform_legal_p (lambda_trans_matrix
, int, varray_type
);
112 void print_lambda_loopnest (FILE *, lambda_loopnest
, char);
114 #define lambda_loop_new() (lambda_loop) ggc_alloc_cleared (sizeof (struct lambda_loop_s))
116 void print_lambda_loop (FILE *, lambda_loop
, int, int, char);
118 lambda_matrix
lambda_matrix_new (int, int);
120 void lambda_matrix_id (lambda_matrix
, int);
121 bool lambda_matrix_id_p (lambda_matrix
, int);
122 void lambda_matrix_copy (lambda_matrix
, lambda_matrix
, int, int);
123 void lambda_matrix_negate (lambda_matrix
, lambda_matrix
, int, int);
124 void lambda_matrix_transpose (lambda_matrix
, lambda_matrix
, int, int);
125 void lambda_matrix_add (lambda_matrix
, lambda_matrix
, lambda_matrix
, int,
127 void lambda_matrix_add_mc (lambda_matrix
, int, lambda_matrix
, int,
128 lambda_matrix
, int, int);
129 void lambda_matrix_mult (lambda_matrix
, lambda_matrix
, lambda_matrix
,
131 void lambda_matrix_delete_rows (lambda_matrix
, int, int, int);
132 void lambda_matrix_row_exchange (lambda_matrix
, int, int);
133 void lambda_matrix_row_add (lambda_matrix
, int, int, int, int);
134 void lambda_matrix_row_negate (lambda_matrix mat
, int, int);
135 void lambda_matrix_row_mc (lambda_matrix
, int, int, int);
136 void lambda_matrix_col_exchange (lambda_matrix
, int, int, int);
137 void lambda_matrix_col_add (lambda_matrix
, int, int, int, int);
138 void lambda_matrix_col_negate (lambda_matrix
, int, int);
139 void lambda_matrix_col_mc (lambda_matrix
, int, int, int);
140 int lambda_matrix_inverse (lambda_matrix
, lambda_matrix
, int);
141 void lambda_matrix_hermite (lambda_matrix
, int, lambda_matrix
, lambda_matrix
);
142 void lambda_matrix_left_hermite (lambda_matrix
, int, int, lambda_matrix
, lambda_matrix
);
143 void lambda_matrix_right_hermite (lambda_matrix
, int, int, lambda_matrix
, lambda_matrix
);
144 int lambda_matrix_first_nz_vec (lambda_matrix
, int, int, int);
145 void lambda_matrix_project_to_null (lambda_matrix
, int, int, int,
147 void print_lambda_matrix (FILE *, lambda_matrix
, int, int);
149 lambda_trans_matrix
lambda_trans_matrix_new (int, int);
150 bool lambda_trans_matrix_nonsingular_p (lambda_trans_matrix
);
151 bool lambda_trans_matrix_fullrank_p (lambda_trans_matrix
);
152 int lambda_trans_matrix_rank (lambda_trans_matrix
);
153 lambda_trans_matrix
lambda_trans_matrix_basis (lambda_trans_matrix
);
154 lambda_trans_matrix
lambda_trans_matrix_padding (lambda_trans_matrix
);
155 lambda_trans_matrix
lambda_trans_matrix_inverse (lambda_trans_matrix
);
156 void print_lambda_trans_matrix (FILE *, lambda_trans_matrix
);
157 void lambda_matrix_vector_mult (lambda_matrix
, int, int, lambda_vector
,
159 bool lambda_trans_matrix_id_p (lambda_trans_matrix
);
161 lambda_body_vector
lambda_body_vector_new (int);
162 lambda_body_vector
lambda_body_vector_compute_new (lambda_trans_matrix
,
164 void print_lambda_body_vector (FILE *, lambda_body_vector
);
165 lambda_loopnest
gcc_loopnest_to_lambda_loopnest (struct loops
*,
170 void lambda_loopnest_to_gcc_loopnest (struct loop
*, VEC(tree
) *,
173 lambda_trans_matrix
);
176 static inline void lambda_vector_negate (lambda_vector
, lambda_vector
, int);
177 static inline void lambda_vector_mult_const (lambda_vector
, lambda_vector
, int, int);
178 static inline void lambda_vector_add (lambda_vector
, lambda_vector
,
180 static inline void lambda_vector_add_mc (lambda_vector
, int, lambda_vector
, int,
182 static inline void lambda_vector_copy (lambda_vector
, lambda_vector
, int);
183 static inline bool lambda_vector_zerop (lambda_vector
, int);
184 static inline void lambda_vector_clear (lambda_vector
, int);
185 static inline bool lambda_vector_equal (lambda_vector
, lambda_vector
, int);
186 static inline int lambda_vector_min_nz (lambda_vector
, int, int);
187 static inline int lambda_vector_first_nz (lambda_vector
, int, int);
188 static inline void print_lambda_vector (FILE *, lambda_vector
, int);
190 /* Allocate a new vector of given SIZE. */
192 static inline lambda_vector
193 lambda_vector_new (int size
)
195 return ggc_alloc_cleared (size
* sizeof(int));
200 /* Multiply vector VEC1 of length SIZE by a constant CONST1,
201 and store the result in VEC2. */
204 lambda_vector_mult_const (lambda_vector vec1
, lambda_vector vec2
,
205 int size
, int const1
)
210 lambda_vector_clear (vec2
, size
);
212 for (i
= 0; i
< size
; i
++)
213 vec2
[i
] = const1
* vec1
[i
];
216 /* Negate vector VEC1 with length SIZE and store it in VEC2. */
219 lambda_vector_negate (lambda_vector vec1
, lambda_vector vec2
,
222 lambda_vector_mult_const (vec1
, vec2
, size
, -1);
225 /* VEC3 = VEC1+VEC2, where all three the vectors are of length SIZE. */
228 lambda_vector_add (lambda_vector vec1
, lambda_vector vec2
,
229 lambda_vector vec3
, int size
)
232 for (i
= 0; i
< size
; i
++)
233 vec3
[i
] = vec1
[i
] + vec2
[i
];
236 /* VEC3 = CONSTANT1*VEC1 + CONSTANT2*VEC2. All vectors have length SIZE. */
239 lambda_vector_add_mc (lambda_vector vec1
, int const1
,
240 lambda_vector vec2
, int const2
,
241 lambda_vector vec3
, int size
)
244 for (i
= 0; i
< size
; i
++)
245 vec3
[i
] = const1
* vec1
[i
] + const2
* vec2
[i
];
248 /* Copy the elements of vector VEC1 with length SIZE to VEC2. */
251 lambda_vector_copy (lambda_vector vec1
, lambda_vector vec2
,
254 memcpy (vec2
, vec1
, size
* sizeof (*vec1
));
257 /* Return true if vector VEC1 of length SIZE is the zero vector. */
260 lambda_vector_zerop (lambda_vector vec1
, int size
)
263 for (i
= 0; i
< size
; i
++)
269 /* Clear out vector VEC1 of length SIZE. */
272 lambda_vector_clear (lambda_vector vec1
, int size
)
274 memset (vec1
, 0, size
* sizeof (*vec1
));
277 /* Return true if two vectors are equal. */
280 lambda_vector_equal (lambda_vector vec1
, lambda_vector vec2
, int size
)
283 for (i
= 0; i
< size
; i
++)
284 if (vec1
[i
] != vec2
[i
])
289 /* Return the minimum nonzero element in vector VEC1 between START and N.
290 We must have START <= N. */
293 lambda_vector_min_nz (lambda_vector vec1
, int n
, int start
)
297 #ifdef ENABLE_CHECKING
301 for (j
= start
; j
< n
; j
++)
304 if (min
< 0 || vec1
[j
] < vec1
[min
])
314 /* Return the first nonzero element of vector VEC1 between START and N.
315 We must have START <= N. Returns N if VEC1 is the zero vector. */
318 lambda_vector_first_nz (lambda_vector vec1
, int n
, int start
)
321 while (j
< n
&& vec1
[j
] == 0)
327 /* Multiply a vector by a matrix. */
330 lambda_vector_matrix_mult (lambda_vector vect
, int m
, lambda_matrix mat
,
331 int n
, lambda_vector dest
)
334 lambda_vector_clear (dest
, n
);
335 for (i
= 0; i
< n
; i
++)
336 for (j
= 0; j
< m
; j
++)
337 dest
[i
] += mat
[j
][i
] * vect
[j
];
341 /* Print out a vector VEC of length N to OUTFILE. */
344 print_lambda_vector (FILE * outfile
, lambda_vector vector
, int n
)
348 for (i
= 0; i
< n
; i
++)
349 fprintf (outfile
, "%3d ", vector
[i
]);
350 fprintf (outfile
, "\n");
352 #endif /* LAMBDA_H */