Mercurial > hg > CbC > CbC_gcc
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 |