]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-loop-distribution.c
re PR target/53461 (Incorrect handling of CASE_VECTOR_PC_RELATIVE in config/m68k.md)
[thirdparty/gcc.git] / gcc / tree-loop-distribution.c
CommitLineData
dea61d92 1/* Loop distribution.
b03c3082 2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
c75c517d 3 Free Software Foundation, Inc.
dea61d92
SP
4 Contributed by Georges-Andre Silber <Georges-Andre.Silber@ensmp.fr>
5 and Sebastian Pop <sebastian.pop@amd.com>.
6
7This file is part of GCC.
b8698a0f 8
dea61d92
SP
9GCC is free software; you can redistribute it and/or modify it
10under the terms of the GNU General Public License as published by the
11Free Software Foundation; either version 3, or (at your option) any
12later version.
b8698a0f 13
dea61d92
SP
14GCC is distributed in the hope that it will be useful, but WITHOUT
15ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
b8698a0f 18
dea61d92
SP
19You should have received a copy of the GNU General Public License
20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
22
23/* This pass performs loop distribution: for example, the loop
24
25 |DO I = 2, N
26 | A(I) = B(I) + C
27 | D(I) = A(I-1)*E
28 |ENDDO
29
b8698a0f 30 is transformed to
dea61d92
SP
31
32 |DOALL I = 2, N
33 | A(I) = B(I) + C
34 |ENDDO
35 |
36 |DOALL I = 2, N
37 | D(I) = A(I-1)*E
38 |ENDDO
39
40 This pass uses an RDG, Reduced Dependence Graph built on top of the
41 data dependence relations. The RDG is then topologically sorted to
42 obtain a map of information producers/consumers based on which it
43 generates the new loops. */
44
45#include "config.h"
46#include "system.h"
47#include "coretypes.h"
dea61d92 48#include "tree-flow.h"
dea61d92 49#include "cfgloop.h"
dea61d92
SP
50#include "tree-chrec.h"
51#include "tree-data-ref.h"
52#include "tree-scalar-evolution.h"
53#include "tree-pass.h"
dea61d92 54
30d55936
RG
55enum partition_kind { PKIND_NORMAL, PKIND_MEMSET };
56
c61f8985
RG
57typedef struct partition_s
58{
59 bitmap stmts;
30d55936
RG
60 enum partition_kind kind;
61 /* Main statement a kind != PKIND_NORMAL partition is about. */
62 gimple main_stmt;
c61f8985
RG
63} *partition_t;
64
65DEF_VEC_P (partition_t);
66DEF_VEC_ALLOC_P (partition_t, heap);
67
68/* Allocate and initialize a partition from BITMAP. */
69
70static partition_t
71partition_alloc (bitmap stmts)
72{
73 partition_t partition = XCNEW (struct partition_s);
74 partition->stmts = stmts ? stmts : BITMAP_ALLOC (NULL);
30d55936 75 partition->kind = PKIND_NORMAL;
c61f8985
RG
76 return partition;
77}
78
79/* Free PARTITION. */
80
81static void
82partition_free (partition_t partition)
83{
84 BITMAP_FREE (partition->stmts);
85 free (partition);
86}
87
30d55936
RG
88/* Returns true if the partition can be generated as a builtin. */
89
90static bool
91partition_builtin_p (partition_t partition)
92{
93 return partition->kind != PKIND_NORMAL;
94}
c61f8985 95
dea61d92
SP
96/* If bit I is not set, it means that this node represents an
97 operation that has already been performed, and that should not be
98 performed again. This is the subgraph of remaining important
99 computations that is passed to the DFS algorithm for avoiding to
100 include several times the same stores in different loops. */
101static bitmap remaining_stmts;
102
103/* A node of the RDG is marked in this bitmap when it has as a
104 predecessor a node that writes to memory. */
105static bitmap upstream_mem_writes;
106
c07a8cb3
RG
107/* Returns true when DEF is an SSA_NAME defined in LOOP and used after
108 the LOOP. */
109
110static bool
111ssa_name_has_uses_outside_loop_p (tree def, loop_p loop)
112{
113 imm_use_iterator imm_iter;
114 use_operand_p use_p;
115
116 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
117 if (loop != loop_containing_stmt (USE_STMT (use_p)))
118 return true;
119
120 return false;
121}
122
123/* Returns true when STMT defines a scalar variable used after the
88af7c1a 124 loop LOOP. */
c07a8cb3
RG
125
126static bool
88af7c1a 127stmt_has_scalar_dependences_outside_loop (loop_p loop, gimple stmt)
c07a8cb3 128{
88af7c1a
RG
129 def_operand_p def_p;
130 ssa_op_iter op_iter;
c07a8cb3 131
9ca86fc3
RG
132 if (gimple_code (stmt) == GIMPLE_PHI)
133 return ssa_name_has_uses_outside_loop_p (gimple_phi_result (stmt), loop);
134
88af7c1a
RG
135 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_DEF)
136 if (ssa_name_has_uses_outside_loop_p (DEF_FROM_PTR (def_p), loop))
137 return true;
c07a8cb3 138
88af7c1a 139 return false;
c07a8cb3
RG
140}
141
dea61d92
SP
142/* Update the PHI nodes of NEW_LOOP. NEW_LOOP is a duplicate of
143 ORIG_LOOP. */
144
145static void
146update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
147{
148 tree new_ssa_name;
726a989a 149 gimple_stmt_iterator si_new, si_orig;
dea61d92
SP
150 edge orig_loop_latch = loop_latch_edge (orig_loop);
151 edge orig_entry_e = loop_preheader_edge (orig_loop);
152 edge new_loop_entry_e = loop_preheader_edge (new_loop);
153
154 /* Scan the phis in the headers of the old and new loops
155 (they are organized in exactly the same order). */
726a989a
RB
156 for (si_new = gsi_start_phis (new_loop->header),
157 si_orig = gsi_start_phis (orig_loop->header);
158 !gsi_end_p (si_new) && !gsi_end_p (si_orig);
159 gsi_next (&si_new), gsi_next (&si_orig))
dea61d92 160 {
726a989a 161 tree def;
f5045c96 162 source_location locus;
726a989a
RB
163 gimple phi_new = gsi_stmt (si_new);
164 gimple phi_orig = gsi_stmt (si_orig);
165
dea61d92
SP
166 /* Add the first phi argument for the phi in NEW_LOOP (the one
167 associated with the entry of NEW_LOOP) */
726a989a 168 def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
f5045c96
AM
169 locus = gimple_phi_arg_location_from_edge (phi_orig, orig_entry_e);
170 add_phi_arg (phi_new, def, new_loop_entry_e, locus);
dea61d92
SP
171
172 /* Add the second phi argument for the phi in NEW_LOOP (the one
173 associated with the latch of NEW_LOOP) */
174 def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
f5045c96 175 locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
dea61d92
SP
176
177 if (TREE_CODE (def) == SSA_NAME)
178 {
179 new_ssa_name = get_current_def (def);
180
181 if (!new_ssa_name)
182 /* This only happens if there are no definitions inside the
61226dc8
SP
183 loop. Use the the invariant in the new loop as is. */
184 new_ssa_name = def;
dea61d92
SP
185 }
186 else
187 /* Could be an integer. */
188 new_ssa_name = def;
189
f5045c96 190 add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
dea61d92
SP
191 }
192}
193
194/* Return a copy of LOOP placed before LOOP. */
195
196static struct loop *
197copy_loop_before (struct loop *loop)
198{
199 struct loop *res;
200 edge preheader = loop_preheader_edge (loop);
201
dea61d92
SP
202 initialize_original_copy_tables ();
203 res = slpeel_tree_duplicate_loop_to_edge_cfg (loop, preheader);
30d55936 204 gcc_assert (res != NULL);
dea61d92
SP
205 free_original_copy_tables ();
206
dea61d92
SP
207 update_phis_for_loop_copy (loop, res);
208 rename_variables_in_loop (res);
209
210 return res;
211}
212
213/* Creates an empty basic block after LOOP. */
214
215static void
216create_bb_after_loop (struct loop *loop)
217{
218 edge exit = single_exit (loop);
219
220 if (!exit)
221 return;
222
223 split_edge (exit);
224}
225
226/* Generate code for PARTITION from the code in LOOP. The loop is
227 copied when COPY_P is true. All the statements not flagged in the
228 PARTITION bitmap are removed from the loop or from its copy. The
229 statements are indexed in sequence inside a basic block, and the
30d55936 230 basic blocks of a loop are taken in dom order. */
dea61d92 231
30d55936 232static void
c61f8985
RG
233generate_loops_for_partition (struct loop *loop, partition_t partition,
234 bool copy_p)
dea61d92
SP
235{
236 unsigned i, x;
726a989a 237 gimple_stmt_iterator bsi;
dea61d92
SP
238 basic_block *bbs;
239
240 if (copy_p)
241 {
242 loop = copy_loop_before (loop);
30d55936 243 gcc_assert (loop != NULL);
dea61d92
SP
244 create_preheader (loop, CP_SIMPLE_PREHEADERS);
245 create_bb_after_loop (loop);
246 }
247
dea61d92
SP
248 /* Remove stmts not in the PARTITION bitmap. The order in which we
249 visit the phi nodes and the statements is exactly as in
250 stmts_from_loop. */
251 bbs = get_loop_body_in_dom_order (loop);
252
b03c3082
JJ
253 if (MAY_HAVE_DEBUG_STMTS)
254 for (x = 0, i = 0; i < loop->num_nodes; i++)
255 {
256 basic_block bb = bbs[i];
257
258 for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
c61f8985 259 if (!bitmap_bit_p (partition->stmts, x++))
b03c3082
JJ
260 reset_debug_uses (gsi_stmt (bsi));
261
262 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
263 {
264 gimple stmt = gsi_stmt (bsi);
265 if (gimple_code (stmt) != GIMPLE_LABEL
266 && !is_gimple_debug (stmt)
c61f8985 267 && !bitmap_bit_p (partition->stmts, x++))
b03c3082
JJ
268 reset_debug_uses (stmt);
269 }
270 }
271
dea61d92
SP
272 for (x = 0, i = 0; i < loop->num_nodes; i++)
273 {
274 basic_block bb = bbs[i];
dea61d92 275
726a989a 276 for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi);)
c61f8985 277 if (!bitmap_bit_p (partition->stmts, x++))
2706a615
RG
278 {
279 gimple phi = gsi_stmt (bsi);
280 if (!is_gimple_reg (gimple_phi_result (phi)))
281 mark_virtual_phi_result_for_renaming (phi);
282 remove_phi_node (&bsi, true);
283 }
dea61d92 284 else
726a989a 285 gsi_next (&bsi);
dea61d92 286
726a989a 287 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);)
2706a615
RG
288 {
289 gimple stmt = gsi_stmt (bsi);
b03c3082
JJ
290 if (gimple_code (stmt) != GIMPLE_LABEL
291 && !is_gimple_debug (stmt)
c61f8985 292 && !bitmap_bit_p (partition->stmts, x++))
2706a615
RG
293 {
294 unlink_stmt_vdef (stmt);
295 gsi_remove (&bsi, true);
296 release_defs (stmt);
297 }
298 else
299 gsi_next (&bsi);
300 }
dea61d92
SP
301 }
302
303 free (bbs);
dea61d92
SP
304}
305
ada39f0b 306/* Build the size argument for a memset call. */
3661e899
TB
307
308static inline tree
fc81a369
RH
309build_size_arg_loc (location_t loc, tree nb_iter, tree op,
310 gimple_seq *stmt_list)
3661e899 311{
fc81a369 312 gimple_seq stmts;
0d82a1c8
RG
313 tree x = fold_build2_loc (loc, MULT_EXPR, size_type_node,
314 fold_convert_loc (loc, size_type_node, nb_iter),
315 fold_convert_loc (loc, size_type_node,
316 TYPE_SIZE_UNIT (TREE_TYPE (op))));
fc81a369
RH
317 x = force_gimple_operand (x, &stmts, true, NULL);
318 gimple_seq_add_seq (stmt_list, stmts);
3661e899 319
fc81a369 320 return x;
3661e899
TB
321}
322
30d55936 323/* Generate a call to memset for PARTITION in LOOP. */
dea61d92 324
cfee318d 325static void
30d55936 326generate_memset_builtin (struct loop *loop, partition_t partition)
dea61d92 327{
30d55936
RG
328 gimple_stmt_iterator gsi;
329 gimple stmt, fn_call;
330 tree op0, nb_iter, mem, fn, addr_base, nb_bytes;
fc81a369 331 gimple_seq stmt_list = NULL, stmts;
dea61d92 332 struct data_reference *dr = XCNEW (struct data_reference);
30d55936
RG
333 location_t loc;
334 bool res;
335
336 stmt = partition->main_stmt;
337 loc = gimple_location (stmt);
338 op0 = gimple_assign_lhs (stmt);
339 if (gimple_bb (stmt) == loop->latch)
340 nb_iter = number_of_latch_executions (loop);
341 else
342 nb_iter = number_of_exit_cond_executions (loop);
343
344 /* The new statements will be placed before LOOP. */
345 gsi = gsi_last_bb (loop_preheader_edge (loop)->src);
dea61d92 346
dea61d92
SP
347 DR_STMT (dr) = stmt;
348 DR_REF (dr) = op0;
4e4452b6 349 res = dr_analyze_innermost (dr, loop_containing_stmt (stmt));
cfee318d 350 gcc_assert (res && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (op0)));
5e37ea0e
SP
351
352 nb_bytes = build_size_arg_loc (loc, nb_iter, op0, &stmt_list);
353 addr_base = size_binop_loc (loc, PLUS_EXPR, DR_OFFSET (dr), DR_INIT (dr));
354 addr_base = fold_convert_loc (loc, sizetype, addr_base);
dea61d92
SP
355
356 /* Test for a negative stride, iterating over every element. */
0d82a1c8 357 if (tree_int_cst_sgn (DR_STEP (dr)) == -1)
dea61d92 358 {
fc81a369
RH
359 addr_base = size_binop_loc (loc, MINUS_EXPR, addr_base,
360 fold_convert_loc (loc, sizetype, nb_bytes));
6edd8198
AM
361 addr_base = size_binop_loc (loc, PLUS_EXPR, addr_base,
362 TYPE_SIZE_UNIT (TREE_TYPE (op0)));
dea61d92 363 }
dea61d92 364
5d49b6a7
RG
365 addr_base = fold_build_pointer_plus_loc (loc,
366 DR_BASE_ADDRESS (dr), addr_base);
dea61d92 367 mem = force_gimple_operand (addr_base, &stmts, true, NULL);
726a989a 368 gimple_seq_add_seq (&stmt_list, stmts);
dea61d92 369
e79983f4 370 fn = build_fold_addr_expr (builtin_decl_implicit (BUILT_IN_MEMSET));
726a989a
RB
371 fn_call = gimple_build_call (fn, 3, mem, integer_zero_node, nb_bytes);
372 gimple_seq_add_stmt (&stmt_list, fn_call);
30d55936 373 gsi_insert_seq_after (&gsi, stmt_list, GSI_CONTINUE_LINKING);
dea61d92
SP
374
375 if (dump_file && (dump_flags & TDF_DETAILS))
376 fprintf (dump_file, "generated memset zero\n");
377
dea61d92 378 free_data_ref (dr);
dea61d92
SP
379}
380
30d55936 381/* Remove and destroy the loop LOOP. */
dea61d92 382
30d55936
RG
383static void
384destroy_loop (struct loop *loop)
dea61d92 385{
30d55936
RG
386 unsigned nbbs = loop->num_nodes;
387 edge exit = single_exit (loop);
388 basic_block src = loop_preheader_edge (loop)->src, dest = exit->dest;
dea61d92 389 basic_block *bbs;
30d55936 390 unsigned i;
dea61d92
SP
391
392 bbs = get_loop_body_in_dom_order (loop);
393
30d55936
RG
394 redirect_edge_pred (exit, src);
395 exit->flags &= ~(EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
396 exit->flags |= EDGE_FALLTHRU;
397 cancel_loop_tree (loop);
398 rescan_loop_exit (exit, false, true);
dea61d92 399
30d55936 400 for (i = 0; i < nbbs; i++)
c014f6f5
RG
401 {
402 /* We have made sure to not leave any dangling uses of SSA
403 names defined in the loop. With the exception of virtuals.
404 Make sure we replace all uses of virtual defs that will remain
405 outside of the loop with the bare symbol as delete_basic_block
406 will release them. */
407 gimple_stmt_iterator gsi;
408 for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
409 {
410 gimple phi = gsi_stmt (gsi);
411 if (!is_gimple_reg (gimple_phi_result (phi)))
412 mark_virtual_phi_result_for_renaming (phi);
413 }
414 for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
415 {
416 gimple stmt = gsi_stmt (gsi);
417 tree vdef = gimple_vdef (stmt);
418 if (vdef && TREE_CODE (vdef) == SSA_NAME)
419 mark_virtual_operand_for_renaming (vdef);
420 }
421 delete_basic_block (bbs[i]);
422 }
dea61d92 423 free (bbs);
30d55936
RG
424
425 set_immediate_dominator (CDI_DOMINATORS, dest,
426 recompute_dominator (CDI_DOMINATORS, dest));
dea61d92
SP
427}
428
30d55936 429/* Generates code for PARTITION. */
dea61d92 430
30d55936 431static void
c61f8985
RG
432generate_code_for_partition (struct loop *loop, partition_t partition,
433 bool copy_p)
dea61d92 434{
30d55936
RG
435 switch (partition->kind)
436 {
437 case PKIND_MEMSET:
438 generate_memset_builtin (loop, partition);
439 /* If this is the last partition for which we generate code, we have
440 to destroy the loop. */
441 if (!copy_p)
442 destroy_loop (loop);
443 break;
444
445 case PKIND_NORMAL:
446 generate_loops_for_partition (loop, partition, copy_p);
447 break;
448
449 default:
450 gcc_unreachable ();
451 }
dea61d92
SP
452}
453
454
455/* Returns true if the node V of RDG cannot be recomputed. */
456
457static bool
458rdg_cannot_recompute_vertex_p (struct graph *rdg, int v)
459{
460 if (RDG_MEM_WRITE_STMT (rdg, v))
461 return true;
462
463 return false;
464}
465
466/* Returns true when the vertex V has already been generated in the
467 current partition (V is in PROCESSED), or when V belongs to another
468 partition and cannot be recomputed (V is not in REMAINING_STMTS). */
469
470static inline bool
471already_processed_vertex_p (bitmap processed, int v)
472{
473 return (bitmap_bit_p (processed, v)
474 || !bitmap_bit_p (remaining_stmts, v));
475}
476
477/* Returns NULL when there is no anti-dependence among the successors
478 of vertex V, otherwise returns the edge with the anti-dep. */
479
480static struct graph_edge *
481has_anti_dependence (struct vertex *v)
482{
483 struct graph_edge *e;
484
485 if (v->succ)
486 for (e = v->succ; e; e = e->succ_next)
487 if (RDGE_TYPE (e) == anti_dd)
488 return e;
489
490 return NULL;
491}
492
493/* Returns true when V has an anti-dependence edge among its successors. */
494
495static bool
496predecessor_has_mem_write (struct graph *rdg, struct vertex *v)
497{
498 struct graph_edge *e;
499
500 if (v->pred)
501 for (e = v->pred; e; e = e->pred_next)
502 if (bitmap_bit_p (upstream_mem_writes, e->src)
503 /* Don't consider flow channels: a write to memory followed
504 by a read from memory. These channels allow the split of
505 the RDG in different partitions. */
506 && !RDG_MEM_WRITE_STMT (rdg, e->src))
507 return true;
508
509 return false;
510}
511
512/* Initializes the upstream_mem_writes bitmap following the
513 information from RDG. */
514
515static void
516mark_nodes_having_upstream_mem_writes (struct graph *rdg)
517{
518 int v, x;
519 bitmap seen = BITMAP_ALLOC (NULL);
520
521 for (v = rdg->n_vertices - 1; v >= 0; v--)
522 if (!bitmap_bit_p (seen, v))
523 {
524 unsigned i;
525 VEC (int, heap) *nodes = VEC_alloc (int, heap, 3);
dea61d92
SP
526
527 graphds_dfs (rdg, &v, 1, &nodes, false, NULL);
528
ac47786e 529 FOR_EACH_VEC_ELT (int, nodes, i, x)
dea61d92 530 {
fcaa4ca4 531 if (!bitmap_set_bit (seen, x))
dea61d92
SP
532 continue;
533
dea61d92
SP
534 if (RDG_MEM_WRITE_STMT (rdg, x)
535 || predecessor_has_mem_write (rdg, &(rdg->vertices[x]))
536 /* In anti dependences the read should occur before
537 the write, this is why both the read and the write
538 should be placed in the same partition. */
539 || has_anti_dependence (&(rdg->vertices[x])))
540 {
dea61d92
SP
541 bitmap_set_bit (upstream_mem_writes, x);
542 }
543 }
544
545 VEC_free (int, heap, nodes);
546 }
547}
548
549/* Returns true when vertex u has a memory write node as a predecessor
550 in RDG. */
551
552static bool
553has_upstream_mem_writes (int u)
554{
555 return bitmap_bit_p (upstream_mem_writes, u);
556}
557
c61f8985
RG
558static void rdg_flag_vertex_and_dependent (struct graph *, int, partition_t,
559 bitmap, bitmap, bool *);
dea61d92 560
dea61d92
SP
561/* Flag the uses of U stopping following the information from
562 upstream_mem_writes. */
563
564static void
c61f8985 565rdg_flag_uses (struct graph *rdg, int u, partition_t partition, bitmap loops,
dea61d92
SP
566 bitmap processed, bool *part_has_writes)
567{
dea61d92
SP
568 use_operand_p use_p;
569 struct vertex *x = &(rdg->vertices[u]);
726a989a 570 gimple stmt = RDGV_STMT (x);
dea61d92
SP
571 struct graph_edge *anti_dep = has_anti_dependence (x);
572
573 /* Keep in the same partition the destination of an antidependence,
574 because this is a store to the exact same location. Putting this
575 in another partition is bad for cache locality. */
576 if (anti_dep)
577 {
578 int v = anti_dep->dest;
579
580 if (!already_processed_vertex_p (processed, v))
581 rdg_flag_vertex_and_dependent (rdg, v, partition, loops,
582 processed, part_has_writes);
583 }
584
726a989a 585 if (gimple_code (stmt) != GIMPLE_PHI)
dea61d92 586 {
5006671f 587 if ((use_p = gimple_vuse_op (stmt)) != NULL_USE_OPERAND_P)
dea61d92
SP
588 {
589 tree use = USE_FROM_PTR (use_p);
590
591 if (TREE_CODE (use) == SSA_NAME)
592 {
726a989a 593 gimple def_stmt = SSA_NAME_DEF_STMT (use);
dea61d92
SP
594 int v = rdg_vertex_for_stmt (rdg, def_stmt);
595
596 if (v >= 0
597 && !already_processed_vertex_p (processed, v))
598 rdg_flag_vertex_and_dependent (rdg, v, partition, loops,
599 processed, part_has_writes);
600 }
601 }
602 }
603
726a989a 604 if (is_gimple_assign (stmt) && has_upstream_mem_writes (u))
dea61d92 605 {
726a989a 606 tree op0 = gimple_assign_lhs (stmt);
dea61d92
SP
607
608 /* Scalar channels don't have enough space for transmitting data
609 between tasks, unless we add more storage by privatizing. */
610 if (is_gimple_reg (op0))
611 {
612 use_operand_p use_p;
613 imm_use_iterator iter;
614
615 FOR_EACH_IMM_USE_FAST (use_p, iter, op0)
616 {
617 int v = rdg_vertex_for_stmt (rdg, USE_STMT (use_p));
618
619 if (!already_processed_vertex_p (processed, v))
620 rdg_flag_vertex_and_dependent (rdg, v, partition, loops,
621 processed, part_has_writes);
622 }
623 }
624 }
625}
626
627/* Flag V from RDG as part of PARTITION, and also flag its loop number
628 in LOOPS. */
629
630static void
c61f8985 631rdg_flag_vertex (struct graph *rdg, int v, partition_t partition, bitmap loops,
dea61d92
SP
632 bool *part_has_writes)
633{
634 struct loop *loop;
635
c61f8985 636 if (!bitmap_set_bit (partition->stmts, v))
dea61d92
SP
637 return;
638
639 loop = loop_containing_stmt (RDG_STMT (rdg, v));
640 bitmap_set_bit (loops, loop->num);
dea61d92
SP
641
642 if (rdg_cannot_recompute_vertex_p (rdg, v))
643 {
644 *part_has_writes = true;
645 bitmap_clear_bit (remaining_stmts, v);
646 }
647}
648
649/* Flag in the bitmap PARTITION the vertex V and all its predecessors.
fa10beec 650 Also flag their loop number in LOOPS. */
dea61d92
SP
651
652static void
c61f8985 653rdg_flag_vertex_and_dependent (struct graph *rdg, int v, partition_t partition,
dea61d92
SP
654 bitmap loops, bitmap processed,
655 bool *part_has_writes)
656{
657 unsigned i;
658 VEC (int, heap) *nodes = VEC_alloc (int, heap, 3);
659 int x;
660
661 bitmap_set_bit (processed, v);
662 rdg_flag_uses (rdg, v, partition, loops, processed, part_has_writes);
663 graphds_dfs (rdg, &v, 1, &nodes, false, remaining_stmts);
664 rdg_flag_vertex (rdg, v, partition, loops, part_has_writes);
665
ac47786e 666 FOR_EACH_VEC_ELT (int, nodes, i, x)
dea61d92
SP
667 if (!already_processed_vertex_p (processed, x))
668 rdg_flag_vertex_and_dependent (rdg, x, partition, loops, processed,
669 part_has_writes);
670
671 VEC_free (int, heap, nodes);
672}
673
674/* Initialize CONDS with all the condition statements from the basic
675 blocks of LOOP. */
676
677static void
726a989a 678collect_condition_stmts (struct loop *loop, VEC (gimple, heap) **conds)
dea61d92
SP
679{
680 unsigned i;
681 edge e;
682 VEC (edge, heap) *exits = get_loop_exit_edges (loop);
683
ac47786e 684 FOR_EACH_VEC_ELT (edge, exits, i, e)
dea61d92 685 {
726a989a 686 gimple cond = last_stmt (e->src);
dea61d92
SP
687
688 if (cond)
726a989a 689 VEC_safe_push (gimple, heap, *conds, cond);
dea61d92
SP
690 }
691
692 VEC_free (edge, heap, exits);
693}
694
695/* Add to PARTITION all the exit condition statements for LOOPS
696 together with all their dependent statements determined from
697 RDG. */
698
699static void
c61f8985 700rdg_flag_loop_exits (struct graph *rdg, bitmap loops, partition_t partition,
dea61d92
SP
701 bitmap processed, bool *part_has_writes)
702{
703 unsigned i;
704 bitmap_iterator bi;
726a989a 705 VEC (gimple, heap) *conds = VEC_alloc (gimple, heap, 3);
dea61d92
SP
706
707 EXECUTE_IF_SET_IN_BITMAP (loops, 0, i, bi)
708 collect_condition_stmts (get_loop (i), &conds);
709
726a989a 710 while (!VEC_empty (gimple, conds))
dea61d92 711 {
726a989a 712 gimple cond = VEC_pop (gimple, conds);
dea61d92
SP
713 int v = rdg_vertex_for_stmt (rdg, cond);
714 bitmap new_loops = BITMAP_ALLOC (NULL);
715
716 if (!already_processed_vertex_p (processed, v))
717 rdg_flag_vertex_and_dependent (rdg, v, partition, new_loops, processed,
718 part_has_writes);
719
720 EXECUTE_IF_SET_IN_BITMAP (new_loops, 0, i, bi)
fcaa4ca4
NF
721 if (bitmap_set_bit (loops, i))
722 collect_condition_stmts (get_loop (i), &conds);
dea61d92
SP
723
724 BITMAP_FREE (new_loops);
725 }
01be8516
SP
726
727 VEC_free (gimple, heap, conds);
dea61d92
SP
728}
729
dea61d92
SP
730/* Returns a bitmap in which all the statements needed for computing
731 the strongly connected component C of the RDG are flagged, also
732 including the loop exit conditions. */
733
c61f8985 734static partition_t
dea61d92 735build_rdg_partition_for_component (struct graph *rdg, rdgc c,
cfee318d 736 bool *part_has_writes)
dea61d92
SP
737{
738 int i, v;
c61f8985 739 partition_t partition = partition_alloc (NULL);
dea61d92
SP
740 bitmap loops = BITMAP_ALLOC (NULL);
741 bitmap processed = BITMAP_ALLOC (NULL);
742
ac47786e 743 FOR_EACH_VEC_ELT (int, c->vertices, i, v)
dea61d92
SP
744 if (!already_processed_vertex_p (processed, v))
745 rdg_flag_vertex_and_dependent (rdg, v, partition, loops, processed,
746 part_has_writes);
747
dea61d92
SP
748 rdg_flag_loop_exits (rdg, loops, partition, processed, part_has_writes);
749
750 BITMAP_FREE (processed);
751 BITMAP_FREE (loops);
752 return partition;
753}
754
755/* Free memory for COMPONENTS. */
756
757static void
758free_rdg_components (VEC (rdgc, heap) *components)
759{
760 int i;
761 rdgc x;
762
ac47786e 763 FOR_EACH_VEC_ELT (rdgc, components, i, x)
dea61d92
SP
764 {
765 VEC_free (int, heap, x->vertices);
766 free (x);
767 }
01be8516
SP
768
769 VEC_free (rdgc, heap, components);
dea61d92
SP
770}
771
772/* Build the COMPONENTS vector with the strongly connected components
773 of RDG in which the STARTING_VERTICES occur. */
774
775static void
b8698a0f 776rdg_build_components (struct graph *rdg, VEC (int, heap) *starting_vertices,
dea61d92
SP
777 VEC (rdgc, heap) **components)
778{
779 int i, v;
780 bitmap saved_components = BITMAP_ALLOC (NULL);
781 int n_components = graphds_scc (rdg, NULL);
782 VEC (int, heap) **all_components = XNEWVEC (VEC (int, heap) *, n_components);
783
784 for (i = 0; i < n_components; i++)
785 all_components[i] = VEC_alloc (int, heap, 3);
786
787 for (i = 0; i < rdg->n_vertices; i++)
788 VEC_safe_push (int, heap, all_components[rdg->vertices[i].component], i);
789
ac47786e 790 FOR_EACH_VEC_ELT (int, starting_vertices, i, v)
dea61d92
SP
791 {
792 int c = rdg->vertices[v].component;
793
fcaa4ca4 794 if (bitmap_set_bit (saved_components, c))
dea61d92
SP
795 {
796 rdgc x = XCNEW (struct rdg_component);
797 x->num = c;
798 x->vertices = all_components[c];
799
800 VEC_safe_push (rdgc, heap, *components, x);
dea61d92
SP
801 }
802 }
803
804 for (i = 0; i < n_components; i++)
805 if (!bitmap_bit_p (saved_components, i))
806 VEC_free (int, heap, all_components[i]);
807
808 free (all_components);
809 BITMAP_FREE (saved_components);
810}
811
30d55936
RG
812/* Classifies the builtin kind we can generate for PARTITION of RDG and LOOP.
813 For the moment we detect only the memset zero pattern. */
cfee318d 814
30d55936
RG
815static void
816classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
cfee318d 817{
cfee318d 818 bitmap_iterator bi;
30d55936
RG
819 unsigned i;
820 tree nb_iter;
821
822 partition->kind = PKIND_NORMAL;
823 partition->main_stmt = NULL;
824
c014f6f5
RG
825 if (!flag_tree_loop_distribute_patterns)
826 return;
827
30d55936
RG
828 /* Perform general partition disqualification for builtins. */
829 nb_iter = number_of_exit_cond_executions (loop);
830 if (!nb_iter || nb_iter == chrec_dont_know)
831 return;
cfee318d 832
c61f8985 833 EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, bi)
30d55936
RG
834 {
835 gimple stmt = RDG_STMT (rdg, i);
836
837 if (gimple_has_volatile_ops (stmt))
838 return;
cfee318d 839
30d55936
RG
840 /* If the stmt has uses outside of the loop fail.
841 ??? If the stmt is generated in another partition that
842 is not created as builtin we can ignore this. */
9ca86fc3 843 if (stmt_has_scalar_dependences_outside_loop (loop, stmt))
30d55936
RG
844 {
845 if (dump_file && (dump_flags & TDF_DETAILS))
846 fprintf (dump_file, "not generating builtin, partition has "
847 "scalar uses outside of the loop\n");
848 return;
849 }
850 }
851
852 /* Detect memset. */
853 EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, bi)
854 {
855 gimple stmt = RDG_STMT (rdg, i);
856
857 if (gimple_code (stmt) == GIMPLE_PHI)
858 continue;
859
860 /* Any scalar stmts are ok. */
861 if (!gimple_vuse (stmt))
862 continue;
863
864 /* Exactly one store. */
865 if (gimple_assign_single_p (stmt)
866 && !is_gimple_reg (gimple_assign_lhs (stmt)))
867 {
868 if (partition->main_stmt != NULL)
869 return;
870 partition->main_stmt = stmt;
871 }
872 else
873 return;
874 }
875
876 if (partition->main_stmt != NULL
877 && stmt_with_adjacent_zero_store_dr_p (partition->main_stmt))
878 partition->kind = PKIND_MEMSET;
cfee318d
SP
879}
880
881/* Returns true when PARTITION1 and PARTITION2 have similar memory
882 accesses in RDG. */
883
884static bool
c61f8985
RG
885similar_memory_accesses (struct graph *rdg, partition_t partition1,
886 partition_t partition2)
cfee318d
SP
887{
888 unsigned i, j;
889 bitmap_iterator bi, bj;
890
c61f8985 891 EXECUTE_IF_SET_IN_BITMAP (partition1->stmts, 0, i, bi)
cfee318d
SP
892 if (RDG_MEM_WRITE_STMT (rdg, i)
893 || RDG_MEM_READS_STMT (rdg, i))
c61f8985 894 EXECUTE_IF_SET_IN_BITMAP (partition2->stmts, 0, j, bj)
cfee318d
SP
895 if (RDG_MEM_WRITE_STMT (rdg, j)
896 || RDG_MEM_READS_STMT (rdg, j))
897 if (rdg_has_similar_memory_accesses (rdg, i, j))
898 return true;
899
900 return false;
901}
902
dea61d92
SP
903/* Aggregate several components into a useful partition that is
904 registered in the PARTITIONS vector. Partitions will be
905 distributed in different loops. */
906
907static void
908rdg_build_partitions (struct graph *rdg, VEC (rdgc, heap) *components,
909 VEC (int, heap) **other_stores,
c61f8985 910 VEC (partition_t, heap) **partitions, bitmap processed)
dea61d92
SP
911{
912 int i;
913 rdgc x;
c61f8985 914 partition_t partition = partition_alloc (NULL);
dea61d92 915
ac47786e 916 FOR_EACH_VEC_ELT (rdgc, components, i, x)
dea61d92 917 {
c61f8985 918 partition_t np;
dea61d92
SP
919 bool part_has_writes = false;
920 int v = VEC_index (int, x->vertices, 0);
b8698a0f 921
dea61d92
SP
922 if (bitmap_bit_p (processed, v))
923 continue;
b8698a0f 924
cfee318d 925 np = build_rdg_partition_for_component (rdg, x, &part_has_writes);
c61f8985
RG
926 bitmap_ior_into (partition->stmts, np->stmts);
927 bitmap_ior_into (processed, np->stmts);
928 partition_free (np);
dea61d92
SP
929
930 if (part_has_writes)
931 {
932 if (dump_file && (dump_flags & TDF_DETAILS))
933 {
934 fprintf (dump_file, "ldist useful partition:\n");
c61f8985 935 dump_bitmap (dump_file, partition->stmts);
dea61d92
SP
936 }
937
c61f8985
RG
938 VEC_safe_push (partition_t, heap, *partitions, partition);
939 partition = partition_alloc (NULL);
dea61d92
SP
940 }
941 }
942
943 /* Add the nodes from the RDG that were not marked as processed, and
944 that are used outside the current loop. These are scalar
945 computations that are not yet part of previous partitions. */
946 for (i = 0; i < rdg->n_vertices; i++)
947 if (!bitmap_bit_p (processed, i)
948 && rdg_defs_used_in_other_loops_p (rdg, i))
949 VEC_safe_push (int, heap, *other_stores, i);
950
951 /* If there are still statements left in the OTHER_STORES array,
952 create other components and partitions with these stores and
953 their dependences. */
954 if (VEC_length (int, *other_stores) > 0)
955 {
956 VEC (rdgc, heap) *comps = VEC_alloc (rdgc, heap, 3);
957 VEC (int, heap) *foo = VEC_alloc (int, heap, 3);
958
959 rdg_build_components (rdg, *other_stores, &comps);
960 rdg_build_partitions (rdg, comps, &foo, partitions, processed);
961
962 VEC_free (int, heap, foo);
963 free_rdg_components (comps);
964 }
965
966 /* If there is something left in the last partition, save it. */
c61f8985
RG
967 if (bitmap_count_bits (partition->stmts) > 0)
968 VEC_safe_push (partition_t, heap, *partitions, partition);
dea61d92 969 else
c61f8985 970 partition_free (partition);
dea61d92
SP
971}
972
973/* Dump to FILE the PARTITIONS. */
974
975static void
c61f8985 976dump_rdg_partitions (FILE *file, VEC (partition_t, heap) *partitions)
dea61d92
SP
977{
978 int i;
c61f8985 979 partition_t partition;
dea61d92 980
c61f8985
RG
981 FOR_EACH_VEC_ELT (partition_t, partitions, i, partition)
982 debug_bitmap_file (file, partition->stmts);
dea61d92
SP
983}
984
985/* Debug PARTITIONS. */
c61f8985 986extern void debug_rdg_partitions (VEC (partition_t, heap) *);
dea61d92 987
24e47c76 988DEBUG_FUNCTION void
c61f8985 989debug_rdg_partitions (VEC (partition_t, heap) *partitions)
dea61d92
SP
990{
991 dump_rdg_partitions (stderr, partitions);
992}
993
2b8aee8e
SP
994/* Returns the number of read and write operations in the RDG. */
995
996static int
997number_of_rw_in_rdg (struct graph *rdg)
998{
999 int i, res = 0;
1000
1001 for (i = 0; i < rdg->n_vertices; i++)
1002 {
1003 if (RDG_MEM_WRITE_STMT (rdg, i))
1004 ++res;
1005
1006 if (RDG_MEM_READS_STMT (rdg, i))
1007 ++res;
1008 }
1009
1010 return res;
1011}
1012
1013/* Returns the number of read and write operations in a PARTITION of
1014 the RDG. */
1015
1016static int
c61f8985 1017number_of_rw_in_partition (struct graph *rdg, partition_t partition)
2b8aee8e
SP
1018{
1019 int res = 0;
1020 unsigned i;
1021 bitmap_iterator ii;
1022
c61f8985 1023 EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, ii)
2b8aee8e
SP
1024 {
1025 if (RDG_MEM_WRITE_STMT (rdg, i))
1026 ++res;
1027
1028 if (RDG_MEM_READS_STMT (rdg, i))
1029 ++res;
1030 }
1031
1032 return res;
1033}
1034
1035/* Returns true when one of the PARTITIONS contains all the read or
1036 write operations of RDG. */
1037
1038static bool
c61f8985 1039partition_contains_all_rw (struct graph *rdg, VEC (partition_t, heap) *partitions)
2b8aee8e
SP
1040{
1041 int i;
c61f8985 1042 partition_t partition;
2b8aee8e
SP
1043 int nrw = number_of_rw_in_rdg (rdg);
1044
c61f8985 1045 FOR_EACH_VEC_ELT (partition_t, partitions, i, partition)
2b8aee8e
SP
1046 if (nrw == number_of_rw_in_partition (rdg, partition))
1047 return true;
1048
1049 return false;
1050}
1051
dea61d92
SP
1052/* Generate code from STARTING_VERTICES in RDG. Returns the number of
1053 distributed loops. */
1054
1055static int
1056ldist_gen (struct loop *loop, struct graph *rdg,
1057 VEC (int, heap) *starting_vertices)
1058{
1059 int i, nbp;
1060 VEC (rdgc, heap) *components = VEC_alloc (rdgc, heap, 3);
c61f8985 1061 VEC (partition_t, heap) *partitions = VEC_alloc (partition_t, heap, 3);
dea61d92 1062 VEC (int, heap) *other_stores = VEC_alloc (int, heap, 3);
c61f8985
RG
1063 partition_t partition;
1064 bitmap processed = BITMAP_ALLOC (NULL);
dea61d92
SP
1065
1066 remaining_stmts = BITMAP_ALLOC (NULL);
1067 upstream_mem_writes = BITMAP_ALLOC (NULL);
1068
1069 for (i = 0; i < rdg->n_vertices; i++)
1070 {
1071 bitmap_set_bit (remaining_stmts, i);
1072
1073 /* Save in OTHER_STORES all the memory writes that are not in
1074 STARTING_VERTICES. */
1075 if (RDG_MEM_WRITE_STMT (rdg, i))
1076 {
1077 int v;
1078 unsigned j;
1079 bool found = false;
1080
ac47786e 1081 FOR_EACH_VEC_ELT (int, starting_vertices, j, v)
dea61d92
SP
1082 if (i == v)
1083 {
1084 found = true;
1085 break;
1086 }
1087
1088 if (!found)
1089 VEC_safe_push (int, heap, other_stores, i);
1090 }
1091 }
1092
1093 mark_nodes_having_upstream_mem_writes (rdg);
1094 rdg_build_components (rdg, starting_vertices, &components);
1095 rdg_build_partitions (rdg, components, &other_stores, &partitions,
1096 processed);
1097 BITMAP_FREE (processed);
dea61d92 1098
30d55936
RG
1099 FOR_EACH_VEC_ELT (partition_t, partitions, i, partition)
1100 classify_partition (loop, rdg, partition);
1101
c014f6f5
RG
1102 /* If we are only distributing patterns fuse all partitions that
1103 were not properly classified as builtins. Else fuse partitions
1104 with similar memory accesses. */
1105 if (!flag_tree_loop_distribution)
1106 {
1107 partition_t into;
1108 for (i = 0; VEC_iterate (partition_t, partitions, i, into); ++i)
1109 if (!partition_builtin_p (into))
1110 break;
1111 for (++i; VEC_iterate (partition_t, partitions, i, partition); ++i)
1112 if (!partition_builtin_p (partition))
1113 {
1114 bitmap_ior_into (into->stmts, partition->stmts);
1115 VEC_ordered_remove (partition_t, partitions, i);
1116 i--;
1117 }
1118 }
1119 else
1120 {
1121 partition_t into;
1122 int j;
1123 for (i = 0; VEC_iterate (partition_t, partitions, i, into); ++i)
1124 {
1125 if (partition_builtin_p (into))
1126 continue;
1127 for (j = i + 1;
1128 VEC_iterate (partition_t, partitions, j, partition); ++j)
1129 {
1130 if (!partition_builtin_p (partition)
1131 /* ??? The following is horribly inefficient,
1132 we are re-computing and analyzing data-references
1133 of the stmts in the partitions all the time. */
1134 && similar_memory_accesses (rdg, into, partition))
1135 {
1136 if (dump_file && (dump_flags & TDF_DETAILS))
1137 {
1138 fprintf (dump_file, "fusing partitions\n");
1139 dump_bitmap (dump_file, into->stmts);
1140 dump_bitmap (dump_file, partition->stmts);
1141 fprintf (dump_file, "because they have similar "
1142 "memory accesses\n");
1143 }
1144 bitmap_ior_into (into->stmts, partition->stmts);
1145 VEC_ordered_remove (partition_t, partitions, j);
1146 j--;
1147 }
1148 }
1149 }
1150 }
30d55936 1151
c61f8985 1152 nbp = VEC_length (partition_t, partitions);
a4293fa6
RG
1153 if (nbp == 0
1154 || (nbp == 1
30d55936 1155 && !partition_builtin_p (VEC_index (partition_t, partitions, 0)))
a4293fa6
RG
1156 || (nbp > 1
1157 && partition_contains_all_rw (rdg, partitions)))
c014f6f5
RG
1158 {
1159 nbp = 0;
1160 goto ldist_done;
1161 }
dea61d92
SP
1162
1163 if (dump_file && (dump_flags & TDF_DETAILS))
1164 dump_rdg_partitions (dump_file, partitions);
1165
c61f8985 1166 FOR_EACH_VEC_ELT (partition_t, partitions, i, partition)
30d55936 1167 generate_code_for_partition (loop, partition, i < nbp - 1);
dea61d92 1168
dea61d92
SP
1169 ldist_done:
1170
1171 BITMAP_FREE (remaining_stmts);
1172 BITMAP_FREE (upstream_mem_writes);
1173
c61f8985
RG
1174 FOR_EACH_VEC_ELT (partition_t, partitions, i, partition)
1175 partition_free (partition);
dea61d92
SP
1176
1177 VEC_free (int, heap, other_stores);
c61f8985 1178 VEC_free (partition_t, heap, partitions);
dea61d92
SP
1179 free_rdg_components (components);
1180 return nbp;
1181}
1182
1183/* Distributes the code from LOOP in such a way that producer
1184 statements are placed before consumer statements. When STMTS is
1185 NULL, performs the maximal distribution, if STMTS is not NULL,
1186 tries to separate only these statements from the LOOP's body.
1187 Returns the number of distributed loops. */
1188
1189static int
726a989a 1190distribute_loop (struct loop *loop, VEC (gimple, heap) *stmts)
dea61d92 1191{
e96d7dd7 1192 int res = 0;
dea61d92 1193 struct graph *rdg;
726a989a 1194 gimple s;
dea61d92
SP
1195 unsigned i;
1196 VEC (int, heap) *vertices;
01be8516
SP
1197 VEC (ddr_p, heap) *dependence_relations;
1198 VEC (data_reference_p, heap) *datarefs;
1199 VEC (loop_p, heap) *loop_nest;
dea61d92 1200
01be8516
SP
1201 datarefs = VEC_alloc (data_reference_p, heap, 10);
1202 dependence_relations = VEC_alloc (ddr_p, heap, 100);
1203 loop_nest = VEC_alloc (loop_p, heap, 3);
1204 rdg = build_rdg (loop, &loop_nest, &dependence_relations, &datarefs);
dea61d92
SP
1205
1206 if (!rdg)
1207 {
1208 if (dump_file && (dump_flags & TDF_DETAILS))
1209 fprintf (dump_file,
1210 "FIXME: Loop %d not distributed: failed to build the RDG.\n",
1211 loop->num);
1212
01be8516
SP
1213 free_dependence_relations (dependence_relations);
1214 free_data_refs (datarefs);
1215 VEC_free (loop_p, heap, loop_nest);
dea61d92
SP
1216 return res;
1217 }
1218
1219 vertices = VEC_alloc (int, heap, 3);
1220
1221 if (dump_file && (dump_flags & TDF_DETAILS))
1222 dump_rdg (dump_file, rdg);
1223
ac47786e 1224 FOR_EACH_VEC_ELT (gimple, stmts, i, s)
dea61d92
SP
1225 {
1226 int v = rdg_vertex_for_stmt (rdg, s);
1227
1228 if (v >= 0)
1229 {
1230 VEC_safe_push (int, heap, vertices, v);
1231
1232 if (dump_file && (dump_flags & TDF_DETAILS))
1233 fprintf (dump_file,
1234 "ldist asked to generate code for vertex %d\n", v);
1235 }
1236 }
1237
1238 res = ldist_gen (loop, rdg, vertices);
1239 VEC_free (int, heap, vertices);
1240 free_rdg (rdg);
01be8516
SP
1241 free_dependence_relations (dependence_relations);
1242 free_data_refs (datarefs);
1243 VEC_free (loop_p, heap, loop_nest);
dea61d92
SP
1244 return res;
1245}
1246
1247/* Distribute all loops in the current function. */
1248
1249static unsigned int
1250tree_loop_distribution (void)
1251{
1252 struct loop *loop;
1253 loop_iterator li;
c014f6f5 1254 bool changed = false;
dea61d92 1255
c014f6f5
RG
1256 /* We can at the moment only distribute non-nested loops, thus restrict
1257 walking to innermost loops. */
1258 FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
dea61d92 1259 {
a3357f7d 1260 VEC (gimple, heap) *work_list = NULL;
0e20c89f 1261 int num = loop->num;
c014f6f5 1262 int nb_generated_loops = 0;
a3357f7d
RG
1263
1264 /* If the loop doesn't have a single exit we will fail anyway,
1265 so do that early. */
1266 if (!single_exit (loop))
1267 continue;
dea61d92 1268
c014f6f5
RG
1269 /* Only distribute loops with a header and latch for now. */
1270 if (loop->num_nodes > 2)
1271 continue;
1272
1273 /* -ftree-loop-distribution strictly distributes more but also
1274 enables pattern detection. For now simply distribute all stores
1275 or memset like stores. */
1276 if (flag_tree_loop_distribution)
1277 stores_from_loop (loop, &work_list);
1278 else if (flag_tree_loop_distribute_patterns)
1279 stores_zero_from_loop (loop, &work_list);
1280
1281 if (VEC_length (gimple, work_list) > 0)
1282 nb_generated_loops = distribute_loop (loop, work_list);
1283
1284 if (nb_generated_loops > 0)
1285 changed = true;
dea61d92
SP
1286
1287 if (dump_file && (dump_flags & TDF_DETAILS))
1288 {
1289 if (nb_generated_loops > 1)
1290 fprintf (dump_file, "Loop %d distributed: split to %d loops.\n",
0e20c89f 1291 num, nb_generated_loops);
dea61d92 1292 else
0e20c89f 1293 fprintf (dump_file, "Loop %d is the same.\n", num);
dea61d92
SP
1294 }
1295
726a989a 1296 VEC_free (gimple, heap, work_list);
dea61d92
SP
1297 }
1298
c014f6f5
RG
1299 if (changed)
1300 {
1301 mark_sym_for_renaming (gimple_vop (cfun));
1302 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
1303 }
1304
1305#ifdef ENABLE_CHECKING
1306 verify_loop_structure ();
1307#endif
1308
5006671f 1309 return 0;
dea61d92
SP
1310}
1311
1312static bool
1313gate_tree_loop_distribution (void)
1314{
20769d5e
SP
1315 return flag_tree_loop_distribution
1316 || flag_tree_loop_distribute_patterns;
dea61d92
SP
1317}
1318
8ddbbcae 1319struct gimple_opt_pass pass_loop_distribution =
dea61d92 1320{
8ddbbcae
JH
1321 {
1322 GIMPLE_PASS,
dea61d92
SP
1323 "ldist", /* name */
1324 gate_tree_loop_distribution, /* gate */
1325 tree_loop_distribution, /* execute */
1326 NULL, /* sub */
1327 NULL, /* next */
1328 0, /* static_pass_number */
1329 TV_TREE_LOOP_DISTRIBUTION, /* tv_id */
1330 PROP_cfg | PROP_ssa, /* properties_required */
1331 0, /* properties_provided */
1332 0, /* properties_destroyed */
1333 0, /* todo_flags_start */
c07a8cb3
RG
1334 TODO_ggc_collect
1335 | TODO_verify_ssa /* todo_flags_finish */
8ddbbcae 1336 }
dea61d92 1337};