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