]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-parloops.c
[ARM/AArch64] PR 68088: Fix RTL checking ICE due to subregs inside accumulator forwar...
[thirdparty/gcc.git] / gcc / tree-parloops.c
CommitLineData
28c92cbb 1/* Loop autoparallelization.
d353bf18 2 Copyright (C) 2006-2015 Free Software Foundation, Inc.
0773b627 3 Contributed by Sebastian Pop <pop@cri.ensmp.fr>
4 Zdenek Dvorak <dvorakz@suse.cz> and Razya Ladelsky <razya@il.ibm.com>.
28c92cbb 5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
4ef8346d 10Software Foundation; either version 3, or (at your option) any later
28c92cbb 11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
4ef8346d 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
28c92cbb 21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
9ef16211 25#include "backend.h"
b20a8bb4 26#include "tree.h"
9ef16211 27#include "gimple.h"
7c29e30e 28#include "cfghooks.h"
29#include "tree-pass.h"
9ef16211 30#include "ssa.h"
7c29e30e 31#include "cgraph.h"
32#include "gimple-pretty-print.h"
9ef16211 33#include "fold-const.h"
a8783bee 34#include "gimplify.h"
dcf1a1ec 35#include "gimple-iterator.h"
e795d6e1 36#include "gimplify-me.h"
dcf1a1ec 37#include "gimple-walk.h"
9ed99284 38#include "stor-layout.h"
39#include "tree-nested.h"
073c1fd5 40#include "tree-cfg.h"
05d9c18a 41#include "tree-ssa-loop-ivopts.h"
42#include "tree-ssa-loop-manip.h"
43#include "tree-ssa-loop-niter.h"
073c1fd5 44#include "tree-ssa-loop.h"
45#include "tree-into-ssa.h"
28c92cbb 46#include "cfgloop.h"
1e5b7b1f 47#include "tree-scalar-evolution.h"
28c92cbb 48#include "langhooks.h"
cb7f680b 49#include "tree-vectorizer.h"
d9dd21a8 50#include "tree-hasher.h"
64641360 51#include "tree-parloops.h"
7740abd8 52#include "omp-low.h"
d38409cd 53#include "tree-ssa.h"
9a782341 54#include "params.h"
2331aa43 55#include "params-enum.h"
28c92cbb 56
57/* This pass tries to distribute iterations of loops into several threads.
58 The implementation is straightforward -- for each loop we test whether its
59 iterations are independent, and if it is the case (and some additional
60 conditions regarding profitability and correctness are satisfied), we
75a70cf9 61 add GIMPLE_OMP_PARALLEL and GIMPLE_OMP_FOR codes and let omp expansion
62 machinery do its job.
48e1416a 63
28c92cbb 64 The most of the complexity is in bringing the code into shape expected
65 by the omp expanders:
75a70cf9 66 -- for GIMPLE_OMP_FOR, ensuring that the loop has only one induction
67 variable and that the exit test is at the start of the loop body
68 -- for GIMPLE_OMP_PARALLEL, replacing the references to local addressable
28c92cbb 69 variables by accesses through pointers, and breaking up ssa chains
70 by storing the values incoming to the parallelized loop to a structure
71 passed to the new function as an argument (something similar is done
72 in omp gimplification, unfortunately only a small part of the code
73 can be shared).
74
75 TODO:
76 -- if there are several parallelizable loops in a function, it may be
77 possible to generate the threads just once (using synchronization to
78 ensure that cross-loop dependences are obeyed).
0773b627 79 -- handling of common reduction patterns for outer loops.
80
81 More info can also be found at http://gcc.gnu.org/wiki/AutoParInGCC */
48e1416a 82/*
cb7f680b 83 Reduction handling:
f4a50267 84 currently we use vect_force_simple_reduction() to detect reduction patterns.
cb7f680b 85 The code transformation will be introduced by an example.
48e1416a 86
87
cb7f680b 88parloop
89{
90 int sum=1;
91
848674d0 92 for (i = 0; i < N; i++)
cb7f680b 93 {
94 x[i] = i + 3;
95 sum+=x[i];
96 }
97}
98
848674d0 99gimple-like code:
cb7f680b 100header_bb:
101
848674d0 102 # sum_29 = PHI <sum_11(5), 1(3)>
103 # i_28 = PHI <i_12(5), 0(3)>
104 D.1795_8 = i_28 + 3;
105 x[i_28] = D.1795_8;
106 sum_11 = D.1795_8 + sum_29;
107 i_12 = i_28 + 1;
108 if (N_6(D) > i_12)
109 goto header_bb;
110
cb7f680b 111
112exit_bb:
113
848674d0 114 # sum_21 = PHI <sum_11(4)>
115 printf (&"%d"[0], sum_21);
cb7f680b 116
117
118after reduction transformation (only relevant parts):
119
120parloop
121{
122
123....
124
848674d0 125
f0b5f617 126 # Storing the initial value given by the user. #
848674d0 127
5bb62c99 128 .paral_data_store.32.sum.27 = 1;
48e1416a 129
130 #pragma omp parallel num_threads(4)
cb7f680b 131
848674d0 132 #pragma omp for schedule(static)
5bb62c99 133
134 # The neutral element corresponding to the particular
135 reduction's operation, e.g. 0 for PLUS_EXPR,
136 1 for MULT_EXPR, etc. replaces the user's initial value. #
137
138 # sum.27_29 = PHI <sum.27_11, 0>
139
848674d0 140 sum.27_11 = D.1827_8 + sum.27_29;
5bb62c99 141
75a70cf9 142 GIMPLE_OMP_CONTINUE
cb7f680b 143
848674d0 144 # Adding this reduction phi is done at create_phi_for_local_result() #
145 # sum.27_56 = PHI <sum.27_11, 0>
75a70cf9 146 GIMPLE_OMP_RETURN
48e1416a 147
148 # Creating the atomic operation is done at
848674d0 149 create_call_for_reduction_1() #
cb7f680b 150
848674d0 151 #pragma omp atomic_load
152 D.1839_59 = *&.paral_data_load.33_51->reduction.23;
153 D.1840_60 = sum.27_56 + D.1839_59;
154 #pragma omp atomic_store (D.1840_60);
48e1416a 155
75a70cf9 156 GIMPLE_OMP_RETURN
48e1416a 157
848674d0 158 # collecting the result after the join of the threads is done at
159 create_loads_for_reductions().
5bb62c99 160 The value computed by the threads is loaded from the
161 shared struct. #
162
48e1416a 163
848674d0 164 .paral_data_load.33_52 = &.paral_data_store.32;
5bb62c99 165 sum_37 = .paral_data_load.33_52->sum.27;
848674d0 166 sum_43 = D.1795_41 + sum_37;
167
168 exit bb:
169 # sum_21 = PHI <sum_43, sum_26>
170 printf (&"%d"[0], sum_21);
171
172...
173
cb7f680b 174}
175
176*/
177
28c92cbb 178/* Minimal number of iterations of a loop that should be executed in each
179 thread. */
180#define MIN_PER_THREAD 100
181
48e1416a 182/* Element of the hashtable, representing a
cb7f680b 183 reduction in the current loop. */
184struct reduction_info
185{
42acab1c 186 gimple *reduc_stmt; /* reduction statement. */
187 gimple *reduc_phi; /* The phi node defining the reduction. */
75a70cf9 188 enum tree_code reduction_code;/* code for the reduction operation. */
71fa519d 189 unsigned reduc_version; /* SSA_NAME_VERSION of original reduc_phi
190 result. */
1a91d914 191 gphi *keep_res; /* The PHI_RESULT of this phi is the resulting value
cb7f680b 192 of the reduction variable when existing the loop. */
5bb62c99 193 tree initial_value; /* The initial value of the reduction var before entering the loop. */
cb7f680b 194 tree field; /* the name of the field in the parloop data structure intended for reduction. */
cb7f680b 195 tree init; /* reduction initialization value. */
1a91d914 196 gphi *new_phi; /* (helper field) Newly created phi node whose result
cb7f680b 197 will be passed to the atomic operation. Represents
198 the local result each thread computed for the reduction
199 operation. */
200};
201
d9dd21a8 202/* Reduction info hashtable helpers. */
cb7f680b 203
298e7f9a 204struct reduction_hasher : free_ptr_hash <reduction_info>
cb7f680b 205{
9969c043 206 static inline hashval_t hash (const reduction_info *);
207 static inline bool equal (const reduction_info *, const reduction_info *);
d9dd21a8 208};
209
210/* Equality and hash functions for hashtab code. */
cb7f680b 211
d9dd21a8 212inline bool
9969c043 213reduction_hasher::equal (const reduction_info *a, const reduction_info *b)
d9dd21a8 214{
cb7f680b 215 return (a->reduc_phi == b->reduc_phi);
216}
217
d9dd21a8 218inline hashval_t
9969c043 219reduction_hasher::hash (const reduction_info *a)
cb7f680b 220{
71fa519d 221 return a->reduc_version;
cb7f680b 222}
223
c1f445d2 224typedef hash_table<reduction_hasher> reduction_info_table_type;
d9dd21a8 225
226
cb7f680b 227static struct reduction_info *
42acab1c 228reduction_phi (reduction_info_table_type *reduction_list, gimple *phi)
cb7f680b 229{
230 struct reduction_info tmpred, *red;
231
c1f445d2 232 if (reduction_list->elements () == 0 || phi == NULL)
cb7f680b 233 return NULL;
234
eac984fd 235 if (gimple_uid (phi) == (unsigned int)-1
236 || gimple_uid (phi) == 0)
237 return NULL;
238
cb7f680b 239 tmpred.reduc_phi = phi;
71fa519d 240 tmpred.reduc_version = gimple_uid (phi);
c1f445d2 241 red = reduction_list->find (&tmpred);
eac984fd 242 gcc_assert (red == NULL || red->reduc_phi == phi);
cb7f680b 243
244 return red;
245}
246
28c92cbb 247/* Element of hashtable of names to copy. */
248
249struct name_to_copy_elt
250{
251 unsigned version; /* The version of the name to copy. */
252 tree new_name; /* The new name used in the copy. */
253 tree field; /* The field of the structure used to pass the
254 value. */
255};
256
d9dd21a8 257/* Name copies hashtable helpers. */
28c92cbb 258
298e7f9a 259struct name_to_copy_hasher : free_ptr_hash <name_to_copy_elt>
28c92cbb 260{
9969c043 261 static inline hashval_t hash (const name_to_copy_elt *);
262 static inline bool equal (const name_to_copy_elt *, const name_to_copy_elt *);
d9dd21a8 263};
264
265/* Equality and hash functions for hashtab code. */
28c92cbb 266
d9dd21a8 267inline bool
9969c043 268name_to_copy_hasher::equal (const name_to_copy_elt *a, const name_to_copy_elt *b)
d9dd21a8 269{
28c92cbb 270 return a->version == b->version;
271}
272
d9dd21a8 273inline hashval_t
9969c043 274name_to_copy_hasher::hash (const name_to_copy_elt *a)
28c92cbb 275{
28c92cbb 276 return (hashval_t) a->version;
277}
278
c1f445d2 279typedef hash_table<name_to_copy_hasher> name_to_copy_table_type;
d9dd21a8 280
e01f9f1f 281/* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE
282 matrix. Rather than use floats, we simply keep a single DENOMINATOR that
283 represents the denominator for every element in the matrix. */
284typedef struct lambda_trans_matrix_s
285{
286 lambda_matrix matrix;
287 int rowsize;
288 int colsize;
289 int denominator;
290} *lambda_trans_matrix;
291#define LTM_MATRIX(T) ((T)->matrix)
292#define LTM_ROWSIZE(T) ((T)->rowsize)
293#define LTM_COLSIZE(T) ((T)->colsize)
294#define LTM_DENOMINATOR(T) ((T)->denominator)
295
296/* Allocate a new transformation matrix. */
297
298static lambda_trans_matrix
299lambda_trans_matrix_new (int colsize, int rowsize,
300 struct obstack * lambda_obstack)
301{
302 lambda_trans_matrix ret;
303
304 ret = (lambda_trans_matrix)
305 obstack_alloc (lambda_obstack, sizeof (struct lambda_trans_matrix_s));
306 LTM_MATRIX (ret) = lambda_matrix_new (rowsize, colsize, lambda_obstack);
307 LTM_ROWSIZE (ret) = rowsize;
308 LTM_COLSIZE (ret) = colsize;
309 LTM_DENOMINATOR (ret) = 1;
310 return ret;
311}
312
313/* Multiply a vector VEC by a matrix MAT.
314 MAT is an M*N matrix, and VEC is a vector with length N. The result
315 is stored in DEST which must be a vector of length M. */
316
317static void
318lambda_matrix_vector_mult (lambda_matrix matrix, int m, int n,
319 lambda_vector vec, lambda_vector dest)
320{
321 int i, j;
322
323 lambda_vector_clear (dest, m);
324 for (i = 0; i < m; i++)
325 for (j = 0; j < n; j++)
326 dest[i] += matrix[i][j] * vec[j];
327}
328
329/* Return true if TRANS is a legal transformation matrix that respects
330 the dependence vectors in DISTS and DIRS. The conservative answer
331 is false.
332
333 "Wolfe proves that a unimodular transformation represented by the
334 matrix T is legal when applied to a loop nest with a set of
335 lexicographically non-negative distance vectors RDG if and only if
336 for each vector d in RDG, (T.d >= 0) is lexicographically positive.
337 i.e.: if and only if it transforms the lexicographically positive
338 distance vectors to lexicographically positive vectors. Note that
339 a unimodular matrix must transform the zero vector (and only it) to
340 the zero vector." S.Muchnick. */
341
342static bool
343lambda_transform_legal_p (lambda_trans_matrix trans,
344 int nb_loops,
f1f41a6c 345 vec<ddr_p> dependence_relations)
e01f9f1f 346{
347 unsigned int i, j;
348 lambda_vector distres;
349 struct data_dependence_relation *ddr;
350
351 gcc_assert (LTM_COLSIZE (trans) == nb_loops
352 && LTM_ROWSIZE (trans) == nb_loops);
353
354 /* When there are no dependences, the transformation is correct. */
f1f41a6c 355 if (dependence_relations.length () == 0)
e01f9f1f 356 return true;
357
f1f41a6c 358 ddr = dependence_relations[0];
e01f9f1f 359 if (ddr == NULL)
360 return true;
361
362 /* When there is an unknown relation in the dependence_relations, we
363 know that it is no worth looking at this loop nest: give up. */
364 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
365 return false;
366
367 distres = lambda_vector_new (nb_loops);
368
369 /* For each distance vector in the dependence graph. */
f1f41a6c 370 FOR_EACH_VEC_ELT (dependence_relations, i, ddr)
e01f9f1f 371 {
372 /* Don't care about relations for which we know that there is no
373 dependence, nor about read-read (aka. output-dependences):
374 these data accesses can happen in any order. */
375 if (DDR_ARE_DEPENDENT (ddr) == chrec_known
376 || (DR_IS_READ (DDR_A (ddr)) && DR_IS_READ (DDR_B (ddr))))
377 continue;
378
379 /* Conservatively answer: "this transformation is not valid". */
380 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
381 return false;
382
383 /* If the dependence could not be captured by a distance vector,
384 conservatively answer that the transform is not valid. */
385 if (DDR_NUM_DIST_VECTS (ddr) == 0)
386 return false;
387
388 /* Compute trans.dist_vect */
389 for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
390 {
391 lambda_matrix_vector_mult (LTM_MATRIX (trans), nb_loops, nb_loops,
392 DDR_DIST_VECT (ddr, j), distres);
393
394 if (!lambda_vector_lexico_pos (distres, nb_loops))
395 return false;
396 }
397 }
398 return true;
399}
5fa90eea 400
401/* Data dependency analysis. Returns true if the iterations of LOOP
402 are independent on each other (that is, if we can execute them
403 in parallel). */
28c92cbb 404
405static bool
1e33ad50 406loop_parallel_p (struct loop *loop, struct obstack * parloop_obstack)
28c92cbb 407{
f1f41a6c 408 vec<ddr_p> dependence_relations;
409 vec<data_reference_p> datarefs;
28c92cbb 410 lambda_trans_matrix trans;
411 bool ret = false;
28c92cbb 412
413 if (dump_file && (dump_flags & TDF_DETAILS))
b0fb253a 414 {
415 fprintf (dump_file, "Considering loop %d\n", loop->num);
416 if (!loop->inner)
417 fprintf (dump_file, "loop is innermost\n");
48e1416a 418 else
b0fb253a 419 fprintf (dump_file, "loop NOT innermost\n");
420 }
28c92cbb 421
28c92cbb 422 /* Check for problems with dependences. If the loop can be reversed,
423 the iterations are independent. */
4997014d 424 auto_vec<loop_p, 3> loop_nest;
f1f41a6c 425 datarefs.create (10);
e85cf4e5 426 dependence_relations.create (100);
713f1f14 427 if (! compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
428 &dependence_relations))
429 {
430 if (dump_file && (dump_flags & TDF_DETAILS))
431 fprintf (dump_file, " FAILED: cannot analyze data dependencies\n");
432 ret = false;
433 goto end;
434 }
28c92cbb 435 if (dump_file && (dump_flags & TDF_DETAILS))
436 dump_data_dependence_relations (dump_file, dependence_relations);
437
1e33ad50 438 trans = lambda_trans_matrix_new (1, 1, parloop_obstack);
28c92cbb 439 LTM_MATRIX (trans)[0][0] = -1;
440
441 if (lambda_transform_legal_p (trans, 1, dependence_relations))
442 {
443 ret = true;
444 if (dump_file && (dump_flags & TDF_DETAILS))
445 fprintf (dump_file, " SUCCESS: may be parallelized\n");
446 }
447 else if (dump_file && (dump_flags & TDF_DETAILS))
cb7f680b 448 fprintf (dump_file,
449 " FAILED: data dependencies exist across iterations\n");
28c92cbb 450
713f1f14 451 end:
28c92cbb 452 free_dependence_relations (dependence_relations);
453 free_data_refs (datarefs);
454
455 return ret;
456}
457
d4fcfd16 458/* Return true when LOOP contains basic blocks marked with the
459 BB_IRREDUCIBLE_LOOP flag. */
460
461static inline bool
462loop_has_blocks_with_irreducible_flag (struct loop *loop)
463{
464 unsigned i;
465 basic_block *bbs = get_loop_body_in_dom_order (loop);
466 bool res = true;
467
468 for (i = 0; i < loop->num_nodes; i++)
469 if (bbs[i]->flags & BB_IRREDUCIBLE_LOOP)
470 goto end;
471
472 res = false;
473 end:
474 free (bbs);
475 return res;
476}
477
c1fb5b25 478/* Assigns the address of OBJ in TYPE to an ssa name, and returns this name.
e06f9c34 479 The assignment statement is placed on edge ENTRY. DECL_ADDRESS maps decls
c1fb5b25 480 to their addresses that can be reused. The address of OBJ is known to
ad57283e 481 be invariant in the whole function. Other needed statements are placed
482 right before GSI. */
28c92cbb 483
484static tree
d9dd21a8 485take_address_of (tree obj, tree type, edge entry,
c1f445d2 486 int_tree_htab_type *decl_address, gimple_stmt_iterator *gsi)
28c92cbb 487{
c1fb5b25 488 int uid;
03d37e4e 489 tree *var_p, name, addr;
1a91d914 490 gassign *stmt;
75a70cf9 491 gimple_seq stmts;
28c92cbb 492
c1fb5b25 493 /* Since the address of OBJ is invariant, the trees may be shared.
494 Avoid rewriting unrelated parts of the code. */
495 obj = unshare_expr (obj);
496 for (var_p = &obj;
497 handled_component_p (*var_p);
498 var_p = &TREE_OPERAND (*var_p, 0))
499 continue;
c1fb5b25 500
64ade643 501 /* Canonicalize the access to base on a MEM_REF. */
502 if (DECL_P (*var_p))
503 *var_p = build_simple_mem_ref (build_fold_addr_expr (*var_p));
504
505 /* Assign a canonical SSA name to the address of the base decl used
506 in the address and share it for all accesses and addresses based
507 on it. */
508 uid = DECL_UID (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0));
2933f7af 509 int_tree_map elt;
510 elt.uid = uid;
511 int_tree_map *slot = decl_address->find_slot (elt, INSERT);
512 if (!slot->to)
28c92cbb 513 {
ad57283e 514 if (gsi == NULL)
515 return NULL;
64ade643 516 addr = TREE_OPERAND (*var_p, 0);
a7c17572 517 const char *obj_name
518 = get_name (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0));
519 if (obj_name)
520 name = make_temp_ssa_name (TREE_TYPE (addr), NULL, obj_name);
521 else
f9e245b2 522 name = make_ssa_name (TREE_TYPE (addr));
03d37e4e 523 stmt = gimple_build_assign (name, addr);
75a70cf9 524 gsi_insert_on_edge_immediate (entry, stmt);
28c92cbb 525
2933f7af 526 slot->uid = uid;
527 slot->to = name;
28c92cbb 528 }
c1fb5b25 529 else
2933f7af 530 name = slot->to;
28c92cbb 531
64ade643 532 /* Express the address in terms of the canonical SSA name. */
533 TREE_OPERAND (*var_p, 0) = name;
ad57283e 534 if (gsi == NULL)
535 return build_fold_addr_expr_with_type (obj, type);
536
0e49e441 537 name = force_gimple_operand (build_addr (obj),
64ade643 538 &stmts, true, NULL_TREE);
539 if (!gimple_seq_empty_p (stmts))
ad57283e 540 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
28c92cbb 541
64ade643 542 if (!useless_type_conversion_p (type, TREE_TYPE (name)))
c1fb5b25 543 {
75a70cf9 544 name = force_gimple_operand (fold_convert (type, name), &stmts, true,
c1fb5b25 545 NULL_TREE);
75a70cf9 546 if (!gimple_seq_empty_p (stmts))
ad57283e 547 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
c1fb5b25 548 }
28c92cbb 549
550 return name;
551}
552
95f4166a 553static tree
42acab1c 554reduc_stmt_res (gimple *stmt)
95f4166a 555{
556 return (gimple_code (stmt) == GIMPLE_PHI
557 ? gimple_phi_result (stmt)
558 : gimple_assign_lhs (stmt));
559}
560
cb7f680b 561/* Callback for htab_traverse. Create the initialization statement
48e1416a 562 for reduction described in SLOT, and place it at the preheader of
cb7f680b 563 the loop described in DATA. */
564
d9dd21a8 565int
566initialize_reductions (reduction_info **slot, struct loop *loop)
cb7f680b 567{
df67b98c 568 tree init;
569 tree type, arg;
cb7f680b 570 edge e;
571
d9dd21a8 572 struct reduction_info *const reduc = *slot;
cb7f680b 573
48e1416a 574 /* Create initialization in preheader:
cb7f680b 575 reduction_variable = initialization value of reduction. */
576
48e1416a 577 /* In the phi node at the header, replace the argument coming
cb7f680b 578 from the preheader with the reduction initialization value. */
579
df67b98c 580 /* Initialize the reduction. */
cb7f680b 581 type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
df67b98c 582 init = omp_reduction_init_op (gimple_location (reduc->reduc_stmt),
583 reduc->reduction_code, type);
cb7f680b 584 reduc->init = init;
585
48e1416a 586 /* Replace the argument representing the initialization value
587 with the initialization value for the reduction (neutral
588 element for the particular operation, e.g. 0 for PLUS_EXPR,
589 1 for MULT_EXPR, etc).
590 Keep the old value in a new variable "reduction_initial",
591 that will be taken in consideration after the parallel
848674d0 592 computing is done. */
cb7f680b 593
594 e = loop_preheader_edge (loop);
595 arg = PHI_ARG_DEF_FROM_EDGE (reduc->reduc_phi, e);
596 /* Create new variable to hold the initial value. */
cb7f680b 597
cb7f680b 598 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE
848674d0 599 (reduc->reduc_phi, loop_preheader_edge (loop)), init);
5bb62c99 600 reduc->initial_value = arg;
cb7f680b 601 return 1;
602}
28c92cbb 603
604struct elv_data
605{
75a70cf9 606 struct walk_stmt_info info;
e06f9c34 607 edge entry;
c1f445d2 608 int_tree_htab_type *decl_address;
ad57283e 609 gimple_stmt_iterator *gsi;
28c92cbb 610 bool changed;
ad57283e 611 bool reset;
28c92cbb 612};
613
e06f9c34 614/* Eliminates references to local variables in *TP out of the single
615 entry single exit region starting at DTA->ENTRY.
616 DECL_ADDRESS contains addresses of the references that had their
617 address taken already. If the expression is changed, CHANGED is
618 set to true. Callback for walk_tree. */
cb7f680b 619
28c92cbb 620static tree
c1fb5b25 621eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data)
28c92cbb 622{
45ba1503 623 struct elv_data *const dta = (struct elv_data *) data;
c1fb5b25 624 tree t = *tp, var, addr, addr_type, type, obj;
28c92cbb 625
626 if (DECL_P (t))
627 {
628 *walk_subtrees = 0;
629
630 if (!SSA_VAR_P (t) || DECL_EXTERNAL (t))
631 return NULL_TREE;
632
633 type = TREE_TYPE (t);
634 addr_type = build_pointer_type (type);
ad57283e 635 addr = take_address_of (t, addr_type, dta->entry, dta->decl_address,
636 dta->gsi);
637 if (dta->gsi == NULL && addr == NULL_TREE)
638 {
639 dta->reset = true;
640 return NULL_TREE;
641 }
642
182cf5a9 643 *tp = build_simple_mem_ref (addr);
28c92cbb 644
645 dta->changed = true;
646 return NULL_TREE;
647 }
648
649 if (TREE_CODE (t) == ADDR_EXPR)
650 {
c1fb5b25 651 /* ADDR_EXPR may appear in two contexts:
652 -- as a gimple operand, when the address taken is a function invariant
653 -- as gimple rhs, when the resulting address in not a function
654 invariant
655 We do not need to do anything special in the latter case (the base of
656 the memory reference whose address is taken may be replaced in the
657 DECL_P case). The former case is more complicated, as we need to
658 ensure that the new address is still a gimple operand. Thus, it
659 is not sufficient to replace just the base of the memory reference --
660 we need to move the whole computation of the address out of the
661 loop. */
662 if (!is_gimple_val (t))
28c92cbb 663 return NULL_TREE;
664
665 *walk_subtrees = 0;
c1fb5b25 666 obj = TREE_OPERAND (t, 0);
667 var = get_base_address (obj);
668 if (!var || !SSA_VAR_P (var) || DECL_EXTERNAL (var))
28c92cbb 669 return NULL_TREE;
670
671 addr_type = TREE_TYPE (t);
ad57283e 672 addr = take_address_of (obj, addr_type, dta->entry, dta->decl_address,
673 dta->gsi);
674 if (dta->gsi == NULL && addr == NULL_TREE)
675 {
676 dta->reset = true;
677 return NULL_TREE;
678 }
28c92cbb 679 *tp = addr;
680
681 dta->changed = true;
682 return NULL_TREE;
683 }
684
75a70cf9 685 if (!EXPR_P (t))
28c92cbb 686 *walk_subtrees = 0;
687
688 return NULL_TREE;
689}
690
ad57283e 691/* Moves the references to local variables in STMT at *GSI out of the single
e06f9c34 692 entry single exit region starting at ENTRY. DECL_ADDRESS contains
693 addresses of the references that had their address taken
694 already. */
28c92cbb 695
696static void
ad57283e 697eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi,
c1f445d2 698 int_tree_htab_type *decl_address)
28c92cbb 699{
700 struct elv_data dta;
42acab1c 701 gimple *stmt = gsi_stmt (*gsi);
28c92cbb 702
75a70cf9 703 memset (&dta.info, '\0', sizeof (dta.info));
e06f9c34 704 dta.entry = entry;
28c92cbb 705 dta.decl_address = decl_address;
706 dta.changed = false;
ad57283e 707 dta.reset = false;
28c92cbb 708
9845d120 709 if (gimple_debug_bind_p (stmt))
ad57283e 710 {
711 dta.gsi = NULL;
712 walk_tree (gimple_debug_bind_get_value_ptr (stmt),
713 eliminate_local_variables_1, &dta.info, NULL);
714 if (dta.reset)
715 {
716 gimple_debug_bind_reset_value (stmt);
717 dta.changed = true;
718 }
719 }
a7c17572 720 else if (gimple_clobber_p (stmt))
721 {
722 stmt = gimple_build_nop ();
723 gsi_replace (gsi, stmt, false);
724 dta.changed = true;
725 }
9845d120 726 else
ad57283e 727 {
728 dta.gsi = gsi;
729 walk_gimple_op (stmt, eliminate_local_variables_1, &dta.info);
730 }
28c92cbb 731
732 if (dta.changed)
733 update_stmt (stmt);
734}
735
e06f9c34 736/* Eliminates the references to local variables from the single entry
737 single exit region between the ENTRY and EXIT edges.
48e1416a 738
cb7f680b 739 This includes:
48e1416a 740 1) Taking address of a local variable -- these are moved out of the
741 region (and temporary variable is created to hold the address if
cb7f680b 742 necessary).
e06f9c34 743
28c92cbb 744 2) Dereferencing a local variable -- these are replaced with indirect
cb7f680b 745 references. */
28c92cbb 746
747static void
e06f9c34 748eliminate_local_variables (edge entry, edge exit)
28c92cbb 749{
e06f9c34 750 basic_block bb;
4997014d 751 auto_vec<basic_block, 3> body;
28c92cbb 752 unsigned i;
75a70cf9 753 gimple_stmt_iterator gsi;
ad57283e 754 bool has_debug_stmt = false;
c1f445d2 755 int_tree_htab_type decl_address (10);
e06f9c34 756 basic_block entry_bb = entry->src;
757 basic_block exit_bb = exit->dest;
28c92cbb 758
e06f9c34 759 gather_blocks_in_sese_region (entry_bb, exit_bb, &body);
28c92cbb 760
f1f41a6c 761 FOR_EACH_VEC_ELT (body, i, bb)
e06f9c34 762 if (bb != entry_bb && bb != exit_bb)
75a70cf9 763 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
841424cc 764 if (is_gimple_debug (gsi_stmt (gsi)))
765 {
766 if (gimple_debug_bind_p (gsi_stmt (gsi)))
767 has_debug_stmt = true;
768 }
ad57283e 769 else
c1f445d2 770 eliminate_local_variables_stmt (entry, &gsi, &decl_address);
ad57283e 771
772 if (has_debug_stmt)
f1f41a6c 773 FOR_EACH_VEC_ELT (body, i, bb)
ad57283e 774 if (bb != entry_bb && bb != exit_bb)
775 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
776 if (gimple_debug_bind_p (gsi_stmt (gsi)))
c1f445d2 777 eliminate_local_variables_stmt (entry, &gsi, &decl_address);
e06f9c34 778}
779
780/* Returns true if expression EXPR is not defined between ENTRY and
781 EXIT, i.e. if all its operands are defined outside of the region. */
782
783static bool
784expr_invariant_in_region_p (edge entry, edge exit, tree expr)
785{
786 basic_block entry_bb = entry->src;
787 basic_block exit_bb = exit->dest;
788 basic_block def_bb;
e06f9c34 789
790 if (is_gimple_min_invariant (expr))
791 return true;
792
793 if (TREE_CODE (expr) == SSA_NAME)
794 {
75a70cf9 795 def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
e06f9c34 796 if (def_bb
797 && dominated_by_p (CDI_DOMINATORS, def_bb, entry_bb)
798 && !dominated_by_p (CDI_DOMINATORS, def_bb, exit_bb))
799 return false;
800
801 return true;
802 }
803
75a70cf9 804 return false;
28c92cbb 805}
806
807/* If COPY_NAME_P is true, creates and returns a duplicate of NAME.
808 The copies are stored to NAME_COPIES, if NAME was already duplicated,
809 its duplicate stored in NAME_COPIES is returned.
48e1416a 810
28c92cbb 811 Regardless of COPY_NAME_P, the decl used as a base of the ssa name is also
812 duplicated, storing the copies in DECL_COPIES. */
813
814static tree
c1f445d2 815separate_decls_in_region_name (tree name, name_to_copy_table_type *name_copies,
816 int_tree_htab_type *decl_copies,
817 bool copy_name_p)
28c92cbb 818{
819 tree copy, var, var_copy;
820 unsigned idx, uid, nuid;
2933f7af 821 struct int_tree_map ielt;
28c92cbb 822 struct name_to_copy_elt elt, *nelt;
d9dd21a8 823 name_to_copy_elt **slot;
2933f7af 824 int_tree_map *dslot;
28c92cbb 825
826 if (TREE_CODE (name) != SSA_NAME)
827 return name;
828
829 idx = SSA_NAME_VERSION (name);
830 elt.version = idx;
c1f445d2 831 slot = name_copies->find_slot_with_hash (&elt, idx,
832 copy_name_p ? INSERT : NO_INSERT);
28c92cbb 833 if (slot && *slot)
d9dd21a8 834 return (*slot)->new_name;
28c92cbb 835
ec11736b 836 if (copy_name_p)
837 {
838 copy = duplicate_ssa_name (name, NULL);
839 nelt = XNEW (struct name_to_copy_elt);
840 nelt->version = idx;
841 nelt->new_name = copy;
842 nelt->field = NULL_TREE;
843 *slot = nelt;
844 }
845 else
846 {
847 gcc_assert (!slot);
848 copy = name;
849 }
850
28c92cbb 851 var = SSA_NAME_VAR (name);
ec11736b 852 if (!var)
853 return copy;
854
28c92cbb 855 uid = DECL_UID (var);
856 ielt.uid = uid;
2933f7af 857 dslot = decl_copies->find_slot_with_hash (ielt, uid, INSERT);
858 if (!dslot->to)
28c92cbb 859 {
860 var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
55ed4df6 861 DECL_GIMPLE_REG_P (var_copy) = DECL_GIMPLE_REG_P (var);
2933f7af 862 dslot->uid = uid;
863 dslot->to = var_copy;
28c92cbb 864
865 /* Ensure that when we meet this decl next time, we won't duplicate
cb7f680b 866 it again. */
28c92cbb 867 nuid = DECL_UID (var_copy);
868 ielt.uid = nuid;
2933f7af 869 dslot = decl_copies->find_slot_with_hash (ielt, nuid, INSERT);
870 gcc_assert (!dslot->to);
871 dslot->uid = nuid;
872 dslot->to = var_copy;
28c92cbb 873 }
874 else
2933f7af 875 var_copy = dslot->to;
28c92cbb 876
3b652cc1 877 replace_ssa_name_symbol (copy, var_copy);
28c92cbb 878 return copy;
879}
880
e06f9c34 881/* Finds the ssa names used in STMT that are defined outside the
882 region between ENTRY and EXIT and replaces such ssa names with
883 their duplicates. The duplicates are stored to NAME_COPIES. Base
884 decls of all ssa names used in STMT (including those defined in
885 LOOP) are replaced with the new temporary variables; the
886 replacement decls are stored in DECL_COPIES. */
28c92cbb 887
888static void
42acab1c 889separate_decls_in_region_stmt (edge entry, edge exit, gimple *stmt,
c1f445d2 890 name_to_copy_table_type *name_copies,
891 int_tree_htab_type *decl_copies)
28c92cbb 892{
893 use_operand_p use;
894 def_operand_p def;
895 ssa_op_iter oi;
896 tree name, copy;
897 bool copy_name_p;
898
28c92cbb 899 FOR_EACH_PHI_OR_STMT_DEF (def, stmt, oi, SSA_OP_DEF)
cb7f680b 900 {
901 name = DEF_FROM_PTR (def);
902 gcc_assert (TREE_CODE (name) == SSA_NAME);
e06f9c34 903 copy = separate_decls_in_region_name (name, name_copies, decl_copies,
904 false);
cb7f680b 905 gcc_assert (copy == name);
906 }
28c92cbb 907
908 FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE)
cb7f680b 909 {
910 name = USE_FROM_PTR (use);
911 if (TREE_CODE (name) != SSA_NAME)
912 continue;
913
e06f9c34 914 copy_name_p = expr_invariant_in_region_p (entry, exit, name);
915 copy = separate_decls_in_region_name (name, name_copies, decl_copies,
916 copy_name_p);
cb7f680b 917 SET_USE (use, copy);
918 }
28c92cbb 919}
920
9845d120 921/* Finds the ssa names used in STMT that are defined outside the
922 region between ENTRY and EXIT and replaces such ssa names with
923 their duplicates. The duplicates are stored to NAME_COPIES. Base
924 decls of all ssa names used in STMT (including those defined in
925 LOOP) are replaced with the new temporary variables; the
926 replacement decls are stored in DECL_COPIES. */
927
928static bool
42acab1c 929separate_decls_in_region_debug (gimple *stmt,
c1f445d2 930 name_to_copy_table_type *name_copies,
931 int_tree_htab_type *decl_copies)
9845d120 932{
933 use_operand_p use;
934 ssa_op_iter oi;
935 tree var, name;
936 struct int_tree_map ielt;
937 struct name_to_copy_elt elt;
d9dd21a8 938 name_to_copy_elt **slot;
2933f7af 939 int_tree_map *dslot;
9845d120 940
841424cc 941 if (gimple_debug_bind_p (stmt))
942 var = gimple_debug_bind_get_var (stmt);
943 else if (gimple_debug_source_bind_p (stmt))
944 var = gimple_debug_source_bind_get_var (stmt);
945 else
946 return true;
eee873f6 947 if (TREE_CODE (var) == DEBUG_EXPR_DECL || TREE_CODE (var) == LABEL_DECL)
9e3c8673 948 return true;
9845d120 949 gcc_assert (DECL_P (var) && SSA_VAR_P (var));
950 ielt.uid = DECL_UID (var);
2933f7af 951 dslot = decl_copies->find_slot_with_hash (ielt, ielt.uid, NO_INSERT);
9845d120 952 if (!dslot)
953 return true;
841424cc 954 if (gimple_debug_bind_p (stmt))
2933f7af 955 gimple_debug_bind_set_var (stmt, dslot->to);
841424cc 956 else if (gimple_debug_source_bind_p (stmt))
2933f7af 957 gimple_debug_source_bind_set_var (stmt, dslot->to);
9845d120 958
959 FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE)
960 {
961 name = USE_FROM_PTR (use);
962 if (TREE_CODE (name) != SSA_NAME)
963 continue;
964
965 elt.version = SSA_NAME_VERSION (name);
c1f445d2 966 slot = name_copies->find_slot_with_hash (&elt, elt.version, NO_INSERT);
9845d120 967 if (!slot)
968 {
969 gimple_debug_bind_reset_value (stmt);
970 update_stmt (stmt);
971 break;
972 }
973
d9dd21a8 974 SET_USE (use, (*slot)->new_name);
9845d120 975 }
976
977 return false;
978}
979
848674d0 980/* Callback for htab_traverse. Adds a field corresponding to the reduction
981 specified in SLOT. The type is passed in DATA. */
982
d9dd21a8 983int
984add_field_for_reduction (reduction_info **slot, tree type)
cb7f680b 985{
48e1416a 986
d9dd21a8 987 struct reduction_info *const red = *slot;
95f4166a 988 tree var = reduc_stmt_res (red->reduc_stmt);
59c0ed80 989 tree field = build_decl (gimple_location (red->reduc_stmt), FIELD_DECL,
990 SSA_NAME_IDENTIFIER (var), TREE_TYPE (var));
848674d0 991
992 insert_field_into_struct (type, field);
993
994 red->field = field;
995
996 return 1;
997}
cb7f680b 998
28c92cbb 999/* Callback for htab_traverse. Adds a field corresponding to a ssa name
48e1416a 1000 described in SLOT. The type is passed in DATA. */
28c92cbb 1001
d9dd21a8 1002int
1003add_field_for_name (name_to_copy_elt **slot, tree type)
28c92cbb 1004{
d9dd21a8 1005 struct name_to_copy_elt *const elt = *slot;
28c92cbb 1006 tree name = ssa_name (elt->version);
ec11736b 1007 tree field = build_decl (UNKNOWN_LOCATION,
1008 FIELD_DECL, SSA_NAME_IDENTIFIER (name),
1009 TREE_TYPE (name));
28c92cbb 1010
1011 insert_field_into_struct (type, field);
1012 elt->field = field;
cb7f680b 1013
28c92cbb 1014 return 1;
1015}
1016
48e1416a 1017/* Callback for htab_traverse. A local result is the intermediate result
1018 computed by a single
f0b5f617 1019 thread, or the initial value in case no iteration was executed.
48e1416a 1020 This function creates a phi node reflecting these values.
1021 The phi's result will be stored in NEW_PHI field of the
1022 reduction's data structure. */
cb7f680b 1023
d9dd21a8 1024int
1025create_phi_for_local_result (reduction_info **slot, struct loop *loop)
cb7f680b 1026{
d9dd21a8 1027 struct reduction_info *const reduc = *slot;
cb7f680b 1028 edge e;
1a91d914 1029 gphi *new_phi;
86a932e0 1030 basic_block store_bb, continue_bb;
cb7f680b 1031 tree local_res;
efbcb6de 1032 source_location locus;
cb7f680b 1033
48e1416a 1034 /* STORE_BB is the block where the phi
1035 should be stored. It is the destination of the loop exit.
75a70cf9 1036 (Find the fallthru edge from GIMPLE_OMP_CONTINUE). */
86a932e0 1037 continue_bb = single_pred (loop->latch);
1038 store_bb = FALLTHRU_EDGE (continue_bb)->dest;
cb7f680b 1039
1040 /* STORE_BB has two predecessors. One coming from the loop
1041 (the reduction's result is computed at the loop),
48e1416a 1042 and another coming from a block preceding the loop,
1043 when no iterations
1044 are executed (the initial value should be taken). */
86a932e0 1045 if (EDGE_PRED (store_bb, 0) == FALLTHRU_EDGE (continue_bb))
cb7f680b 1046 e = EDGE_PRED (store_bb, 1);
1047 else
1048 e = EDGE_PRED (store_bb, 0);
95f4166a 1049 tree lhs = reduc_stmt_res (reduc->reduc_stmt);
1050 local_res = copy_ssa_name (lhs);
efbcb6de 1051 locus = gimple_location (reduc->reduc_stmt);
cb7f680b 1052 new_phi = create_phi_node (local_res, store_bb);
60d535d2 1053 add_phi_arg (new_phi, reduc->init, e, locus);
86a932e0 1054 add_phi_arg (new_phi, lhs, FALLTHRU_EDGE (continue_bb), locus);
cb7f680b 1055 reduc->new_phi = new_phi;
1056
1057 return 1;
1058}
28c92cbb 1059
1060struct clsn_data
1061{
1062 tree store;
1063 tree load;
1064
1065 basic_block store_bb;
1066 basic_block load_bb;
1067};
1068
cb7f680b 1069/* Callback for htab_traverse. Create an atomic instruction for the
48e1416a 1070 reduction described in SLOT.
cb7f680b 1071 DATA annotates the place in memory the atomic operation relates to,
1072 and the basic block it needs to be generated in. */
1073
d9dd21a8 1074int
1075create_call_for_reduction_1 (reduction_info **slot, struct clsn_data *clsn_data)
cb7f680b 1076{
d9dd21a8 1077 struct reduction_info *const reduc = *slot;
75a70cf9 1078 gimple_stmt_iterator gsi;
cb7f680b 1079 tree type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
cb7f680b 1080 tree load_struct;
1081 basic_block bb;
1082 basic_block new_bb;
1083 edge e;
f018d957 1084 tree t, addr, ref, x;
75a70cf9 1085 tree tmp_load, name;
42acab1c 1086 gimple *load;
cb7f680b 1087
182cf5a9 1088 load_struct = build_simple_mem_ref (clsn_data->load);
cb7f680b 1089 t = build3 (COMPONENT_REF, type, load_struct, reduc->field, NULL_TREE);
cb7f680b 1090
0e49e441 1091 addr = build_addr (t);
cb7f680b 1092
1093 /* Create phi node. */
1094 bb = clsn_data->load_bb;
1095
923635e7 1096 gsi = gsi_last_bb (bb);
1097 e = split_block (bb, gsi_stmt (gsi));
cb7f680b 1098 new_bb = e->dest;
1099
f9e245b2 1100 tmp_load = create_tmp_var (TREE_TYPE (TREE_TYPE (addr)));
1101 tmp_load = make_ssa_name (tmp_load);
75a70cf9 1102 load = gimple_build_omp_atomic_load (tmp_load, addr);
cb7f680b 1103 SSA_NAME_DEF_STMT (tmp_load) = load;
75a70cf9 1104 gsi = gsi_start_bb (new_bb);
1105 gsi_insert_after (&gsi, load, GSI_NEW_STMT);
cb7f680b 1106
1107 e = split_block (new_bb, load);
1108 new_bb = e->dest;
75a70cf9 1109 gsi = gsi_start_bb (new_bb);
cb7f680b 1110 ref = tmp_load;
75a70cf9 1111 x = fold_build2 (reduc->reduction_code,
1112 TREE_TYPE (PHI_RESULT (reduc->new_phi)), ref,
1113 PHI_RESULT (reduc->new_phi));
cb7f680b 1114
75a70cf9 1115 name = force_gimple_operand_gsi (&gsi, x, true, NULL_TREE, true,
1116 GSI_CONTINUE_LINKING);
cb7f680b 1117
75a70cf9 1118 gsi_insert_after (&gsi, gimple_build_omp_atomic_store (name), GSI_NEW_STMT);
cb7f680b 1119 return 1;
1120}
1121
48e1416a 1122/* Create the atomic operation at the join point of the threads.
1123 REDUCTION_LIST describes the reductions in the LOOP.
1124 LD_ST_DATA describes the shared data structure where
cb7f680b 1125 shared data is stored in and loaded from. */
1126static void
d9dd21a8 1127create_call_for_reduction (struct loop *loop,
c1f445d2 1128 reduction_info_table_type *reduction_list,
cb7f680b 1129 struct clsn_data *ld_st_data)
1130{
c1f445d2 1131 reduction_list->traverse <struct loop *, create_phi_for_local_result> (loop);
75a70cf9 1132 /* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
86a932e0 1133 basic_block continue_bb = single_pred (loop->latch);
1134 ld_st_data->load_bb = FALLTHRU_EDGE (continue_bb)->dest;
d9dd21a8 1135 reduction_list
c1f445d2 1136 ->traverse <struct clsn_data *, create_call_for_reduction_1> (ld_st_data);
cb7f680b 1137}
1138
5bb62c99 1139/* Callback for htab_traverse. Loads the final reduction value at the
1140 join point of all threads, and inserts it in the right place. */
cb7f680b 1141
d9dd21a8 1142int
1143create_loads_for_reductions (reduction_info **slot, struct clsn_data *clsn_data)
cb7f680b 1144{
d9dd21a8 1145 struct reduction_info *const red = *slot;
42acab1c 1146 gimple *stmt;
75a70cf9 1147 gimple_stmt_iterator gsi;
95f4166a 1148 tree type = TREE_TYPE (reduc_stmt_res (red->reduc_stmt));
cb7f680b 1149 tree load_struct;
5bb62c99 1150 tree name;
cb7f680b 1151 tree x;
1152
de46ad2e 1153 /* If there's no exit phi, the result of the reduction is unused. */
1154 if (red->keep_res == NULL)
1155 return 1;
1156
75a70cf9 1157 gsi = gsi_after_labels (clsn_data->load_bb);
182cf5a9 1158 load_struct = build_simple_mem_ref (clsn_data->load);
cb7f680b 1159 load_struct = build3 (COMPONENT_REF, type, load_struct, red->field,
1160 NULL_TREE);
cb7f680b 1161
5bb62c99 1162 x = load_struct;
cb7f680b 1163 name = PHI_RESULT (red->keep_res);
75a70cf9 1164 stmt = gimple_build_assign (name, x);
cb7f680b 1165
75a70cf9 1166 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
cb7f680b 1167
75a70cf9 1168 for (gsi = gsi_start_phis (gimple_bb (red->keep_res));
1169 !gsi_end_p (gsi); gsi_next (&gsi))
1170 if (gsi_stmt (gsi) == red->keep_res)
1171 {
1172 remove_phi_node (&gsi, false);
1173 return 1;
1174 }
1175 gcc_unreachable ();
cb7f680b 1176}
1177
48e1416a 1178/* Load the reduction result that was stored in LD_ST_DATA.
cb7f680b 1179 REDUCTION_LIST describes the list of reductions that the
f0b5f617 1180 loads should be generated for. */
cb7f680b 1181static void
c1f445d2 1182create_final_loads_for_reduction (reduction_info_table_type *reduction_list,
cb7f680b 1183 struct clsn_data *ld_st_data)
1184{
75a70cf9 1185 gimple_stmt_iterator gsi;
cb7f680b 1186 tree t;
42acab1c 1187 gimple *stmt;
cb7f680b 1188
75a70cf9 1189 gsi = gsi_after_labels (ld_st_data->load_bb);
cb7f680b 1190 t = build_fold_addr_expr (ld_st_data->store);
75a70cf9 1191 stmt = gimple_build_assign (ld_st_data->load, t);
cb7f680b 1192
75a70cf9 1193 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
cb7f680b 1194
d9dd21a8 1195 reduction_list
c1f445d2 1196 ->traverse <struct clsn_data *, create_loads_for_reductions> (ld_st_data);
cb7f680b 1197
1198}
1199
848674d0 1200/* Callback for htab_traverse. Store the neutral value for the
1201 particular reduction's operation, e.g. 0 for PLUS_EXPR,
1202 1 for MULT_EXPR, etc. into the reduction field.
48e1416a 1203 The reduction is specified in SLOT. The store information is
1204 passed in DATA. */
848674d0 1205
d9dd21a8 1206int
1207create_stores_for_reduction (reduction_info **slot, struct clsn_data *clsn_data)
848674d0 1208{
d9dd21a8 1209 struct reduction_info *const red = *slot;
75a70cf9 1210 tree t;
42acab1c 1211 gimple *stmt;
75a70cf9 1212 gimple_stmt_iterator gsi;
95f4166a 1213 tree type = TREE_TYPE (reduc_stmt_res (red->reduc_stmt));
75a70cf9 1214
1215 gsi = gsi_last_bb (clsn_data->store_bb);
1216 t = build3 (COMPONENT_REF, type, clsn_data->store, red->field, NULL_TREE);
1217 stmt = gimple_build_assign (t, red->initial_value);
75a70cf9 1218 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
848674d0 1219
1220 return 1;
1221}
1222
cb7f680b 1223/* Callback for htab_traverse. Creates loads to a field of LOAD in LOAD_BB and
1224 store to a field of STORE in STORE_BB for the ssa name and its duplicate
1225 specified in SLOT. */
1226
d9dd21a8 1227int
1228create_loads_and_stores_for_name (name_to_copy_elt **slot,
1229 struct clsn_data *clsn_data)
28c92cbb 1230{
d9dd21a8 1231 struct name_to_copy_elt *const elt = *slot;
75a70cf9 1232 tree t;
42acab1c 1233 gimple *stmt;
75a70cf9 1234 gimple_stmt_iterator gsi;
28c92cbb 1235 tree type = TREE_TYPE (elt->new_name);
28c92cbb 1236 tree load_struct;
1237
75a70cf9 1238 gsi = gsi_last_bb (clsn_data->store_bb);
1239 t = build3 (COMPONENT_REF, type, clsn_data->store, elt->field, NULL_TREE);
1240 stmt = gimple_build_assign (t, ssa_name (elt->version));
75a70cf9 1241 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1242
75a70cf9 1243 gsi = gsi_last_bb (clsn_data->load_bb);
182cf5a9 1244 load_struct = build_simple_mem_ref (clsn_data->load);
75a70cf9 1245 t = build3 (COMPONENT_REF, type, load_struct, elt->field, NULL_TREE);
1246 stmt = gimple_build_assign (elt->new_name, t);
75a70cf9 1247 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1248
1249 return 1;
1250}
1251
1252/* Moves all the variables used in LOOP and defined outside of it (including
1253 the initial values of loop phi nodes, and *PER_THREAD if it is a ssa
1254 name) to a structure created for this purpose. The code
48e1416a 1255
28c92cbb 1256 while (1)
1257 {
1258 use (a);
1259 use (b);
1260 }
1261
1262 is transformed this way:
1263
1264 bb0:
1265 old.a = a;
1266 old.b = b;
1267
1268 bb1:
1269 a' = new->a;
1270 b' = new->b;
1271 while (1)
1272 {
1273 use (a');
1274 use (b');
1275 }
1276
1277 `old' is stored to *ARG_STRUCT and `new' is stored to NEW_ARG_STRUCT. The
1278 pointer `new' is intentionally not initialized (the loop will be split to a
1279 separate function later, and `new' will be initialized from its arguments).
cb7f680b 1280 LD_ST_DATA holds information about the shared data structure used to pass
48e1416a 1281 information among the threads. It is initialized here, and
1282 gen_parallel_loop will pass it to create_call_for_reduction that
1283 needs this information. REDUCTION_LIST describes the reductions
cb7f680b 1284 in LOOP. */
28c92cbb 1285
1286static void
d9dd21a8 1287separate_decls_in_region (edge entry, edge exit,
c1f445d2 1288 reduction_info_table_type *reduction_list,
48e1416a 1289 tree *arg_struct, tree *new_arg_struct,
e06f9c34 1290 struct clsn_data *ld_st_data)
cb7f680b 1291
28c92cbb 1292{
e06f9c34 1293 basic_block bb1 = split_edge (entry);
28c92cbb 1294 basic_block bb0 = single_pred (bb1);
c1f445d2 1295 name_to_copy_table_type name_copies (10);
1296 int_tree_htab_type decl_copies (10);
28c92cbb 1297 unsigned i;
75a70cf9 1298 tree type, type_name, nvar;
1299 gimple_stmt_iterator gsi;
28c92cbb 1300 struct clsn_data clsn_data;
4997014d 1301 auto_vec<basic_block, 3> body;
e06f9c34 1302 basic_block bb;
1303 basic_block entry_bb = bb1;
1304 basic_block exit_bb = exit->dest;
9845d120 1305 bool has_debug_stmt = false;
28c92cbb 1306
75a70cf9 1307 entry = single_succ_edge (entry_bb);
e06f9c34 1308 gather_blocks_in_sese_region (entry_bb, exit_bb, &body);
28c92cbb 1309
f1f41a6c 1310 FOR_EACH_VEC_ELT (body, i, bb)
e06f9c34 1311 {
48e1416a 1312 if (bb != entry_bb && bb != exit_bb)
e06f9c34 1313 {
75a70cf9 1314 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1315 separate_decls_in_region_stmt (entry, exit, gsi_stmt (gsi),
c1f445d2 1316 &name_copies, &decl_copies);
75a70cf9 1317
1318 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
9845d120 1319 {
42acab1c 1320 gimple *stmt = gsi_stmt (gsi);
9845d120 1321
1322 if (is_gimple_debug (stmt))
1323 has_debug_stmt = true;
1324 else
1325 separate_decls_in_region_stmt (entry, exit, stmt,
c1f445d2 1326 &name_copies, &decl_copies);
9845d120 1327 }
e06f9c34 1328 }
28c92cbb 1329 }
e06f9c34 1330
9845d120 1331 /* Now process debug bind stmts. We must not create decls while
1332 processing debug stmts, so we defer their processing so as to
1333 make sure we will have debug info for as many variables as
1334 possible (all of those that were dealt with in the loop above),
1335 and discard those for which we know there's nothing we can
1336 do. */
1337 if (has_debug_stmt)
f1f41a6c 1338 FOR_EACH_VEC_ELT (body, i, bb)
9845d120 1339 if (bb != entry_bb && bb != exit_bb)
1340 {
1341 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1342 {
42acab1c 1343 gimple *stmt = gsi_stmt (gsi);
9845d120 1344
841424cc 1345 if (is_gimple_debug (stmt))
9845d120 1346 {
c1f445d2 1347 if (separate_decls_in_region_debug (stmt, &name_copies,
1348 &decl_copies))
9845d120 1349 {
1350 gsi_remove (&gsi, true);
1351 continue;
1352 }
1353 }
1354
1355 gsi_next (&gsi);
1356 }
1357 }
1358
c1f445d2 1359 if (name_copies.elements () == 0 && reduction_list->elements () == 0)
28c92cbb 1360 {
1361 /* It may happen that there is nothing to copy (if there are only
cb7f680b 1362 loop carried and external variables in the loop). */
28c92cbb 1363 *arg_struct = NULL;
1364 *new_arg_struct = NULL;
1365 }
1366 else
1367 {
1368 /* Create the type for the structure to store the ssa names to. */
1369 type = lang_hooks.types.make_type (RECORD_TYPE);
0aecb55e 1370 type_name = build_decl (UNKNOWN_LOCATION,
e60a6f7b 1371 TYPE_DECL, create_tmp_var_name (".paral_data"),
28c92cbb 1372 type);
1373 TYPE_NAME (type) = type_name;
1374
d9dd21a8 1375 name_copies.traverse <tree, add_field_for_name> (type);
c1f445d2 1376 if (reduction_list && reduction_list->elements () > 0)
848674d0 1377 {
1378 /* Create the fields for reductions. */
c1f445d2 1379 reduction_list->traverse <tree, add_field_for_reduction> (type);
848674d0 1380 }
28c92cbb 1381 layout_type (type);
48e1416a 1382
28c92cbb 1383 /* Create the loads and stores. */
1384 *arg_struct = create_tmp_var (type, ".paral_data_store");
28c92cbb 1385 nvar = create_tmp_var (build_pointer_type (type), ".paral_data_load");
f9e245b2 1386 *new_arg_struct = make_ssa_name (nvar);
28c92cbb 1387
cb7f680b 1388 ld_st_data->store = *arg_struct;
1389 ld_st_data->load = *new_arg_struct;
1390 ld_st_data->store_bb = bb0;
1391 ld_st_data->load_bb = bb1;
848674d0 1392
d9dd21a8 1393 name_copies
1394 .traverse <struct clsn_data *, create_loads_and_stores_for_name>
1395 (ld_st_data);
cb7f680b 1396
5bb62c99 1397 /* Load the calculation from memory (after the join of the threads). */
1398
c1f445d2 1399 if (reduction_list && reduction_list->elements () > 0)
cb7f680b 1400 {
d9dd21a8 1401 reduction_list
c1f445d2 1402 ->traverse <struct clsn_data *, create_stores_for_reduction>
1403 (ld_st_data);
f9e245b2 1404 clsn_data.load = make_ssa_name (nvar);
e06f9c34 1405 clsn_data.load_bb = exit->dest;
cb7f680b 1406 clsn_data.store = ld_st_data->store;
1407 create_final_loads_for_reduction (reduction_list, &clsn_data);
1408 }
28c92cbb 1409 }
28c92cbb 1410}
1411
66460ec1 1412/* Returns true if FN was created to run in parallel. */
28c92cbb 1413
479a6d79 1414bool
66460ec1 1415parallelized_function_p (tree fndecl)
28c92cbb 1416{
66460ec1 1417 cgraph_node *node = cgraph_node::get (fndecl);
1418 gcc_assert (node != NULL);
1419 return node->parallelized_function;
28c92cbb 1420}
1421
1422/* Creates and returns an empty function that will receive the body of
1423 a parallelized loop. */
1424
1425static tree
0aecb55e 1426create_loop_fn (location_t loc)
28c92cbb 1427{
1428 char buf[100];
1429 char *tname;
1430 tree decl, type, name, t;
1431 struct function *act_cfun = cfun;
1432 static unsigned loopfn_num;
1433
5169661d 1434 loc = LOCATION_LOCUS (loc);
28c92cbb 1435 snprintf (buf, 100, "%s.$loopfn", current_function_name ());
1436 ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
1437 clean_symbol_name (tname);
1438 name = get_identifier (tname);
1439 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1440
0aecb55e 1441 decl = build_decl (loc, FUNCTION_DECL, name, type);
28c92cbb 1442 TREE_STATIC (decl) = 1;
1443 TREE_USED (decl) = 1;
1444 DECL_ARTIFICIAL (decl) = 1;
1445 DECL_IGNORED_P (decl) = 0;
1446 TREE_PUBLIC (decl) = 0;
1447 DECL_UNINLINABLE (decl) = 1;
1448 DECL_EXTERNAL (decl) = 0;
1449 DECL_CONTEXT (decl) = NULL_TREE;
1450 DECL_INITIAL (decl) = make_node (BLOCK);
1451
0aecb55e 1452 t = build_decl (loc, RESULT_DECL, NULL_TREE, void_type_node);
28c92cbb 1453 DECL_ARTIFICIAL (t) = 1;
1454 DECL_IGNORED_P (t) = 1;
1455 DECL_RESULT (decl) = t;
1456
0aecb55e 1457 t = build_decl (loc, PARM_DECL, get_identifier (".paral_data_param"),
28c92cbb 1458 ptr_type_node);
1459 DECL_ARTIFICIAL (t) = 1;
1460 DECL_ARG_TYPE (t) = ptr_type_node;
1461 DECL_CONTEXT (t) = decl;
1462 TREE_USED (t) = 1;
1463 DECL_ARGUMENTS (decl) = t;
1464
80f2ef47 1465 allocate_struct_function (decl, false);
28c92cbb 1466
1467 /* The call to allocate_struct_function clobbers CFUN, so we need to restore
1468 it. */
c8a152f6 1469 set_cfun (act_cfun);
28c92cbb 1470
1471 return decl;
1472}
1473
d38409cd 1474/* Replace uses of NAME by VAL in block BB. */
1475
1476static void
1477replace_uses_in_bb_by (tree name, tree val, basic_block bb)
1478{
42acab1c 1479 gimple *use_stmt;
d38409cd 1480 imm_use_iterator imm_iter;
1481
1482 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, name)
1483 {
1484 if (gimple_bb (use_stmt) != bb)
1485 continue;
1486
1487 use_operand_p use_p;
1488 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
1489 SET_USE (use_p, val);
1490 }
1491}
1492
d38409cd 1493/* Do transformation from:
1494
1495 <bb preheader>:
1496 ...
1497 goto <bb header>
1498
1499 <bb header>:
1500 ivtmp_a = PHI <ivtmp_init (preheader), ivtmp_b (latch)>
1501 sum_a = PHI <sum_init (preheader), sum_b (latch)>
1502 ...
1503 use (ivtmp_a)
1504 ...
1505 sum_b = sum_a + sum_update
1506 ...
1507 if (ivtmp_a < n)
1508 goto <bb latch>;
1509 else
1510 goto <bb exit>;
1511
1512 <bb latch>:
1513 ivtmp_b = ivtmp_a + 1;
1514 goto <bb header>
1515
1516 <bb exit>:
5a3d2e18 1517 sum_z = PHI <sum_b (cond[1]), ...>
d38409cd 1518
1519 [1] Where <bb cond> is single_pred (bb latch); In the simplest case,
1520 that's <bb header>.
1521
1522 to:
1523
1524 <bb preheader>:
1525 ...
1526 goto <bb newheader>
1527
1528 <bb header>:
1529 ivtmp_a = PHI <ivtmp_c (latch)>
1530 sum_a = PHI <sum_c (latch)>
1531 ...
1532 use (ivtmp_a)
1533 ...
1534 sum_b = sum_a + sum_update
1535 ...
1536 goto <bb latch>;
1537
1538 <bb newheader>:
1539 ivtmp_c = PHI <ivtmp_init (preheader), ivtmp_b (latch)>
1540 sum_c = PHI <sum_init (preheader), sum_b (latch)>
1541 if (ivtmp_c < n + 1)
1542 goto <bb header>;
1543 else
5a3d2e18 1544 goto <bb newexit>;
d38409cd 1545
1546 <bb latch>:
1547 ivtmp_b = ivtmp_a + 1;
1548 goto <bb newheader>
1549
5a3d2e18 1550 <bb newexit>:
1551 sum_y = PHI <sum_c (newheader)>
1552
d38409cd 1553 <bb exit>:
5a3d2e18 1554 sum_z = PHI <sum_y (newexit), ...>
d38409cd 1555
1556
1557 In unified diff format:
1558
1559 <bb preheader>:
1560 ...
1561- goto <bb header>
1562+ goto <bb newheader>
1563
1564 <bb header>:
1565- ivtmp_a = PHI <ivtmp_init (preheader), ivtmp_b (latch)>
1566- sum_a = PHI <sum_init (preheader), sum_b (latch)>
1567+ ivtmp_a = PHI <ivtmp_c (latch)>
1568+ sum_a = PHI <sum_c (latch)>
1569 ...
1570 use (ivtmp_a)
1571 ...
1572 sum_b = sum_a + sum_update
1573 ...
1574- if (ivtmp_a < n)
1575- goto <bb latch>;
1576+ goto <bb latch>;
1577+
1578+ <bb newheader>:
1579+ ivtmp_c = PHI <ivtmp_init (preheader), ivtmp_b (latch)>
1580+ sum_c = PHI <sum_init (preheader), sum_b (latch)>
1581+ if (ivtmp_c < n + 1)
1582+ goto <bb header>;
1583 else
1584 goto <bb exit>;
1585
1586 <bb latch>:
1587 ivtmp_b = ivtmp_a + 1;
1588- goto <bb header>
1589+ goto <bb newheader>
1590
5a3d2e18 1591+ <bb newexit>:
1592+ sum_y = PHI <sum_c (newheader)>
1593
d38409cd 1594 <bb exit>:
5a3d2e18 1595- sum_z = PHI <sum_b (cond[1]), ...>
1596+ sum_z = PHI <sum_y (newexit), ...>
d38409cd 1597
1598 Note: the example does not show any virtual phis, but these are handled more
1599 or less as reductions.
48e1416a 1600
d38409cd 1601
1602 Moves the exit condition of LOOP to the beginning of its header.
1603 REDUCTION_LIST describes the reductions in LOOP. BOUND is the new loop
1604 bound. */
1605
1606static void
1607transform_to_exit_first_loop_alt (struct loop *loop,
1608 reduction_info_table_type *reduction_list,
1609 tree bound)
1610{
1611 basic_block header = loop->header;
1612 basic_block latch = loop->latch;
1613 edge exit = single_dom_exit (loop);
1614 basic_block exit_block = exit->dest;
1615 gcond *cond_stmt = as_a <gcond *> (last_stmt (exit->src));
1616 tree control = gimple_cond_lhs (cond_stmt);
1617 edge e;
1618
4d7c6f77 1619 /* Rewriting virtuals into loop-closed ssa normal form makes this
1620 transformation simpler. It also ensures that the virtuals are in
1621 loop-closed ssa normal from after the transformation, which is required by
1622 create_parallel_loop. */
1623 rewrite_virtuals_into_loop_closed_ssa (loop);
d38409cd 1624
1625 /* Create the new_header block. */
1626 basic_block new_header = split_block_before_cond_jump (exit->src);
5a3d2e18 1627 edge edge_at_split = single_pred_edge (new_header);
d38409cd 1628
1629 /* Redirect entry edge to new_header. */
1630 edge entry = loop_preheader_edge (loop);
1631 e = redirect_edge_and_branch (entry, new_header);
1632 gcc_assert (e == entry);
1633
1634 /* Redirect post_inc_edge to new_header. */
1635 edge post_inc_edge = single_succ_edge (latch);
1636 e = redirect_edge_and_branch (post_inc_edge, new_header);
1637 gcc_assert (e == post_inc_edge);
1638
1639 /* Redirect post_cond_edge to header. */
1640 edge post_cond_edge = single_pred_edge (latch);
1641 e = redirect_edge_and_branch (post_cond_edge, header);
1642 gcc_assert (e == post_cond_edge);
1643
5a3d2e18 1644 /* Redirect edge_at_split to latch. */
1645 e = redirect_edge_and_branch (edge_at_split, latch);
1646 gcc_assert (e == edge_at_split);
d38409cd 1647
1648 /* Set the new loop bound. */
1649 gimple_cond_set_rhs (cond_stmt, bound);
7f2289e8 1650 update_stmt (cond_stmt);
d38409cd 1651
1652 /* Repair the ssa. */
1653 vec<edge_var_map> *v = redirect_edge_var_map_vector (post_inc_edge);
1654 edge_var_map *vm;
1655 gphi_iterator gsi;
4d7c6f77 1656 int i;
d38409cd 1657 for (gsi = gsi_start_phis (header), i = 0;
1658 !gsi_end_p (gsi) && v->iterate (i, &vm);
1659 gsi_next (&gsi), i++)
1660 {
1661 gphi *phi = gsi.phi ();
1662 tree res_a = PHI_RESULT (phi);
1663
1664 /* Create new phi. */
1665 tree res_c = copy_ssa_name (res_a, phi);
1666 gphi *nphi = create_phi_node (res_c, new_header);
1667
1668 /* Replace ivtmp_a with ivtmp_c in condition 'if (ivtmp_a < n)'. */
1669 replace_uses_in_bb_by (res_a, res_c, new_header);
1670
1671 /* Replace ivtmp/sum_b with ivtmp/sum_c in header phi. */
1672 add_phi_arg (phi, res_c, post_cond_edge, UNKNOWN_LOCATION);
1673
4d7c6f77 1674 /* Replace sum_b with sum_c in exit phi. */
d38409cd 1675 tree res_b = redirect_edge_var_map_def (vm);
4d7c6f77 1676 replace_uses_in_bb_by (res_b, res_c, exit_block);
d38409cd 1677
1678 struct reduction_info *red = reduction_phi (reduction_list, phi);
1679 gcc_assert (virtual_operand_p (res_a)
1680 || res_a == control
1681 || red != NULL);
1682
1683 if (red)
1684 {
1685 /* Register the new reduction phi. */
1686 red->reduc_phi = nphi;
1687 gimple_set_uid (red->reduc_phi, red->reduc_version);
1688 }
1689 }
1690 gcc_assert (gsi_end_p (gsi) && !v->iterate (i, &vm));
d38409cd 1691
1692 /* Set the preheader argument of the new phis to ivtmp/sum_init. */
1693 flush_pending_stmts (entry);
1694
1695 /* Set the latch arguments of the new phis to ivtmp/sum_b. */
1696 flush_pending_stmts (post_inc_edge);
1697
5a3d2e18 1698 /* Create a new empty exit block, inbetween the new loop header and the old
1699 exit block. The function separate_decls_in_region needs this block to
1700 insert code that is active on loop exit, but not any other path. */
1701 basic_block new_exit_block = split_edge (exit);
1702
1703 /* Insert and register the reduction exit phis. */
d38409cd 1704 for (gphi_iterator gsi = gsi_start_phis (exit_block);
1705 !gsi_end_p (gsi);
1706 gsi_next (&gsi))
1707 {
1708 gphi *phi = gsi.phi ();
1709 tree res_z = PHI_RESULT (phi);
5a3d2e18 1710
1711 /* Now that we have a new exit block, duplicate the phi of the old exit
1712 block in the new exit block to preserve loop-closed ssa. */
1713 edge succ_new_exit_block = single_succ_edge (new_exit_block);
1714 edge pred_new_exit_block = single_pred_edge (new_exit_block);
1715 tree res_y = copy_ssa_name (res_z, phi);
1716 gphi *nphi = create_phi_node (res_y, new_exit_block);
1717 tree res_c = PHI_ARG_DEF_FROM_EDGE (phi, succ_new_exit_block);
1718 add_phi_arg (nphi, res_c, pred_new_exit_block, UNKNOWN_LOCATION);
1719 add_phi_arg (phi, res_y, succ_new_exit_block, UNKNOWN_LOCATION);
1720
d38409cd 1721 if (virtual_operand_p (res_z))
1722 continue;
1723
42acab1c 1724 gimple *reduc_phi = SSA_NAME_DEF_STMT (res_c);
d38409cd 1725 struct reduction_info *red = reduction_phi (reduction_list, reduc_phi);
1726 if (red != NULL)
5a3d2e18 1727 red->keep_res = nphi;
d38409cd 1728 }
1729
1730 /* We're going to cancel the loop at the end of gen_parallel_loop, but until
1731 then we're still using some fields, so only bother about fields that are
1732 still used: header and latch.
1733 The loop has a new header bb, so we update it. The latch bb stays the
1734 same. */
1735 loop->header = new_header;
1736
1737 /* Recalculate dominance info. */
1738 free_dominance_info (CDI_DOMINATORS);
1739 calculate_dominance_info (CDI_DOMINATORS);
1740}
1741
1742/* Tries to moves the exit condition of LOOP to the beginning of its header
1743 without duplication of the loop body. NIT is the number of iterations of the
1744 loop. REDUCTION_LIST describes the reductions in LOOP. Return true if
1745 transformation is successful. */
1746
1747static bool
1748try_transform_to_exit_first_loop_alt (struct loop *loop,
1749 reduction_info_table_type *reduction_list,
1750 tree nit)
1751{
1752 /* Check whether the latch contains a single statement. */
2ce3b2a5 1753 if (!gimple_seq_nondebug_singleton_p (bb_seq (loop->latch)))
1754 return false;
d38409cd 1755
1756 /* Check whether the latch contains the loop iv increment. */
1757 edge back = single_succ_edge (loop->latch);
1758 edge exit = single_dom_exit (loop);
1759 gcond *cond_stmt = as_a <gcond *> (last_stmt (exit->src));
1760 tree control = gimple_cond_lhs (cond_stmt);
1761 gphi *phi = as_a <gphi *> (SSA_NAME_DEF_STMT (control));
1762 tree inc_res = gimple_phi_arg_def (phi, back->dest_idx);
1763 if (gimple_bb (SSA_NAME_DEF_STMT (inc_res)) != loop->latch)
1764 return false;
1765
1766 /* Check whether there's no code between the loop condition and the latch. */
1767 if (!single_pred_p (loop->latch)
1768 || single_pred (loop->latch) != exit->src)
1769 return false;
1770
1771 tree alt_bound = NULL_TREE;
1772 tree nit_type = TREE_TYPE (nit);
1773
1774 /* Figure out whether nit + 1 overflows. */
1775 if (TREE_CODE (nit) == INTEGER_CST)
1776 {
1777 if (!tree_int_cst_equal (nit, TYPE_MAXVAL (nit_type)))
1778 {
1779 alt_bound = fold_build2_loc (UNKNOWN_LOCATION, PLUS_EXPR, nit_type,
1780 nit, build_one_cst (nit_type));
1781
1782 gcc_assert (TREE_CODE (alt_bound) == INTEGER_CST);
bd797881 1783 transform_to_exit_first_loop_alt (loop, reduction_list, alt_bound);
1784 return true;
d38409cd 1785 }
1786 else
1787 {
1788 /* Todo: Figure out if we can trigger this, if it's worth to handle
1789 optimally, and if we can handle it optimally. */
bd797881 1790 return false;
d38409cd 1791 }
1792 }
d38409cd 1793
bd797881 1794 gcc_assert (TREE_CODE (nit) == SSA_NAME);
d38409cd 1795
5d4f3ed8 1796 /* Variable nit is the loop bound as returned by canonicalize_loop_ivs, for an
1797 iv with base 0 and step 1 that is incremented in the latch, like this:
1798
1799 <bb header>:
1800 # iv_1 = PHI <0 (preheader), iv_2 (latch)>
1801 ...
1802 if (iv_1 < nit)
1803 goto <bb latch>;
1804 else
1805 goto <bb exit>;
1806
1807 <bb latch>:
1808 iv_2 = iv_1 + 1;
1809 goto <bb header>;
1810
1811 The range of iv_1 is [0, nit]. The latch edge is taken for
1812 iv_1 == [0, nit - 1] and the exit edge is taken for iv_1 == nit. So the
1813 number of latch executions is equal to nit.
1814
1815 The function max_loop_iterations gives us the maximum number of latch
1816 executions, so it gives us the maximum value of nit. */
1817 widest_int nit_max;
1818 if (!max_loop_iterations (loop, &nit_max))
1819 return false;
1820
1821 /* Check if nit + 1 overflows. */
1822 widest_int type_max = wi::to_widest (TYPE_MAXVAL (nit_type));
1823 if (!wi::lts_p (nit_max, type_max))
1824 return false;
1825
42acab1c 1826 gimple *def = SSA_NAME_DEF_STMT (nit);
d38409cd 1827
5d4f3ed8 1828 /* Try to find nit + 1, in the form of n in an assignment nit = n - 1. */
bd797881 1829 if (def
1830 && is_gimple_assign (def)
1831 && gimple_assign_rhs_code (def) == PLUS_EXPR)
1832 {
1833 tree op1 = gimple_assign_rhs1 (def);
1834 tree op2 = gimple_assign_rhs2 (def);
1835 if (integer_minus_onep (op1))
1836 alt_bound = op2;
1837 else if (integer_minus_onep (op2))
1838 alt_bound = op1;
d38409cd 1839 }
1840
3c31a6c6 1841 /* If not found, insert nit + 1. */
d38409cd 1842 if (alt_bound == NULL_TREE)
3c31a6c6 1843 {
1844 alt_bound = fold_build2 (PLUS_EXPR, nit_type, nit,
1845 build_int_cst_type (nit_type, 1));
1846
1847 gimple_stmt_iterator gsi = gsi_last_bb (loop_preheader_edge (loop)->src);
1848
1849 alt_bound
1850 = force_gimple_operand_gsi (&gsi, alt_bound, true, NULL_TREE, false,
1851 GSI_CONTINUE_LINKING);
1852 }
d38409cd 1853
1854 transform_to_exit_first_loop_alt (loop, reduction_list, alt_bound);
1855 return true;
1856}
1857
1858/* Moves the exit condition of LOOP to the beginning of its header. NIT is the
1859 number of iterations of the loop. REDUCTION_LIST describes the reductions in
1860 LOOP. */
28c92cbb 1861
1862static void
d9dd21a8 1863transform_to_exit_first_loop (struct loop *loop,
c1f445d2 1864 reduction_info_table_type *reduction_list,
d9dd21a8 1865 tree nit)
28c92cbb 1866{
1867 basic_block *bbs, *nbbs, ex_bb, orig_header;
1868 unsigned n;
1869 bool ok;
1870 edge exit = single_dom_exit (loop), hpred;
75a70cf9 1871 tree control, control_name, res, t;
1a91d914 1872 gphi *phi, *nphi;
1873 gassign *stmt;
1874 gcond *cond_stmt, *cond_nit;
b0fb253a 1875 tree nit_1;
28c92cbb 1876
1877 split_block_after_labels (loop->header);
1878 orig_header = single_succ (loop->header);
1879 hpred = single_succ_edge (loop->header);
1880
1a91d914 1881 cond_stmt = as_a <gcond *> (last_stmt (exit->src));
75a70cf9 1882 control = gimple_cond_lhs (cond_stmt);
1883 gcc_assert (gimple_cond_rhs (cond_stmt) == nit);
28c92cbb 1884
1885 /* Make sure that we have phi nodes on exit for all loop header phis
1886 (create_parallel_loop requires that). */
1a91d914 1887 for (gphi_iterator gsi = gsi_start_phis (loop->header);
1888 !gsi_end_p (gsi);
1889 gsi_next (&gsi))
28c92cbb 1890 {
1a91d914 1891 phi = gsi.phi ();
28c92cbb 1892 res = PHI_RESULT (phi);
874117c8 1893 t = copy_ssa_name (res, phi);
28c92cbb 1894 SET_PHI_RESULT (phi, t);
28c92cbb 1895 nphi = create_phi_node (res, orig_header);
60d535d2 1896 add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
28c92cbb 1897
1898 if (res == control)
1899 {
75a70cf9 1900 gimple_cond_set_lhs (cond_stmt, t);
28c92cbb 1901 update_stmt (cond_stmt);
1902 control = t;
1903 }
1904 }
2a556654 1905
28c92cbb 1906 bbs = get_loop_body_in_dom_order (loop);
b0fb253a 1907
89675e8c 1908 for (n = 0; bbs[n] != exit->src; n++)
1909 continue;
28c92cbb 1910 nbbs = XNEWVEC (basic_block, n);
75a70cf9 1911 ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
1912 bbs + 1, n, nbbs);
28c92cbb 1913 gcc_assert (ok);
1914 free (bbs);
1915 ex_bb = nbbs[0];
1916 free (nbbs);
1917
48e1416a 1918 /* Other than reductions, the only gimple reg that should be copied
75a70cf9 1919 out of the loop is the control variable. */
89675e8c 1920 exit = single_dom_exit (loop);
28c92cbb 1921 control_name = NULL_TREE;
1a91d914 1922 for (gphi_iterator gsi = gsi_start_phis (ex_bb);
1923 !gsi_end_p (gsi); )
28c92cbb 1924 {
1a91d914 1925 phi = gsi.phi ();
28c92cbb 1926 res = PHI_RESULT (phi);
7c782c9b 1927 if (virtual_operand_p (res))
75a70cf9 1928 {
1929 gsi_next (&gsi);
1930 continue;
1931 }
28c92cbb 1932
cb7f680b 1933 /* Check if it is a part of reduction. If it is,
48e1416a 1934 keep the phi at the reduction's keep_res field. The
1935 PHI_RESULT of this phi is the resulting value of the reduction
cb7f680b 1936 variable when exiting the loop. */
1937
c1f445d2 1938 if (reduction_list->elements () > 0)
cb7f680b 1939 {
1940 struct reduction_info *red;
1941
1942 tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
cb7f680b 1943 red = reduction_phi (reduction_list, SSA_NAME_DEF_STMT (val));
1944 if (red)
75a70cf9 1945 {
1946 red->keep_res = phi;
1947 gsi_next (&gsi);
1948 continue;
1949 }
cb7f680b 1950 }
75a70cf9 1951 gcc_assert (control_name == NULL_TREE
1952 && SSA_NAME_VAR (res) == SSA_NAME_VAR (control));
28c92cbb 1953 control_name = res;
75a70cf9 1954 remove_phi_node (&gsi, false);
28c92cbb 1955 }
1956 gcc_assert (control_name != NULL_TREE);
28c92cbb 1957
48e1416a 1958 /* Initialize the control variable to number of iterations
b0fb253a 1959 according to the rhs of the exit condition. */
1a91d914 1960 gimple_stmt_iterator gsi = gsi_after_labels (ex_bb);
1961 cond_nit = as_a <gcond *> (last_stmt (exit->src));
b0fb253a 1962 nit_1 = gimple_cond_rhs (cond_nit);
1963 nit_1 = force_gimple_operand_gsi (&gsi,
1964 fold_convert (TREE_TYPE (control_name), nit_1),
75a70cf9 1965 false, NULL_TREE, false, GSI_SAME_STMT);
b0fb253a 1966 stmt = gimple_build_assign (control_name, nit_1);
75a70cf9 1967 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1968}
1969
1970/* Create the parallel constructs for LOOP as described in gen_parallel_loop.
75a70cf9 1971 LOOP_FN and DATA are the arguments of GIMPLE_OMP_PARALLEL.
28c92cbb 1972 NEW_DATA is the variable that should be initialized from the argument
1973 of LOOP_FN. N_THREADS is the requested number of threads. Returns the
75a70cf9 1974 basic block containing GIMPLE_OMP_PARALLEL tree. */
28c92cbb 1975
1976static basic_block
1977create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
0aecb55e 1978 tree new_data, unsigned n_threads, location_t loc)
28c92cbb 1979{
75a70cf9 1980 gimple_stmt_iterator gsi;
86a932e0 1981 basic_block bb, paral_bb, for_bb, ex_bb, continue_bb;
f018d957 1982 tree t, param;
1a91d914 1983 gomp_parallel *omp_par_stmt;
42acab1c 1984 gimple *omp_return_stmt1, *omp_return_stmt2;
1985 gimple *phi;
1a91d914 1986 gcond *cond_stmt;
1987 gomp_for *for_stmt;
1988 gomp_continue *omp_cont_stmt;
75a70cf9 1989 tree cvar, cvar_init, initvar, cvar_next, cvar_base, type;
28c92cbb 1990 edge exit, nexit, guard, end, e;
1991
75a70cf9 1992 /* Prepare the GIMPLE_OMP_PARALLEL statement. */
28c92cbb 1993 bb = loop_preheader_edge (loop)->src;
1994 paral_bb = single_pred (bb);
75a70cf9 1995 gsi = gsi_last_bb (paral_bb);
28c92cbb 1996
0aecb55e 1997 t = build_omp_clause (loc, OMP_CLAUSE_NUM_THREADS);
28c92cbb 1998 OMP_CLAUSE_NUM_THREADS_EXPR (t)
cb7f680b 1999 = build_int_cst (integer_type_node, n_threads);
1a91d914 2000 omp_par_stmt = gimple_build_omp_parallel (NULL, t, loop_fn, data);
2001 gimple_set_location (omp_par_stmt, loc);
28c92cbb 2002
1a91d914 2003 gsi_insert_after (&gsi, omp_par_stmt, GSI_NEW_STMT);
28c92cbb 2004
2005 /* Initialize NEW_DATA. */
2006 if (data)
2007 {
1a91d914 2008 gassign *assign_stmt;
2009
75a70cf9 2010 gsi = gsi_after_labels (bb);
2011
f9e245b2 2012 param = make_ssa_name (DECL_ARGUMENTS (loop_fn));
1a91d914 2013 assign_stmt = gimple_build_assign (param, build_fold_addr_expr (data));
2014 gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
75a70cf9 2015
1a91d914 2016 assign_stmt = gimple_build_assign (new_data,
75a70cf9 2017 fold_convert (TREE_TYPE (new_data), param));
1a91d914 2018 gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
28c92cbb 2019 }
2020
75a70cf9 2021 /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_PARALLEL. */
28c92cbb 2022 bb = split_loop_exit_edge (single_dom_exit (loop));
75a70cf9 2023 gsi = gsi_last_bb (bb);
1a91d914 2024 omp_return_stmt1 = gimple_build_omp_return (false);
2025 gimple_set_location (omp_return_stmt1, loc);
2026 gsi_insert_after (&gsi, omp_return_stmt1, GSI_NEW_STMT);
28c92cbb 2027
75a70cf9 2028 /* Extract data for GIMPLE_OMP_FOR. */
28c92cbb 2029 gcc_assert (loop->header == single_dom_exit (loop)->src);
1a91d914 2030 cond_stmt = as_a <gcond *> (last_stmt (loop->header));
28c92cbb 2031
75a70cf9 2032 cvar = gimple_cond_lhs (cond_stmt);
28c92cbb 2033 cvar_base = SSA_NAME_VAR (cvar);
2034 phi = SSA_NAME_DEF_STMT (cvar);
2035 cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
f9e245b2 2036 initvar = copy_ssa_name (cvar);
28c92cbb 2037 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, loop_preheader_edge (loop)),
2038 initvar);
2039 cvar_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
2040
4bcf12c5 2041 gsi = gsi_last_nondebug_bb (loop->latch);
75a70cf9 2042 gcc_assert (gsi_stmt (gsi) == SSA_NAME_DEF_STMT (cvar_next));
2043 gsi_remove (&gsi, true);
28c92cbb 2044
2045 /* Prepare cfg. */
2046 for_bb = split_edge (loop_preheader_edge (loop));
2047 ex_bb = split_loop_exit_edge (single_dom_exit (loop));
2048 extract_true_false_edges_from_block (loop->header, &nexit, &exit);
2049 gcc_assert (exit == single_dom_exit (loop));
2050
2051 guard = make_edge (for_bb, ex_bb, 0);
86a932e0 2052 /* Split the latch edge, so LOOPS_HAVE_SIMPLE_LATCHES is still valid. */
2053 loop->latch = split_edge (single_succ_edge (loop->latch));
2054 single_pred_edge (loop->latch)->flags = 0;
2055 end = make_edge (single_pred (loop->latch), ex_bb, EDGE_FALLTHRU);
2056 rescan_loop_exit (end, true, false);
2057
1a91d914 2058 for (gphi_iterator gpi = gsi_start_phis (ex_bb);
2059 !gsi_end_p (gpi); gsi_next (&gpi))
28c92cbb 2060 {
efbcb6de 2061 source_location locus;
1a91d914 2062 gphi *phi = gpi.phi ();
d1134db8 2063 tree def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
42acab1c 2064 gimple *def_stmt = SSA_NAME_DEF_STMT (def);
1a91d914 2065
d1134db8 2066 /* If the exit phi is not connected to a header phi in the same loop, this
2067 value is not modified in the loop, and we're done with this phi. */
2068 if (!(gimple_code (def_stmt) == GIMPLE_PHI
2069 && gimple_bb (def_stmt) == loop->header))
2070 continue;
efbcb6de 2071
d1134db8 2072 gphi *stmt = as_a <gphi *> (def_stmt);
efbcb6de 2073 def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop));
48e1416a 2074 locus = gimple_phi_arg_location_from_edge (stmt,
efbcb6de 2075 loop_preheader_edge (loop));
60d535d2 2076 add_phi_arg (phi, def, guard, locus);
efbcb6de 2077
2078 def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop));
2079 locus = gimple_phi_arg_location_from_edge (stmt, loop_latch_edge (loop));
60d535d2 2080 add_phi_arg (phi, def, end, locus);
28c92cbb 2081 }
2082 e = redirect_edge_and_branch (exit, nexit->dest);
2083 PENDING_STMT (e) = NULL;
2084
75a70cf9 2085 /* Emit GIMPLE_OMP_FOR. */
2086 gimple_cond_set_lhs (cond_stmt, cvar_base);
28c92cbb 2087 type = TREE_TYPE (cvar);
0aecb55e 2088 t = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
9a782341 2089 int chunk_size = PARAM_VALUE (PARAM_PARLOOPS_CHUNK_SIZE);
2331aa43 2090 enum PARAM_PARLOOPS_SCHEDULE_KIND schedule_type \
2091 = (enum PARAM_PARLOOPS_SCHEDULE_KIND) PARAM_VALUE (PARAM_PARLOOPS_SCHEDULE);
2092 switch (schedule_type)
2093 {
2094 case PARAM_PARLOOPS_SCHEDULE_KIND_static:
2095 OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
2096 break;
2097 case PARAM_PARLOOPS_SCHEDULE_KIND_dynamic:
2098 OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
2099 break;
2100 case PARAM_PARLOOPS_SCHEDULE_KIND_guided:
2101 OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_GUIDED;
2102 break;
2103 case PARAM_PARLOOPS_SCHEDULE_KIND_auto:
2104 OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_AUTO;
2105 chunk_size = 0;
2106 break;
2107 case PARAM_PARLOOPS_SCHEDULE_KIND_runtime:
2108 OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_RUNTIME;
2109 chunk_size = 0;
2110 break;
2111 default:
2112 gcc_unreachable ();
2113 }
9a782341 2114 if (chunk_size != 0)
2115 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t)
2116 = build_int_cst (integer_type_node, chunk_size);
28c92cbb 2117
3d483a94 2118 for_stmt = gimple_build_omp_for (NULL, GF_OMP_FOR_KIND_FOR, t, 1, NULL);
0aecb55e 2119 gimple_set_location (for_stmt, loc);
75a70cf9 2120 gimple_omp_for_set_index (for_stmt, 0, initvar);
2121 gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
2122 gimple_omp_for_set_final (for_stmt, 0, gimple_cond_rhs (cond_stmt));
2123 gimple_omp_for_set_cond (for_stmt, 0, gimple_cond_code (cond_stmt));
2124 gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
2125 cvar_base,
2126 build_int_cst (type, 1)));
2127
2128 gsi = gsi_last_bb (for_bb);
2129 gsi_insert_after (&gsi, for_stmt, GSI_NEW_STMT);
28c92cbb 2130 SSA_NAME_DEF_STMT (initvar) = for_stmt;
2131
75a70cf9 2132 /* Emit GIMPLE_OMP_CONTINUE. */
86a932e0 2133 continue_bb = single_pred (loop->latch);
2134 gsi = gsi_last_bb (continue_bb);
1a91d914 2135 omp_cont_stmt = gimple_build_omp_continue (cvar_next, cvar);
2136 gimple_set_location (omp_cont_stmt, loc);
2137 gsi_insert_after (&gsi, omp_cont_stmt, GSI_NEW_STMT);
2138 SSA_NAME_DEF_STMT (cvar_next) = omp_cont_stmt;
28c92cbb 2139
75a70cf9 2140 /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_FOR. */
2141 gsi = gsi_last_bb (ex_bb);
1a91d914 2142 omp_return_stmt2 = gimple_build_omp_return (true);
2143 gimple_set_location (omp_return_stmt2, loc);
2144 gsi_insert_after (&gsi, omp_return_stmt2, GSI_NEW_STMT);
28c92cbb 2145
821ac701 2146 /* After the above dom info is hosed. Re-compute it. */
2147 free_dominance_info (CDI_DOMINATORS);
2148 calculate_dominance_info (CDI_DOMINATORS);
2149
28c92cbb 2150 return paral_bb;
2151}
2152
5fa90eea 2153/* Generates code to execute the iterations of LOOP in N_THREADS
2154 threads in parallel.
2155
2156 NITER describes number of iterations of LOOP.
f0b5f617 2157 REDUCTION_LIST describes the reductions existent in the LOOP. */
28c92cbb 2158
2159static void
c1f445d2 2160gen_parallel_loop (struct loop *loop,
2161 reduction_info_table_type *reduction_list,
cb7f680b 2162 unsigned n_threads, struct tree_niter_desc *niter)
28c92cbb 2163{
28c92cbb 2164 tree many_iterations_cond, type, nit;
75a70cf9 2165 tree arg_struct, new_arg_struct;
2166 gimple_seq stmts;
e06f9c34 2167 edge entry, exit;
cb7f680b 2168 struct clsn_data clsn_data;
28c92cbb 2169 unsigned prob;
0aecb55e 2170 location_t loc;
42acab1c 2171 gimple *cond_stmt;
362dc73c 2172 unsigned int m_p_thread=2;
28c92cbb 2173
2174 /* From
2175
2176 ---------------------------------------------------------------------
2177 loop
2178 {
2179 IV = phi (INIT, IV + STEP)
2180 BODY1;
2181 if (COND)
2182 break;
2183 BODY2;
2184 }
2185 ---------------------------------------------------------------------
2186
2187 with # of iterations NITER (possibly with MAY_BE_ZERO assumption),
2188 we generate the following code:
2189
2190 ---------------------------------------------------------------------
2191
2192 if (MAY_BE_ZERO
cb7f680b 2193 || NITER < MIN_PER_THREAD * N_THREADS)
2194 goto original;
28c92cbb 2195
2196 BODY1;
2197 store all local loop-invariant variables used in body of the loop to DATA.
75a70cf9 2198 GIMPLE_OMP_PARALLEL (OMP_CLAUSE_NUM_THREADS (N_THREADS), LOOPFN, DATA);
28c92cbb 2199 load the variables from DATA.
75a70cf9 2200 GIMPLE_OMP_FOR (IV = INIT; COND; IV += STEP) (OMP_CLAUSE_SCHEDULE (static))
28c92cbb 2201 BODY2;
2202 BODY1;
75a70cf9 2203 GIMPLE_OMP_CONTINUE;
2204 GIMPLE_OMP_RETURN -- GIMPLE_OMP_FOR
2205 GIMPLE_OMP_RETURN -- GIMPLE_OMP_PARALLEL
28c92cbb 2206 goto end;
2207
2208 original:
2209 loop
2210 {
2211 IV = phi (INIT, IV + STEP)
2212 BODY1;
2213 if (COND)
2214 break;
2215 BODY2;
2216 }
2217
2218 end:
2219
2220 */
2221
2222 /* Create two versions of the loop -- in the old one, we know that the
2223 number of iterations is large enough, and we will transform it into the
2224 loop that will be split to loop_fn, the new one will be used for the
2225 remaining iterations. */
cb7f680b 2226
362dc73c 2227 /* We should compute a better number-of-iterations value for outer loops.
2228 That is, if we have
2229
2230 for (i = 0; i < n; ++i)
2231 for (j = 0; j < m; ++j)
2232 ...
2233
2234 we should compute nit = n * m, not nit = n.
2235 Also may_be_zero handling would need to be adjusted. */
2236
28c92cbb 2237 type = TREE_TYPE (niter->niter);
2238 nit = force_gimple_operand (unshare_expr (niter->niter), &stmts, true,
2239 NULL_TREE);
2240 if (stmts)
75a70cf9 2241 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
28c92cbb 2242
362dc73c 2243 if (loop->inner)
2244 m_p_thread=2;
2245 else
2246 m_p_thread=MIN_PER_THREAD;
2247
2248 many_iterations_cond =
2249 fold_build2 (GE_EXPR, boolean_type_node,
2250 nit, build_int_cst (type, m_p_thread * n_threads));
2251
28c92cbb 2252 many_iterations_cond
cb7f680b 2253 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2254 invert_truthvalue (unshare_expr (niter->may_be_zero)),
2255 many_iterations_cond);
28c92cbb 2256 many_iterations_cond
cb7f680b 2257 = force_gimple_operand (many_iterations_cond, &stmts, false, NULL_TREE);
28c92cbb 2258 if (stmts)
75a70cf9 2259 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
28c92cbb 2260 if (!is_gimple_condexpr (many_iterations_cond))
2261 {
2262 many_iterations_cond
cb7f680b 2263 = force_gimple_operand (many_iterations_cond, &stmts,
2264 true, NULL_TREE);
28c92cbb 2265 if (stmts)
75a70cf9 2266 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
28c92cbb 2267 }
2268
2269 initialize_original_copy_tables ();
2270
2271 /* We assume that the loop usually iterates a lot. */
2272 prob = 4 * REG_BR_PROB_BASE / 5;
f018d957 2273 loop_version (loop, many_iterations_cond, NULL,
2274 prob, prob, REG_BR_PROB_BASE - prob, true);
28c92cbb 2275 update_ssa (TODO_update_ssa);
2276 free_original_copy_tables ();
2277
2278 /* Base all the induction variables in LOOP on a single control one. */
0207206d 2279 canonicalize_loop_ivs (loop, &nit, true);
28c92cbb 2280
d38409cd 2281 /* Ensure that the exit condition is the first statement in the loop.
2282 The common case is that latch of the loop is empty (apart from the
2283 increment) and immediately follows the loop exit test. Attempt to move the
2284 entry of the loop directly before the exit check and increase the number of
2285 iterations of the loop by one. */
91d14856 2286 if (try_transform_to_exit_first_loop_alt (loop, reduction_list, nit))
2287 {
2288 if (dump_file
2289 && (dump_flags & TDF_DETAILS))
2290 fprintf (dump_file,
2291 "alternative exit-first loop transform succeeded"
2292 " for loop %d\n", loop->num);
2293 }
2294 else
d38409cd 2295 {
2296 /* Fall back on the method that handles more cases, but duplicates the
2297 loop body: move the exit condition of LOOP to the beginning of its
2298 header, and duplicate the part of the last iteration that gets disabled
2299 to the exit of the loop. */
2300 transform_to_exit_first_loop (loop, reduction_list, nit);
2301 }
cb7f680b 2302
f0b5f617 2303 /* Generate initializations for reductions. */
c1f445d2 2304 if (reduction_list->elements () > 0)
2305 reduction_list->traverse <struct loop *, initialize_reductions> (loop);
28c92cbb 2306
2307 /* Eliminate the references to local variables from the loop. */
e06f9c34 2308 gcc_assert (single_exit (loop));
2309 entry = loop_preheader_edge (loop);
2310 exit = single_dom_exit (loop);
28c92cbb 2311
e06f9c34 2312 eliminate_local_variables (entry, exit);
28c92cbb 2313 /* In the old loop, move all variables non-local to the loop to a structure
2314 and back, and create separate decls for the variables used in loop. */
48e1416a 2315 separate_decls_in_region (entry, exit, reduction_list, &arg_struct,
e06f9c34 2316 &new_arg_struct, &clsn_data);
28c92cbb 2317
2318 /* Create the parallel constructs. */
0aecb55e 2319 loc = UNKNOWN_LOCATION;
2320 cond_stmt = last_stmt (loop->header);
2321 if (cond_stmt)
2322 loc = gimple_location (cond_stmt);
8917c50b 2323 create_parallel_loop (loop, create_loop_fn (loc), arg_struct,
2324 new_arg_struct, n_threads, loc);
c1f445d2 2325 if (reduction_list->elements () > 0)
cb7f680b 2326 create_call_for_reduction (loop, reduction_list, &clsn_data);
28c92cbb 2327
2328 scev_reset ();
2329
d46d3c1c 2330 /* Free loop bound estimations that could contain references to
2331 removed statements. */
f21d4d00 2332 FOR_EACH_LOOP (loop, 0)
d46d3c1c 2333 free_numbers_of_iterations_estimates_loop (loop);
28c92cbb 2334}
2335
c968a07c 2336/* Returns true when LOOP contains vector phi nodes. */
2337
2338static bool
75a70cf9 2339loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED)
c968a07c 2340{
2341 unsigned i;
2342 basic_block *bbs = get_loop_body_in_dom_order (loop);
1a91d914 2343 gphi_iterator gsi;
c968a07c 2344 bool res = true;
c968a07c 2345
2346 for (i = 0; i < loop->num_nodes; i++)
75a70cf9 2347 for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
1a91d914 2348 if (TREE_CODE (TREE_TYPE (PHI_RESULT (gsi.phi ()))) == VECTOR_TYPE)
c968a07c 2349 goto end;
2350
2351 res = false;
2352 end:
2353 free (bbs);
2354 return res;
2355}
2356
5fa90eea 2357/* Create a reduction_info struct, initialize it with REDUC_STMT
2358 and PHI, insert it to the REDUCTION_LIST. */
2359
2360static void
c1f445d2 2361build_new_reduction (reduction_info_table_type *reduction_list,
42acab1c 2362 gimple *reduc_stmt, gphi *phi)
5fa90eea 2363{
d9dd21a8 2364 reduction_info **slot;
5fa90eea 2365 struct reduction_info *new_reduction;
95f4166a 2366 enum tree_code reduction_code;
5fa90eea 2367
2368 gcc_assert (reduc_stmt);
48e1416a 2369
5fa90eea 2370 if (dump_file && (dump_flags & TDF_DETAILS))
2371 {
2372 fprintf (dump_file,
2373 "Detected reduction. reduction stmt is: \n");
2374 print_gimple_stmt (dump_file, reduc_stmt, 0, 0);
2375 fprintf (dump_file, "\n");
2376 }
48e1416a 2377
95f4166a 2378 if (gimple_code (reduc_stmt) == GIMPLE_PHI)
2379 {
2380 tree op1 = PHI_ARG_DEF (reduc_stmt, 0);
42acab1c 2381 gimple *def1 = SSA_NAME_DEF_STMT (op1);
95f4166a 2382 reduction_code = gimple_assign_rhs_code (def1);
2383 }
2384
2385 else
2386 reduction_code = gimple_assign_rhs_code (reduc_stmt);
2387
5fa90eea 2388 new_reduction = XCNEW (struct reduction_info);
48e1416a 2389
5fa90eea 2390 new_reduction->reduc_stmt = reduc_stmt;
2391 new_reduction->reduc_phi = phi;
71fa519d 2392 new_reduction->reduc_version = SSA_NAME_VERSION (gimple_phi_result (phi));
95f4166a 2393 new_reduction->reduction_code = reduction_code;
c1f445d2 2394 slot = reduction_list->find_slot (new_reduction, INSERT);
5fa90eea 2395 *slot = new_reduction;
2396}
2397
71fa519d 2398/* Callback for htab_traverse. Sets gimple_uid of reduc_phi stmts. */
2399
d9dd21a8 2400int
2401set_reduc_phi_uids (reduction_info **slot, void *data ATTRIBUTE_UNUSED)
71fa519d 2402{
d9dd21a8 2403 struct reduction_info *const red = *slot;
71fa519d 2404 gimple_set_uid (red->reduc_phi, red->reduc_version);
2405 return 1;
2406}
2407
5fa90eea 2408/* Detect all reductions in the LOOP, insert them into REDUCTION_LIST. */
2409
2410static void
c1f445d2 2411gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list)
5fa90eea 2412{
1a91d914 2413 gphi_iterator gsi;
5fa90eea 2414 loop_vec_info simple_loop_info;
95f4166a 2415 loop_vec_info simple_inner_loop_info = NULL;
2416 bool allow_double_reduc = true;
5fa90eea 2417
eac984fd 2418 if (!stmt_vec_info_vec.exists ())
2419 init_stmt_vec_info_vec ();
2420
5fa90eea 2421 simple_loop_info = vect_analyze_loop_form (loop);
81fbee06 2422 if (simple_loop_info == NULL)
2423 return;
5fa90eea 2424
2425 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
2426 {
1a91d914 2427 gphi *phi = gsi.phi ();
5fa90eea 2428 affine_iv iv;
2429 tree res = PHI_RESULT (phi);
2430 bool double_reduc;
2431
7c782c9b 2432 if (virtual_operand_p (res))
5fa90eea 2433 continue;
2434
81fbee06 2435 if (simple_iv (loop, loop, res, &iv, true))
2436 continue;
2437
42acab1c 2438 gimple *reduc_stmt
81fbee06 2439 = vect_force_simple_reduction (simple_loop_info, phi, true,
2440 &double_reduc, true);
95f4166a 2441 if (!reduc_stmt)
81fbee06 2442 continue;
2443
95f4166a 2444 if (double_reduc)
2445 {
2446 if (!allow_double_reduc
2447 || loop->inner->inner != NULL)
2448 continue;
2449
2450 if (!simple_inner_loop_info)
2451 {
2452 simple_inner_loop_info = vect_analyze_loop_form (loop->inner);
2453 if (!simple_inner_loop_info)
2454 {
2455 allow_double_reduc = false;
2456 continue;
2457 }
2458 }
2459
2460 use_operand_p use_p;
42acab1c 2461 gimple *inner_stmt;
95f4166a 2462 bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
2463 gcc_assert (single_use_p);
2464 gphi *inner_phi = as_a <gphi *> (inner_stmt);
2465 if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
2466 &iv, true))
2467 continue;
2468
42acab1c 2469 gimple *inner_reduc_stmt
95f4166a 2470 = vect_force_simple_reduction (simple_inner_loop_info, inner_phi,
2471 true, &double_reduc, true);
2472 gcc_assert (!double_reduc);
2473 if (inner_reduc_stmt == NULL)
2474 continue;
2475 }
2476
81fbee06 2477 build_new_reduction (reduction_list, reduc_stmt, phi);
5fa90eea 2478 }
71fa519d 2479 destroy_loop_vec_info (simple_loop_info, true);
95f4166a 2480 destroy_loop_vec_info (simple_inner_loop_info, true);
71fa519d 2481
eac984fd 2482 /* Release the claim on gimple_uid. */
2483 free_stmt_vec_info_vec ();
2484
71fa519d 2485 /* As gimple_uid is used by the vectorizer in between vect_analyze_loop_form
eac984fd 2486 and free_stmt_vec_info_vec, we can set gimple_uid of reduc_phi stmts only
2487 now. */
2488 basic_block bb;
2489 FOR_EACH_BB_FN (bb, cfun)
2490 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2491 gimple_set_uid (gsi_stmt (gsi), (unsigned int)-1);
c1f445d2 2492 reduction_list->traverse <void *, set_reduc_phi_uids> (NULL);
5fa90eea 2493}
2494
2495/* Try to initialize NITER for code generation part. */
2496
2497static bool
2498try_get_loop_niter (loop_p loop, struct tree_niter_desc *niter)
2499{
2500 edge exit = single_dom_exit (loop);
2501
2502 gcc_assert (exit);
2503
2504 /* We need to know # of iterations, and there should be no uses of values
2505 defined inside loop outside of it, unless the values are invariants of
2506 the loop. */
2507 if (!number_of_iterations_exit (loop, exit, niter, false))
2508 {
2509 if (dump_file && (dump_flags & TDF_DETAILS))
2510 fprintf (dump_file, " FAILED: number of iterations not known\n");
2511 return false;
2512 }
2513
2514 return true;
2515}
2516
2517/* Try to initialize REDUCTION_LIST for code generation part.
2518 REDUCTION_LIST describes the reductions. */
2519
2520static bool
d9dd21a8 2521try_create_reduction_list (loop_p loop,
c1f445d2 2522 reduction_info_table_type *reduction_list)
5fa90eea 2523{
2524 edge exit = single_dom_exit (loop);
1a91d914 2525 gphi_iterator gsi;
5fa90eea 2526
2527 gcc_assert (exit);
2528
2529 gather_scalar_reductions (loop, reduction_list);
2530
48e1416a 2531
5fa90eea 2532 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
2533 {
1a91d914 2534 gphi *phi = gsi.phi ();
5fa90eea 2535 struct reduction_info *red;
2536 imm_use_iterator imm_iter;
2537 use_operand_p use_p;
42acab1c 2538 gimple *reduc_phi;
5fa90eea 2539 tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
2540
7c782c9b 2541 if (!virtual_operand_p (val))
5fa90eea 2542 {
2543 if (dump_file && (dump_flags & TDF_DETAILS))
2544 {
2545 fprintf (dump_file, "phi is ");
2546 print_gimple_stmt (dump_file, phi, 0, 0);
2547 fprintf (dump_file, "arg of phi to exit: value ");
2548 print_generic_expr (dump_file, val, 0);
2549 fprintf (dump_file, " used outside loop\n");
2550 fprintf (dump_file,
2551 " checking if it a part of reduction pattern: \n");
2552 }
c1f445d2 2553 if (reduction_list->elements () == 0)
5fa90eea 2554 {
2555 if (dump_file && (dump_flags & TDF_DETAILS))
2556 fprintf (dump_file,
2557 " FAILED: it is not a part of reduction.\n");
2558 return false;
2559 }
2560 reduc_phi = NULL;
2561 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, val)
2562 {
43989e16 2563 if (!gimple_debug_bind_p (USE_STMT (use_p))
2564 && flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
5fa90eea 2565 {
2566 reduc_phi = USE_STMT (use_p);
2567 break;
2568 }
2569 }
2570 red = reduction_phi (reduction_list, reduc_phi);
2571 if (red == NULL)
2572 {
2573 if (dump_file && (dump_flags & TDF_DETAILS))
2574 fprintf (dump_file,
2575 " FAILED: it is not a part of reduction.\n");
2576 return false;
2577 }
2578 if (dump_file && (dump_flags & TDF_DETAILS))
2579 {
2580 fprintf (dump_file, "reduction phi is ");
2581 print_gimple_stmt (dump_file, red->reduc_phi, 0, 0);
2582 fprintf (dump_file, "reduction stmt is ");
2583 print_gimple_stmt (dump_file, red->reduc_stmt, 0, 0);
2584 }
2585 }
2586 }
2587
2588 /* The iterations of the loop may communicate only through bivs whose
2589 iteration space can be distributed efficiently. */
2590 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
2591 {
1a91d914 2592 gphi *phi = gsi.phi ();
5fa90eea 2593 tree def = PHI_RESULT (phi);
2594 affine_iv iv;
2595
7c782c9b 2596 if (!virtual_operand_p (def) && !simple_iv (loop, loop, def, &iv, true))
5fa90eea 2597 {
2598 struct reduction_info *red;
2599
2600 red = reduction_phi (reduction_list, phi);
2601 if (red == NULL)
2602 {
2603 if (dump_file && (dump_flags & TDF_DETAILS))
2604 fprintf (dump_file,
2605 " FAILED: scalar dependency between iterations\n");
2606 return false;
2607 }
2608 }
2609 }
2610
2611
2612 return true;
2613}
2614
28c92cbb 2615/* Detect parallel loops and generate parallel code using libgomp
2616 primitives. Returns true if some loop was parallelized, false
2617 otherwise. */
2618
4abc36e8 2619static bool
28c92cbb 2620parallelize_loops (void)
2621{
2622 unsigned n_threads = flag_tree_parallelize_loops;
2623 bool changed = false;
2624 struct loop *loop;
86a932e0 2625 struct loop *skip_loop = NULL;
28c92cbb 2626 struct tree_niter_desc niter_desc;
1e33ad50 2627 struct obstack parloop_obstack;
fbbe5b51 2628 HOST_WIDE_INT estimated;
36f39b2e 2629 source_location loop_loc;
1e33ad50 2630
28c92cbb 2631 /* Do not parallelize loops in the functions created by parallelization. */
2632 if (parallelized_function_p (cfun->decl))
2633 return false;
fbbe5b51 2634 if (cfun->has_nonlocal_label)
2635 return false;
28c92cbb 2636
1e33ad50 2637 gcc_obstack_init (&parloop_obstack);
c1f445d2 2638 reduction_info_table_type reduction_list (10);
cb7f680b 2639
f21d4d00 2640 FOR_EACH_LOOP (loop, 0)
28c92cbb 2641 {
86a932e0 2642 if (loop == skip_loop)
2643 {
2644 if (dump_file && (dump_flags & TDF_DETAILS))
2645 fprintf (dump_file,
2646 "Skipping loop %d as inner loop of parallelized loop\n",
2647 loop->num);
2648
2649 skip_loop = loop->inner;
2650 continue;
2651 }
2652 else
2653 skip_loop = NULL;
2654
d9dd21a8 2655 reduction_list.empty ();
b0fb253a 2656 if (dump_file && (dump_flags & TDF_DETAILS))
2657 {
2658 fprintf (dump_file, "Trying loop %d as candidate\n",loop->num);
2659 if (loop->inner)
2660 fprintf (dump_file, "loop %d is not innermost\n",loop->num);
2661 else
2662 fprintf (dump_file, "loop %d is innermost\n",loop->num);
2663 }
48e1416a 2664
b0fb253a 2665 /* If we use autopar in graphite pass, we use its marked dependency
525c22c4 2666 checking results. */
2667 if (flag_loop_parallelize_all && !loop->can_be_parallel)
b0fb253a 2668 {
2669 if (dump_file && (dump_flags & TDF_DETAILS))
2670 fprintf (dump_file, "loop is not parallel according to graphite\n");
525c22c4 2671 continue;
b0fb253a 2672 }
525c22c4 2673
b0fb253a 2674 if (!single_dom_exit (loop))
2675 {
48e1416a 2676
b0fb253a 2677 if (dump_file && (dump_flags & TDF_DETAILS))
2678 fprintf (dump_file, "loop is !single_dom_exit\n");
48e1416a 2679
5fa90eea 2680 continue;
b0fb253a 2681 }
5fa90eea 2682
2683 if (/* And of course, the loop must be parallelizable. */
2684 !can_duplicate_loop_p (loop)
d4fcfd16 2685 || loop_has_blocks_with_irreducible_flag (loop)
fbbe5b51 2686 || (loop_preheader_edge (loop)->src->flags & BB_IRREDUCIBLE_LOOP)
c968a07c 2687 /* FIXME: the check for vector phi nodes could be removed. */
89675e8c 2688 || loop_has_vector_phi_nodes (loop))
5fa90eea 2689 continue;
b0b097b4 2690
fee017b3 2691 estimated = estimated_stmt_executions_int (loop);
b0b097b4 2692 if (estimated == -1)
2693 estimated = max_stmt_executions_int (loop);
525c22c4 2694 /* FIXME: Bypass this check as graphite doesn't update the
b0b097b4 2695 count and frequency correctly now. */
525c22c4 2696 if (!flag_loop_parallelize_all
b0b097b4 2697 && ((estimated != -1
2698 && estimated <= (HOST_WIDE_INT) n_threads * MIN_PER_THREAD)
525c22c4 2699 /* Do not bother with loops in cold areas. */
2700 || optimize_loop_nest_for_size_p (loop)))
5fa90eea 2701 continue;
48e1416a 2702
5fa90eea 2703 if (!try_get_loop_niter (loop, &niter_desc))
2704 continue;
2705
c1f445d2 2706 if (!try_create_reduction_list (loop, &reduction_list))
5fa90eea 2707 continue;
2708
1e33ad50 2709 if (!flag_loop_parallelize_all
2710 && !loop_parallel_p (loop, &parloop_obstack))
28c92cbb 2711 continue;
2712
2713 changed = true;
86a932e0 2714 skip_loop = loop->inner;
b0fb253a 2715 if (dump_file && (dump_flags & TDF_DETAILS))
2716 {
b0fb253a 2717 if (loop->inner)
fbbe5b51 2718 fprintf (dump_file, "parallelizing outer loop %d\n",loop->header->index);
b0fb253a 2719 else
fbbe5b51 2720 fprintf (dump_file, "parallelizing inner loop %d\n",loop->header->index);
2721 loop_loc = find_loop_location (loop);
36f39b2e 2722 if (loop_loc != UNKNOWN_LOCATION)
fbbe5b51 2723 fprintf (dump_file, "\nloop at %s:%d: ",
36f39b2e 2724 LOCATION_FILE (loop_loc), LOCATION_LINE (loop_loc));
48e1416a 2725 }
c1f445d2 2726 gen_parallel_loop (loop, &reduction_list,
5fa90eea 2727 n_threads, &niter_desc);
28c92cbb 2728 }
2729
1e33ad50 2730 obstack_free (&parloop_obstack, NULL);
7f81b5ee 2731
2732 /* Parallelization will cause new function calls to be inserted through
cb245216 2733 which local variables will escape. Reset the points-to solution
2734 for ESCAPED. */
7f81b5ee 2735 if (changed)
cb245216 2736 pt_solution_reset (&cfun->gimple_df->escaped);
7f81b5ee 2737
28c92cbb 2738 return changed;
2739}
2740
64641360 2741/* Parallelization. */
2742
64641360 2743namespace {
2744
2745const pass_data pass_data_parallelize_loops =
2746{
2747 GIMPLE_PASS, /* type */
2748 "parloops", /* name */
2749 OPTGROUP_LOOP, /* optinfo_flags */
64641360 2750 TV_TREE_PARALLELIZE_LOOPS, /* tv_id */
2751 ( PROP_cfg | PROP_ssa ), /* properties_required */
2752 0, /* properties_provided */
2753 0, /* properties_destroyed */
2754 0, /* todo_flags_start */
8b88439e 2755 0, /* todo_flags_finish */
64641360 2756};
2757
2758class pass_parallelize_loops : public gimple_opt_pass
2759{
2760public:
2761 pass_parallelize_loops (gcc::context *ctxt)
2762 : gimple_opt_pass (pass_data_parallelize_loops, ctxt)
2763 {}
2764
2765 /* opt_pass methods: */
31315c24 2766 virtual bool gate (function *) { return flag_tree_parallelize_loops > 1; }
65b0537f 2767 virtual unsigned int execute (function *);
64641360 2768
2769}; // class pass_parallelize_loops
2770
65b0537f 2771unsigned
2772pass_parallelize_loops::execute (function *fun)
2773{
2774 if (number_of_loops (fun) <= 1)
2775 return 0;
2776
2777 if (parallelize_loops ())
8917c50b 2778 {
2779 fun->curr_properties &= ~(PROP_gimple_eomp);
86a932e0 2780
382ecba7 2781 checking_verify_loop_structure ();
86a932e0 2782
8917c50b 2783 return TODO_update_ssa;
2784 }
2785
65b0537f 2786 return 0;
2787}
2788
64641360 2789} // anon namespace
2790
2791gimple_opt_pass *
2792make_pass_parallelize_loops (gcc::context *ctxt)
2793{
2794 return new pass_parallelize_loops (ctxt);
2795}