comparison gcc/graphite-blocking.c @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
1 /* Heuristics and transform for loop blocking and strip mining on 1 /* Heuristics and transform for loop blocking and strip mining on
2 polyhedral representation. 2 polyhedral representation.
3 3
4 Copyright (C) 2009 Free Software Foundation, Inc. 4 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
5 Contributed by Sebastian Pop <sebastian.pop@amd.com> and 5 Contributed by Sebastian Pop <sebastian.pop@amd.com> and
6 Pranav Garg <pranav.garg2107@gmail.com>. 6 Pranav Garg <pranav.garg2107@gmail.com>.
7 7
8 This file is part of GCC. 8 This file is part of GCC.
9 9
21 along with GCC; see the file COPYING3. If not see 21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */ 22 <http://www.gnu.org/licenses/>. */
23 #include "config.h" 23 #include "config.h"
24 #include "system.h" 24 #include "system.h"
25 #include "coretypes.h" 25 #include "coretypes.h"
26 #include "tm.h"
27 #include "ggc.h"
28 #include "tree.h"
29 #include "rtl.h"
30 #include "output.h"
31 #include "basic-block.h"
32 #include "diagnostic.h"
33 #include "tree-flow.h" 26 #include "tree-flow.h"
34 #include "toplev.h"
35 #include "tree-dump.h" 27 #include "tree-dump.h"
36 #include "timevar.h"
37 #include "cfgloop.h" 28 #include "cfgloop.h"
38 #include "tree-chrec.h" 29 #include "tree-chrec.h"
39 #include "tree-data-ref.h" 30 #include "tree-data-ref.h"
40 #include "tree-scalar-evolution.h" 31 #include "sese.h"
41 #include "tree-pass.h"
42 #include "domwalk.h"
43 #include "value-prof.h"
44 #include "pointer-set.h"
45 #include "gimple.h"
46 #include "params.h"
47 32
48 #ifdef HAVE_cloog 33 #ifdef HAVE_cloog
49 #include "cloog/cloog.h"
50 #include "ppl_c.h" 34 #include "ppl_c.h"
51 #include "sese.h"
52 #include "graphite-ppl.h" 35 #include "graphite-ppl.h"
53 #include "graphite.h"
54 #include "graphite-poly.h" 36 #include "graphite-poly.h"
55 37
56 38
57 /* Strip mines with a factor STRIDE the scattering (time) dimension 39 /* Strip mines with a factor STRIDE the scattering (time) dimension
58 around PBB at depth TIME_DEPTH. 40 around PBB at depth TIME_DEPTH.
171 } 153 }
172 154
173 return true; 155 return true;
174 } 156 }
175 157
176 /* Returns true when strip mining with STRIDE of the loop around PBB 158 /* Returns true when strip mining with STRIDE of the loop LST is
177 at DEPTH is profitable. */ 159 profitable. */
178 160
179 static bool 161 static bool
180 pbb_strip_mine_profitable_p (poly_bb_p pbb, 162 lst_strip_mine_profitable_p (lst_p lst, int stride)
181 graphite_dim_t depth,
182 int stride)
183 { 163 {
184 mpz_t niter, strip_stride; 164 mpz_t niter, strip_stride;
185 bool res; 165 bool res;
186 166
167 gcc_assert (LST_LOOP_P (lst));
187 mpz_init (strip_stride); 168 mpz_init (strip_stride);
188 mpz_init (niter); 169 mpz_init (niter);
170
189 mpz_set_si (strip_stride, stride); 171 mpz_set_si (strip_stride, stride);
190 pbb_number_of_iterations_at_time (pbb, psct_dynamic_dim (pbb, depth), niter); 172 lst_niter_for_loop (lst, niter);
191 res = (mpz_cmp (niter, strip_stride) > 0); 173 res = (mpz_cmp (niter, strip_stride) > 0);
174
192 mpz_clear (strip_stride); 175 mpz_clear (strip_stride);
193 mpz_clear (niter); 176 mpz_clear (niter);
194
195 return res; 177 return res;
196 } 178 }
197 179
198 /* Strip-mines all the loops of LST that are considered profitable to 180 /* Strip-mines all the loops of LST with STRIDE. Return true if it
199 strip-mine. Return true if it did strip-mined some loops. */ 181 did strip-mined some loops. */
200 182
201 static bool 183 static bool
202 lst_do_strip_mine_loop (lst_p lst, int depth) 184 lst_do_strip_mine_loop (lst_p lst, int depth, int stride)
203 { 185 {
204 int i; 186 int i;
205 lst_p l; 187 lst_p l;
206 int stride = PARAM_VALUE (PARAM_LOOP_BLOCK_TILE_SIZE);
207 poly_bb_p pbb; 188 poly_bb_p pbb;
208 189
209 if (!lst) 190 if (!lst)
210 return false; 191 return false;
211 192
212 if (LST_LOOP_P (lst)) 193 if (LST_LOOP_P (lst))
213 { 194 {
214 bool res = false; 195 bool res = false;
215 196
216 for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++) 197 FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l)
217 res |= lst_do_strip_mine_loop (l, depth); 198 res |= lst_do_strip_mine_loop (l, depth, stride);
218 199
219 return res; 200 return res;
220 } 201 }
221 202
222 pbb = LST_PBB (lst); 203 pbb = LST_PBB (lst);
223 return pbb_strip_mine_time_depth (pbb, psct_dynamic_dim (pbb, depth), 204 return pbb_strip_mine_time_depth (pbb, psct_dynamic_dim (pbb, depth),
224 stride); 205 stride);
225 } 206 }
226 207
227 /* Strip-mines all the loops of LST that are considered profitable to 208 /* Strip-mines all the loops of LST with STRIDE. When STRIDE is zero,
228 strip-mine. Return true if it did strip-mined some loops. */ 209 read the stride from the PARAM_LOOP_BLOCK_TILE_SIZE. Return true
229 210 if it did strip-mined some loops.
230 static bool 211
231 lst_do_strip_mine (lst_p lst) 212 Strip mining transforms a loop
213
214 | for (i = 0; i < N; i++)
215 | S (i);
216
217 into the following loop nest:
218
219 | for (k = 0; k < N; k += STRIDE)
220 | for (j = 0; j < STRIDE; j++)
221 | S (i = k + j);
222 */
223
224 static bool
225 lst_do_strip_mine (lst_p lst, int stride)
232 { 226 {
233 int i; 227 int i;
234 lst_p l; 228 lst_p l;
235 bool res = false; 229 bool res = false;
236 int stride = PARAM_VALUE (PARAM_LOOP_BLOCK_TILE_SIZE);
237 int depth; 230 int depth;
231
232 if (!stride)
233 stride = PARAM_VALUE (PARAM_LOOP_BLOCK_TILE_SIZE);
238 234
239 if (!lst 235 if (!lst
240 || !LST_LOOP_P (lst)) 236 || !LST_LOOP_P (lst))
241 return false; 237 return false;
242 238
243 for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++) 239 FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l)
244 res |= lst_do_strip_mine (l); 240 res |= lst_do_strip_mine (l, stride);
245 241
246 depth = lst_depth (lst); 242 depth = lst_depth (lst);
247 if (depth >= 0 243 if (depth >= 0
248 && pbb_strip_mine_profitable_p (LST_PBB (lst_find_first_pbb (lst)), 244 && lst_strip_mine_profitable_p (lst, stride))
249 depth, stride))
250 { 245 {
251 res |= lst_do_strip_mine_loop (lst, lst_depth (lst)); 246 res |= lst_do_strip_mine_loop (lst, lst_depth (lst), stride);
252 lst_add_loop_under_loop (lst); 247 lst_add_loop_under_loop (lst);
253 } 248 }
254 249
255 return res; 250 return res;
256 } 251 }
257 252
258 /* Strip mines all the loops in SCOP. Nothing profitable in all this: 253 /* Strip mines all the loops in SCOP. Returns true when some loops
259 this is just a driver function. */ 254 have been strip-mined. */
260 255
261 bool 256 bool
262 scop_do_strip_mine (scop_p scop) 257 scop_do_strip_mine (scop_p scop, int stride)
263 { 258 {
264 bool transform_done = false; 259 return lst_do_strip_mine (SCOP_TRANSFORMED_SCHEDULE (scop), stride);
265
266 store_scattering (scop);
267
268 transform_done = lst_do_strip_mine (SCOP_TRANSFORMED_SCHEDULE (scop));
269
270 if (!transform_done)
271 return false;
272
273 if (!graphite_legal_transform (scop))
274 {
275 restore_scattering (scop);
276 return false;
277 }
278
279 return transform_done;
280 } 260 }
281 261
282 /* Loop blocks all the loops in SCOP. Returns true when we manage to 262 /* Loop blocks all the loops in SCOP. Returns true when we manage to
283 block some loops. */ 263 block some loops. */
284 264
288 bool strip_mined = false; 268 bool strip_mined = false;
289 bool interchanged = false; 269 bool interchanged = false;
290 270
291 store_scattering (scop); 271 store_scattering (scop);
292 272
293 strip_mined = lst_do_strip_mine (SCOP_TRANSFORMED_SCHEDULE (scop)); 273 strip_mined = lst_do_strip_mine (SCOP_TRANSFORMED_SCHEDULE (scop), 0);
294 interchanged = scop_do_interchange (scop); 274 interchanged = scop_do_interchange (scop);
295 275
296 /* If we don't interchange loops, then the strip mine is not 276 /* If we don't interchange loops, the strip mine alone will not be
297 profitable, and the transform is not a loop blocking. */ 277 profitable, and the transform is not a loop blocking: so revert
298 if (!interchanged 278 the transform. */
299 || !graphite_legal_transform (scop)) 279 if (!interchanged)
300 { 280 {
301 restore_scattering (scop); 281 restore_scattering (scop);
302 return false; 282 return false;
303 } 283 }
304 else if (strip_mined && interchanged 284 else if (strip_mined && interchanged