]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-parloops.c
* config/i386/i386.c (ix86_init_mmx_sse_builtins): Fix builtin
[thirdparty/gcc.git] / gcc / tree-parloops.c
CommitLineData
28c92cbb 1/* Loop autoparallelization.
79216f37 2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
7cf0dbf3 3 Free Software Foundation, Inc.
0773b627 4 Contributed by Sebastian Pop <pop@cri.ensmp.fr>
5 Zdenek Dvorak <dvorakz@suse.cz> and Razya Ladelsky <razya@il.ibm.com>.
28c92cbb 6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
4ef8346d 11Software Foundation; either version 3, or (at your option) any later
28c92cbb 12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
4ef8346d 20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
28c92cbb 22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
28c92cbb 26#include "tree-flow.h"
27#include "cfgloop.h"
28c92cbb 28#include "tree-data-ref.h"
1e5b7b1f 29#include "tree-scalar-evolution.h"
ce084dfc 30#include "gimple-pretty-print.h"
28c92cbb 31#include "tree-pass.h"
28c92cbb 32#include "langhooks.h"
cb7f680b 33#include "tree-vectorizer.h"
28c92cbb 34
35/* This pass tries to distribute iterations of loops into several threads.
36 The implementation is straightforward -- for each loop we test whether its
37 iterations are independent, and if it is the case (and some additional
38 conditions regarding profitability and correctness are satisfied), we
75a70cf9 39 add GIMPLE_OMP_PARALLEL and GIMPLE_OMP_FOR codes and let omp expansion
40 machinery do its job.
48e1416a 41
28c92cbb 42 The most of the complexity is in bringing the code into shape expected
43 by the omp expanders:
75a70cf9 44 -- for GIMPLE_OMP_FOR, ensuring that the loop has only one induction
45 variable and that the exit test is at the start of the loop body
46 -- for GIMPLE_OMP_PARALLEL, replacing the references to local addressable
28c92cbb 47 variables by accesses through pointers, and breaking up ssa chains
48 by storing the values incoming to the parallelized loop to a structure
49 passed to the new function as an argument (something similar is done
50 in omp gimplification, unfortunately only a small part of the code
51 can be shared).
52
53 TODO:
54 -- if there are several parallelizable loops in a function, it may be
55 possible to generate the threads just once (using synchronization to
56 ensure that cross-loop dependences are obeyed).
0773b627 57 -- handling of common reduction patterns for outer loops.
58
59 More info can also be found at http://gcc.gnu.org/wiki/AutoParInGCC */
48e1416a 60/*
cb7f680b 61 Reduction handling:
f4a50267 62 currently we use vect_force_simple_reduction() to detect reduction patterns.
cb7f680b 63 The code transformation will be introduced by an example.
48e1416a 64
65
cb7f680b 66parloop
67{
68 int sum=1;
69
848674d0 70 for (i = 0; i < N; i++)
cb7f680b 71 {
72 x[i] = i + 3;
73 sum+=x[i];
74 }
75}
76
848674d0 77gimple-like code:
cb7f680b 78header_bb:
79
848674d0 80 # sum_29 = PHI <sum_11(5), 1(3)>
81 # i_28 = PHI <i_12(5), 0(3)>
82 D.1795_8 = i_28 + 3;
83 x[i_28] = D.1795_8;
84 sum_11 = D.1795_8 + sum_29;
85 i_12 = i_28 + 1;
86 if (N_6(D) > i_12)
87 goto header_bb;
88
cb7f680b 89
90exit_bb:
91
848674d0 92 # sum_21 = PHI <sum_11(4)>
93 printf (&"%d"[0], sum_21);
cb7f680b 94
95
96after reduction transformation (only relevant parts):
97
98parloop
99{
100
101....
102
848674d0 103
f0b5f617 104 # Storing the initial value given by the user. #
848674d0 105
5bb62c99 106 .paral_data_store.32.sum.27 = 1;
48e1416a 107
108 #pragma omp parallel num_threads(4)
cb7f680b 109
848674d0 110 #pragma omp for schedule(static)
5bb62c99 111
112 # The neutral element corresponding to the particular
113 reduction's operation, e.g. 0 for PLUS_EXPR,
114 1 for MULT_EXPR, etc. replaces the user's initial value. #
115
116 # sum.27_29 = PHI <sum.27_11, 0>
117
848674d0 118 sum.27_11 = D.1827_8 + sum.27_29;
5bb62c99 119
75a70cf9 120 GIMPLE_OMP_CONTINUE
cb7f680b 121
848674d0 122 # Adding this reduction phi is done at create_phi_for_local_result() #
123 # sum.27_56 = PHI <sum.27_11, 0>
75a70cf9 124 GIMPLE_OMP_RETURN
48e1416a 125
126 # Creating the atomic operation is done at
848674d0 127 create_call_for_reduction_1() #
cb7f680b 128
848674d0 129 #pragma omp atomic_load
130 D.1839_59 = *&.paral_data_load.33_51->reduction.23;
131 D.1840_60 = sum.27_56 + D.1839_59;
132 #pragma omp atomic_store (D.1840_60);
48e1416a 133
75a70cf9 134 GIMPLE_OMP_RETURN
48e1416a 135
848674d0 136 # collecting the result after the join of the threads is done at
137 create_loads_for_reductions().
5bb62c99 138 The value computed by the threads is loaded from the
139 shared struct. #
140
48e1416a 141
848674d0 142 .paral_data_load.33_52 = &.paral_data_store.32;
5bb62c99 143 sum_37 = .paral_data_load.33_52->sum.27;
848674d0 144 sum_43 = D.1795_41 + sum_37;
145
146 exit bb:
147 # sum_21 = PHI <sum_43, sum_26>
148 printf (&"%d"[0], sum_21);
149
150...
151
cb7f680b 152}
153
154*/
155
28c92cbb 156/* Minimal number of iterations of a loop that should be executed in each
157 thread. */
158#define MIN_PER_THREAD 100
159
48e1416a 160/* Element of the hashtable, representing a
cb7f680b 161 reduction in the current loop. */
162struct reduction_info
163{
75a70cf9 164 gimple reduc_stmt; /* reduction statement. */
165 gimple reduc_phi; /* The phi node defining the reduction. */
166 enum tree_code reduction_code;/* code for the reduction operation. */
71fa519d 167 unsigned reduc_version; /* SSA_NAME_VERSION of original reduc_phi
168 result. */
48e1416a 169 gimple keep_res; /* The PHI_RESULT of this phi is the resulting value
cb7f680b 170 of the reduction variable when existing the loop. */
5bb62c99 171 tree initial_value; /* The initial value of the reduction var before entering the loop. */
cb7f680b 172 tree field; /* the name of the field in the parloop data structure intended for reduction. */
cb7f680b 173 tree init; /* reduction initialization value. */
48e1416a 174 gimple new_phi; /* (helper field) Newly created phi node whose result
cb7f680b 175 will be passed to the atomic operation. Represents
176 the local result each thread computed for the reduction
177 operation. */
178};
179
180/* Equality and hash functions for hashtab code. */
181
182static int
183reduction_info_eq (const void *aa, const void *bb)
184{
185 const struct reduction_info *a = (const struct reduction_info *) aa;
186 const struct reduction_info *b = (const struct reduction_info *) bb;
187
188 return (a->reduc_phi == b->reduc_phi);
189}
190
191static hashval_t
192reduction_info_hash (const void *aa)
193{
194 const struct reduction_info *a = (const struct reduction_info *) aa;
195
71fa519d 196 return a->reduc_version;
cb7f680b 197}
198
199static struct reduction_info *
75a70cf9 200reduction_phi (htab_t reduction_list, gimple phi)
cb7f680b 201{
202 struct reduction_info tmpred, *red;
203
b7d90831 204 if (htab_elements (reduction_list) == 0 || phi == NULL)
cb7f680b 205 return NULL;
206
207 tmpred.reduc_phi = phi;
71fa519d 208 tmpred.reduc_version = gimple_uid (phi);
45ba1503 209 red = (struct reduction_info *) htab_find (reduction_list, &tmpred);
cb7f680b 210
211 return red;
212}
213
28c92cbb 214/* Element of hashtable of names to copy. */
215
216struct name_to_copy_elt
217{
218 unsigned version; /* The version of the name to copy. */
219 tree new_name; /* The new name used in the copy. */
220 tree field; /* The field of the structure used to pass the
221 value. */
222};
223
224/* Equality and hash functions for hashtab code. */
225
226static int
227name_to_copy_elt_eq (const void *aa, const void *bb)
228{
cb7f680b 229 const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
230 const struct name_to_copy_elt *b = (const struct name_to_copy_elt *) bb;
28c92cbb 231
232 return a->version == b->version;
233}
234
235static hashval_t
236name_to_copy_elt_hash (const void *aa)
237{
cb7f680b 238 const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
28c92cbb 239
240 return (hashval_t) a->version;
241}
242
e01f9f1f 243/* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE
244 matrix. Rather than use floats, we simply keep a single DENOMINATOR that
245 represents the denominator for every element in the matrix. */
246typedef struct lambda_trans_matrix_s
247{
248 lambda_matrix matrix;
249 int rowsize;
250 int colsize;
251 int denominator;
252} *lambda_trans_matrix;
253#define LTM_MATRIX(T) ((T)->matrix)
254#define LTM_ROWSIZE(T) ((T)->rowsize)
255#define LTM_COLSIZE(T) ((T)->colsize)
256#define LTM_DENOMINATOR(T) ((T)->denominator)
257
258/* Allocate a new transformation matrix. */
259
260static lambda_trans_matrix
261lambda_trans_matrix_new (int colsize, int rowsize,
262 struct obstack * lambda_obstack)
263{
264 lambda_trans_matrix ret;
265
266 ret = (lambda_trans_matrix)
267 obstack_alloc (lambda_obstack, sizeof (struct lambda_trans_matrix_s));
268 LTM_MATRIX (ret) = lambda_matrix_new (rowsize, colsize, lambda_obstack);
269 LTM_ROWSIZE (ret) = rowsize;
270 LTM_COLSIZE (ret) = colsize;
271 LTM_DENOMINATOR (ret) = 1;
272 return ret;
273}
274
275/* Multiply a vector VEC by a matrix MAT.
276 MAT is an M*N matrix, and VEC is a vector with length N. The result
277 is stored in DEST which must be a vector of length M. */
278
279static void
280lambda_matrix_vector_mult (lambda_matrix matrix, int m, int n,
281 lambda_vector vec, lambda_vector dest)
282{
283 int i, j;
284
285 lambda_vector_clear (dest, m);
286 for (i = 0; i < m; i++)
287 for (j = 0; j < n; j++)
288 dest[i] += matrix[i][j] * vec[j];
289}
290
291/* Return true if TRANS is a legal transformation matrix that respects
292 the dependence vectors in DISTS and DIRS. The conservative answer
293 is false.
294
295 "Wolfe proves that a unimodular transformation represented by the
296 matrix T is legal when applied to a loop nest with a set of
297 lexicographically non-negative distance vectors RDG if and only if
298 for each vector d in RDG, (T.d >= 0) is lexicographically positive.
299 i.e.: if and only if it transforms the lexicographically positive
300 distance vectors to lexicographically positive vectors. Note that
301 a unimodular matrix must transform the zero vector (and only it) to
302 the zero vector." S.Muchnick. */
303
304static bool
305lambda_transform_legal_p (lambda_trans_matrix trans,
306 int nb_loops,
307 VEC (ddr_p, heap) *dependence_relations)
308{
309 unsigned int i, j;
310 lambda_vector distres;
311 struct data_dependence_relation *ddr;
312
313 gcc_assert (LTM_COLSIZE (trans) == nb_loops
314 && LTM_ROWSIZE (trans) == nb_loops);
315
316 /* When there are no dependences, the transformation is correct. */
317 if (VEC_length (ddr_p, dependence_relations) == 0)
318 return true;
319
320 ddr = VEC_index (ddr_p, dependence_relations, 0);
321 if (ddr == NULL)
322 return true;
323
324 /* When there is an unknown relation in the dependence_relations, we
325 know that it is no worth looking at this loop nest: give up. */
326 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
327 return false;
328
329 distres = lambda_vector_new (nb_loops);
330
331 /* For each distance vector in the dependence graph. */
332 FOR_EACH_VEC_ELT (ddr_p, dependence_relations, i, ddr)
333 {
334 /* Don't care about relations for which we know that there is no
335 dependence, nor about read-read (aka. output-dependences):
336 these data accesses can happen in any order. */
337 if (DDR_ARE_DEPENDENT (ddr) == chrec_known
338 || (DR_IS_READ (DDR_A (ddr)) && DR_IS_READ (DDR_B (ddr))))
339 continue;
340
341 /* Conservatively answer: "this transformation is not valid". */
342 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
343 return false;
344
345 /* If the dependence could not be captured by a distance vector,
346 conservatively answer that the transform is not valid. */
347 if (DDR_NUM_DIST_VECTS (ddr) == 0)
348 return false;
349
350 /* Compute trans.dist_vect */
351 for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
352 {
353 lambda_matrix_vector_mult (LTM_MATRIX (trans), nb_loops, nb_loops,
354 DDR_DIST_VECT (ddr, j), distres);
355
356 if (!lambda_vector_lexico_pos (distres, nb_loops))
357 return false;
358 }
359 }
360 return true;
361}
5fa90eea 362
363/* Data dependency analysis. Returns true if the iterations of LOOP
364 are independent on each other (that is, if we can execute them
365 in parallel). */
28c92cbb 366
367static bool
1e33ad50 368loop_parallel_p (struct loop *loop, struct obstack * parloop_obstack)
28c92cbb 369{
a8af2e86 370 VEC (loop_p, heap) *loop_nest;
371 VEC (ddr_p, heap) *dependence_relations;
75a70cf9 372 VEC (data_reference_p, heap) *datarefs;
28c92cbb 373 lambda_trans_matrix trans;
374 bool ret = false;
28c92cbb 375
376 if (dump_file && (dump_flags & TDF_DETAILS))
b0fb253a 377 {
378 fprintf (dump_file, "Considering loop %d\n", loop->num);
379 if (!loop->inner)
380 fprintf (dump_file, "loop is innermost\n");
48e1416a 381 else
b0fb253a 382 fprintf (dump_file, "loop NOT innermost\n");
383 }
28c92cbb 384
28c92cbb 385 /* Check for problems with dependences. If the loop can be reversed,
386 the iterations are independent. */
387 datarefs = VEC_alloc (data_reference_p, heap, 10);
388 dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
a8af2e86 389 loop_nest = VEC_alloc (loop_p, heap, 3);
713f1f14 390 if (! compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
391 &dependence_relations))
392 {
393 if (dump_file && (dump_flags & TDF_DETAILS))
394 fprintf (dump_file, " FAILED: cannot analyze data dependencies\n");
395 ret = false;
396 goto end;
397 }
28c92cbb 398 if (dump_file && (dump_flags & TDF_DETAILS))
399 dump_data_dependence_relations (dump_file, dependence_relations);
400
1e33ad50 401 trans = lambda_trans_matrix_new (1, 1, parloop_obstack);
28c92cbb 402 LTM_MATRIX (trans)[0][0] = -1;
403
404 if (lambda_transform_legal_p (trans, 1, dependence_relations))
405 {
406 ret = true;
407 if (dump_file && (dump_flags & TDF_DETAILS))
408 fprintf (dump_file, " SUCCESS: may be parallelized\n");
409 }
410 else if (dump_file && (dump_flags & TDF_DETAILS))
cb7f680b 411 fprintf (dump_file,
412 " FAILED: data dependencies exist across iterations\n");
28c92cbb 413
713f1f14 414 end:
a8af2e86 415 VEC_free (loop_p, heap, loop_nest);
28c92cbb 416 free_dependence_relations (dependence_relations);
417 free_data_refs (datarefs);
418
419 return ret;
420}
421
d4fcfd16 422/* Return true when LOOP contains basic blocks marked with the
423 BB_IRREDUCIBLE_LOOP flag. */
424
425static inline bool
426loop_has_blocks_with_irreducible_flag (struct loop *loop)
427{
428 unsigned i;
429 basic_block *bbs = get_loop_body_in_dom_order (loop);
430 bool res = true;
431
432 for (i = 0; i < loop->num_nodes; i++)
433 if (bbs[i]->flags & BB_IRREDUCIBLE_LOOP)
434 goto end;
435
436 res = false;
437 end:
438 free (bbs);
439 return res;
440}
441
c1fb5b25 442/* Assigns the address of OBJ in TYPE to an ssa name, and returns this name.
e06f9c34 443 The assignment statement is placed on edge ENTRY. DECL_ADDRESS maps decls
c1fb5b25 444 to their addresses that can be reused. The address of OBJ is known to
ad57283e 445 be invariant in the whole function. Other needed statements are placed
446 right before GSI. */
28c92cbb 447
448static tree
ad57283e 449take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
450 gimple_stmt_iterator *gsi)
28c92cbb 451{
c1fb5b25 452 int uid;
28c92cbb 453 void **dslot;
454 struct int_tree_map ielt, *nielt;
75a70cf9 455 tree *var_p, name, bvar, addr;
456 gimple stmt;
457 gimple_seq stmts;
28c92cbb 458
c1fb5b25 459 /* Since the address of OBJ is invariant, the trees may be shared.
460 Avoid rewriting unrelated parts of the code. */
461 obj = unshare_expr (obj);
462 for (var_p = &obj;
463 handled_component_p (*var_p);
464 var_p = &TREE_OPERAND (*var_p, 0))
465 continue;
c1fb5b25 466
64ade643 467 /* Canonicalize the access to base on a MEM_REF. */
468 if (DECL_P (*var_p))
469 *var_p = build_simple_mem_ref (build_fold_addr_expr (*var_p));
470
471 /* Assign a canonical SSA name to the address of the base decl used
472 in the address and share it for all accesses and addresses based
473 on it. */
474 uid = DECL_UID (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0));
28c92cbb 475 ielt.uid = uid;
476 dslot = htab_find_slot_with_hash (decl_address, &ielt, uid, INSERT);
477 if (!*dslot)
478 {
ad57283e 479 if (gsi == NULL)
480 return NULL;
64ade643 481 addr = TREE_OPERAND (*var_p, 0);
482 bvar = create_tmp_var (TREE_TYPE (addr),
483 get_name (TREE_OPERAND
484 (TREE_OPERAND (*var_p, 0), 0)));
75a70cf9 485 stmt = gimple_build_assign (bvar, addr);
28c92cbb 486 name = make_ssa_name (bvar, stmt);
75a70cf9 487 gimple_assign_set_lhs (stmt, name);
488 gsi_insert_on_edge_immediate (entry, stmt);
28c92cbb 489
490 nielt = XNEW (struct int_tree_map);
491 nielt->uid = uid;
492 nielt->to = name;
493 *dslot = nielt;
28c92cbb 494 }
c1fb5b25 495 else
496 name = ((struct int_tree_map *) *dslot)->to;
28c92cbb 497
64ade643 498 /* Express the address in terms of the canonical SSA name. */
499 TREE_OPERAND (*var_p, 0) = name;
ad57283e 500 if (gsi == NULL)
501 return build_fold_addr_expr_with_type (obj, type);
502
64ade643 503 name = force_gimple_operand (build_addr (obj, current_function_decl),
504 &stmts, true, NULL_TREE);
505 if (!gimple_seq_empty_p (stmts))
ad57283e 506 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
28c92cbb 507
64ade643 508 if (!useless_type_conversion_p (type, TREE_TYPE (name)))
c1fb5b25 509 {
75a70cf9 510 name = force_gimple_operand (fold_convert (type, name), &stmts, true,
c1fb5b25 511 NULL_TREE);
75a70cf9 512 if (!gimple_seq_empty_p (stmts))
ad57283e 513 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
c1fb5b25 514 }
28c92cbb 515
516 return name;
517}
518
cb7f680b 519/* Callback for htab_traverse. Create the initialization statement
48e1416a 520 for reduction described in SLOT, and place it at the preheader of
cb7f680b 521 the loop described in DATA. */
522
523static int
524initialize_reductions (void **slot, void *data)
525{
cb7f680b 526 tree init, c;
cb7f680b 527 tree bvar, type, arg;
528 edge e;
529
45ba1503 530 struct reduction_info *const reduc = (struct reduction_info *) *slot;
cb7f680b 531 struct loop *loop = (struct loop *) data;
532
48e1416a 533 /* Create initialization in preheader:
cb7f680b 534 reduction_variable = initialization value of reduction. */
535
48e1416a 536 /* In the phi node at the header, replace the argument coming
cb7f680b 537 from the preheader with the reduction initialization value. */
538
539 /* Create a new variable to initialize the reduction. */
540 type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
541 bvar = create_tmp_var (type, "reduction");
cb7f680b 542
e60a6f7b 543 c = build_omp_clause (gimple_location (reduc->reduc_stmt),
544 OMP_CLAUSE_REDUCTION);
cb7f680b 545 OMP_CLAUSE_REDUCTION_CODE (c) = reduc->reduction_code;
75a70cf9 546 OMP_CLAUSE_DECL (c) = SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt));
cb7f680b 547
548 init = omp_reduction_init (c, TREE_TYPE (bvar));
549 reduc->init = init;
550
48e1416a 551 /* Replace the argument representing the initialization value
552 with the initialization value for the reduction (neutral
553 element for the particular operation, e.g. 0 for PLUS_EXPR,
554 1 for MULT_EXPR, etc).
555 Keep the old value in a new variable "reduction_initial",
556 that will be taken in consideration after the parallel
848674d0 557 computing is done. */
cb7f680b 558
559 e = loop_preheader_edge (loop);
560 arg = PHI_ARG_DEF_FROM_EDGE (reduc->reduc_phi, e);
561 /* Create new variable to hold the initial value. */
cb7f680b 562
cb7f680b 563 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE
848674d0 564 (reduc->reduc_phi, loop_preheader_edge (loop)), init);
5bb62c99 565 reduc->initial_value = arg;
cb7f680b 566 return 1;
567}
28c92cbb 568
569struct elv_data
570{
75a70cf9 571 struct walk_stmt_info info;
e06f9c34 572 edge entry;
28c92cbb 573 htab_t decl_address;
ad57283e 574 gimple_stmt_iterator *gsi;
28c92cbb 575 bool changed;
ad57283e 576 bool reset;
28c92cbb 577};
578
e06f9c34 579/* Eliminates references to local variables in *TP out of the single
580 entry single exit region starting at DTA->ENTRY.
581 DECL_ADDRESS contains addresses of the references that had their
582 address taken already. If the expression is changed, CHANGED is
583 set to true. Callback for walk_tree. */
cb7f680b 584
28c92cbb 585static tree
c1fb5b25 586eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data)
28c92cbb 587{
45ba1503 588 struct elv_data *const dta = (struct elv_data *) data;
c1fb5b25 589 tree t = *tp, var, addr, addr_type, type, obj;
28c92cbb 590
591 if (DECL_P (t))
592 {
593 *walk_subtrees = 0;
594
595 if (!SSA_VAR_P (t) || DECL_EXTERNAL (t))
596 return NULL_TREE;
597
598 type = TREE_TYPE (t);
599 addr_type = build_pointer_type (type);
ad57283e 600 addr = take_address_of (t, addr_type, dta->entry, dta->decl_address,
601 dta->gsi);
602 if (dta->gsi == NULL && addr == NULL_TREE)
603 {
604 dta->reset = true;
605 return NULL_TREE;
606 }
607
182cf5a9 608 *tp = build_simple_mem_ref (addr);
28c92cbb 609
610 dta->changed = true;
611 return NULL_TREE;
612 }
613
614 if (TREE_CODE (t) == ADDR_EXPR)
615 {
c1fb5b25 616 /* ADDR_EXPR may appear in two contexts:
617 -- as a gimple operand, when the address taken is a function invariant
618 -- as gimple rhs, when the resulting address in not a function
619 invariant
620 We do not need to do anything special in the latter case (the base of
621 the memory reference whose address is taken may be replaced in the
622 DECL_P case). The former case is more complicated, as we need to
623 ensure that the new address is still a gimple operand. Thus, it
624 is not sufficient to replace just the base of the memory reference --
625 we need to move the whole computation of the address out of the
626 loop. */
627 if (!is_gimple_val (t))
28c92cbb 628 return NULL_TREE;
629
630 *walk_subtrees = 0;
c1fb5b25 631 obj = TREE_OPERAND (t, 0);
632 var = get_base_address (obj);
633 if (!var || !SSA_VAR_P (var) || DECL_EXTERNAL (var))
28c92cbb 634 return NULL_TREE;
635
636 addr_type = TREE_TYPE (t);
ad57283e 637 addr = take_address_of (obj, addr_type, dta->entry, dta->decl_address,
638 dta->gsi);
639 if (dta->gsi == NULL && addr == NULL_TREE)
640 {
641 dta->reset = true;
642 return NULL_TREE;
643 }
28c92cbb 644 *tp = addr;
645
646 dta->changed = true;
647 return NULL_TREE;
648 }
649
75a70cf9 650 if (!EXPR_P (t))
28c92cbb 651 *walk_subtrees = 0;
652
653 return NULL_TREE;
654}
655
ad57283e 656/* Moves the references to local variables in STMT at *GSI out of the single
e06f9c34 657 entry single exit region starting at ENTRY. DECL_ADDRESS contains
658 addresses of the references that had their address taken
659 already. */
28c92cbb 660
661static void
ad57283e 662eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi,
28c92cbb 663 htab_t decl_address)
664{
665 struct elv_data dta;
ad57283e 666 gimple stmt = gsi_stmt (*gsi);
28c92cbb 667
75a70cf9 668 memset (&dta.info, '\0', sizeof (dta.info));
e06f9c34 669 dta.entry = entry;
28c92cbb 670 dta.decl_address = decl_address;
671 dta.changed = false;
ad57283e 672 dta.reset = false;
28c92cbb 673
9845d120 674 if (gimple_debug_bind_p (stmt))
ad57283e 675 {
676 dta.gsi = NULL;
677 walk_tree (gimple_debug_bind_get_value_ptr (stmt),
678 eliminate_local_variables_1, &dta.info, NULL);
679 if (dta.reset)
680 {
681 gimple_debug_bind_reset_value (stmt);
682 dta.changed = true;
683 }
684 }
9845d120 685 else
ad57283e 686 {
687 dta.gsi = gsi;
688 walk_gimple_op (stmt, eliminate_local_variables_1, &dta.info);
689 }
28c92cbb 690
691 if (dta.changed)
692 update_stmt (stmt);
693}
694
e06f9c34 695/* Eliminates the references to local variables from the single entry
696 single exit region between the ENTRY and EXIT edges.
48e1416a 697
cb7f680b 698 This includes:
48e1416a 699 1) Taking address of a local variable -- these are moved out of the
700 region (and temporary variable is created to hold the address if
cb7f680b 701 necessary).
e06f9c34 702
28c92cbb 703 2) Dereferencing a local variable -- these are replaced with indirect
cb7f680b 704 references. */
28c92cbb 705
706static void
e06f9c34 707eliminate_local_variables (edge entry, edge exit)
28c92cbb 708{
e06f9c34 709 basic_block bb;
710 VEC (basic_block, heap) *body = VEC_alloc (basic_block, heap, 3);
28c92cbb 711 unsigned i;
75a70cf9 712 gimple_stmt_iterator gsi;
ad57283e 713 bool has_debug_stmt = false;
28c92cbb 714 htab_t decl_address = htab_create (10, int_tree_map_hash, int_tree_map_eq,
715 free);
e06f9c34 716 basic_block entry_bb = entry->src;
717 basic_block exit_bb = exit->dest;
28c92cbb 718
e06f9c34 719 gather_blocks_in_sese_region (entry_bb, exit_bb, &body);
28c92cbb 720
48148244 721 FOR_EACH_VEC_ELT (basic_block, body, i, bb)
e06f9c34 722 if (bb != entry_bb && bb != exit_bb)
75a70cf9 723 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
841424cc 724 if (is_gimple_debug (gsi_stmt (gsi)))
725 {
726 if (gimple_debug_bind_p (gsi_stmt (gsi)))
727 has_debug_stmt = true;
728 }
ad57283e 729 else
730 eliminate_local_variables_stmt (entry, &gsi, decl_address);
731
732 if (has_debug_stmt)
733 FOR_EACH_VEC_ELT (basic_block, body, i, bb)
734 if (bb != entry_bb && bb != exit_bb)
735 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
736 if (gimple_debug_bind_p (gsi_stmt (gsi)))
737 eliminate_local_variables_stmt (entry, &gsi, decl_address);
28c92cbb 738
739 htab_delete (decl_address);
e06f9c34 740 VEC_free (basic_block, heap, body);
741}
742
743/* Returns true if expression EXPR is not defined between ENTRY and
744 EXIT, i.e. if all its operands are defined outside of the region. */
745
746static bool
747expr_invariant_in_region_p (edge entry, edge exit, tree expr)
748{
749 basic_block entry_bb = entry->src;
750 basic_block exit_bb = exit->dest;
751 basic_block def_bb;
e06f9c34 752
753 if (is_gimple_min_invariant (expr))
754 return true;
755
756 if (TREE_CODE (expr) == SSA_NAME)
757 {
75a70cf9 758 def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
e06f9c34 759 if (def_bb
760 && dominated_by_p (CDI_DOMINATORS, def_bb, entry_bb)
761 && !dominated_by_p (CDI_DOMINATORS, def_bb, exit_bb))
762 return false;
763
764 return true;
765 }
766
75a70cf9 767 return false;
28c92cbb 768}
769
770/* If COPY_NAME_P is true, creates and returns a duplicate of NAME.
771 The copies are stored to NAME_COPIES, if NAME was already duplicated,
772 its duplicate stored in NAME_COPIES is returned.
48e1416a 773
28c92cbb 774 Regardless of COPY_NAME_P, the decl used as a base of the ssa name is also
775 duplicated, storing the copies in DECL_COPIES. */
776
777static tree
e06f9c34 778separate_decls_in_region_name (tree name,
779 htab_t name_copies, htab_t decl_copies,
780 bool copy_name_p)
28c92cbb 781{
782 tree copy, var, var_copy;
783 unsigned idx, uid, nuid;
784 struct int_tree_map ielt, *nielt;
785 struct name_to_copy_elt elt, *nelt;
786 void **slot, **dslot;
787
788 if (TREE_CODE (name) != SSA_NAME)
789 return name;
790
791 idx = SSA_NAME_VERSION (name);
792 elt.version = idx;
793 slot = htab_find_slot_with_hash (name_copies, &elt, idx,
794 copy_name_p ? INSERT : NO_INSERT);
795 if (slot && *slot)
796 return ((struct name_to_copy_elt *) *slot)->new_name;
797
ec11736b 798 if (copy_name_p)
799 {
800 copy = duplicate_ssa_name (name, NULL);
801 nelt = XNEW (struct name_to_copy_elt);
802 nelt->version = idx;
803 nelt->new_name = copy;
804 nelt->field = NULL_TREE;
805 *slot = nelt;
806 }
807 else
808 {
809 gcc_assert (!slot);
810 copy = name;
811 }
812
28c92cbb 813 var = SSA_NAME_VAR (name);
ec11736b 814 if (!var)
815 return copy;
816
28c92cbb 817 uid = DECL_UID (var);
818 ielt.uid = uid;
819 dslot = htab_find_slot_with_hash (decl_copies, &ielt, uid, INSERT);
820 if (!*dslot)
821 {
822 var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
55ed4df6 823 DECL_GIMPLE_REG_P (var_copy) = DECL_GIMPLE_REG_P (var);
28c92cbb 824 nielt = XNEW (struct int_tree_map);
825 nielt->uid = uid;
826 nielt->to = var_copy;
827 *dslot = nielt;
828
829 /* Ensure that when we meet this decl next time, we won't duplicate
cb7f680b 830 it again. */
28c92cbb 831 nuid = DECL_UID (var_copy);
832 ielt.uid = nuid;
833 dslot = htab_find_slot_with_hash (decl_copies, &ielt, nuid, INSERT);
834 gcc_assert (!*dslot);
835 nielt = XNEW (struct int_tree_map);
836 nielt->uid = nuid;
837 nielt->to = var_copy;
838 *dslot = nielt;
839 }
840 else
841 var_copy = ((struct int_tree_map *) *dslot)->to;
842
3b652cc1 843 replace_ssa_name_symbol (copy, var_copy);
28c92cbb 844 return copy;
845}
846
e06f9c34 847/* Finds the ssa names used in STMT that are defined outside the
848 region between ENTRY and EXIT and replaces such ssa names with
849 their duplicates. The duplicates are stored to NAME_COPIES. Base
850 decls of all ssa names used in STMT (including those defined in
851 LOOP) are replaced with the new temporary variables; the
852 replacement decls are stored in DECL_COPIES. */
28c92cbb 853
854static void
75a70cf9 855separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
e06f9c34 856 htab_t name_copies, htab_t decl_copies)
28c92cbb 857{
858 use_operand_p use;
859 def_operand_p def;
860 ssa_op_iter oi;
861 tree name, copy;
862 bool copy_name_p;
863
28c92cbb 864 FOR_EACH_PHI_OR_STMT_DEF (def, stmt, oi, SSA_OP_DEF)
cb7f680b 865 {
866 name = DEF_FROM_PTR (def);
867 gcc_assert (TREE_CODE (name) == SSA_NAME);
e06f9c34 868 copy = separate_decls_in_region_name (name, name_copies, decl_copies,
869 false);
cb7f680b 870 gcc_assert (copy == name);
871 }
28c92cbb 872
873 FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE)
cb7f680b 874 {
875 name = USE_FROM_PTR (use);
876 if (TREE_CODE (name) != SSA_NAME)
877 continue;
878
e06f9c34 879 copy_name_p = expr_invariant_in_region_p (entry, exit, name);
880 copy = separate_decls_in_region_name (name, name_copies, decl_copies,
881 copy_name_p);
cb7f680b 882 SET_USE (use, copy);
883 }
28c92cbb 884}
885
9845d120 886/* Finds the ssa names used in STMT that are defined outside the
887 region between ENTRY and EXIT and replaces such ssa names with
888 their duplicates. The duplicates are stored to NAME_COPIES. Base
889 decls of all ssa names used in STMT (including those defined in
890 LOOP) are replaced with the new temporary variables; the
891 replacement decls are stored in DECL_COPIES. */
892
893static bool
841424cc 894separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
895 htab_t decl_copies)
9845d120 896{
897 use_operand_p use;
898 ssa_op_iter oi;
899 tree var, name;
900 struct int_tree_map ielt;
901 struct name_to_copy_elt elt;
902 void **slot, **dslot;
903
841424cc 904 if (gimple_debug_bind_p (stmt))
905 var = gimple_debug_bind_get_var (stmt);
906 else if (gimple_debug_source_bind_p (stmt))
907 var = gimple_debug_source_bind_get_var (stmt);
908 else
909 return true;
eee873f6 910 if (TREE_CODE (var) == DEBUG_EXPR_DECL || TREE_CODE (var) == LABEL_DECL)
9e3c8673 911 return true;
9845d120 912 gcc_assert (DECL_P (var) && SSA_VAR_P (var));
913 ielt.uid = DECL_UID (var);
914 dslot = htab_find_slot_with_hash (decl_copies, &ielt, ielt.uid, NO_INSERT);
915 if (!dslot)
916 return true;
841424cc 917 if (gimple_debug_bind_p (stmt))
918 gimple_debug_bind_set_var (stmt, ((struct int_tree_map *) *dslot)->to);
919 else if (gimple_debug_source_bind_p (stmt))
920 gimple_debug_source_bind_set_var (stmt, ((struct int_tree_map *) *dslot)->to);
9845d120 921
922 FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE)
923 {
924 name = USE_FROM_PTR (use);
925 if (TREE_CODE (name) != SSA_NAME)
926 continue;
927
928 elt.version = SSA_NAME_VERSION (name);
929 slot = htab_find_slot_with_hash (name_copies, &elt, elt.version, NO_INSERT);
930 if (!slot)
931 {
932 gimple_debug_bind_reset_value (stmt);
933 update_stmt (stmt);
934 break;
935 }
936
937 SET_USE (use, ((struct name_to_copy_elt *) *slot)->new_name);
938 }
939
940 return false;
941}
942
848674d0 943/* Callback for htab_traverse. Adds a field corresponding to the reduction
944 specified in SLOT. The type is passed in DATA. */
945
946static int
947add_field_for_reduction (void **slot, void *data)
cb7f680b 948{
48e1416a 949
45ba1503 950 struct reduction_info *const red = (struct reduction_info *) *slot;
951 tree const type = (tree) data;
75a70cf9 952 tree var = SSA_NAME_VAR (gimple_assign_lhs (red->reduc_stmt));
e60a6f7b 953 tree field = build_decl (gimple_location (red->reduc_stmt),
954 FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
848674d0 955
956 insert_field_into_struct (type, field);
957
958 red->field = field;
959
960 return 1;
961}
cb7f680b 962
28c92cbb 963/* Callback for htab_traverse. Adds a field corresponding to a ssa name
48e1416a 964 described in SLOT. The type is passed in DATA. */
28c92cbb 965
966static int
967add_field_for_name (void **slot, void *data)
968{
45ba1503 969 struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
970 tree type = (tree) data;
28c92cbb 971 tree name = ssa_name (elt->version);
ec11736b 972 tree field = build_decl (UNKNOWN_LOCATION,
973 FIELD_DECL, SSA_NAME_IDENTIFIER (name),
974 TREE_TYPE (name));
28c92cbb 975
976 insert_field_into_struct (type, field);
977 elt->field = field;
cb7f680b 978
28c92cbb 979 return 1;
980}
981
48e1416a 982/* Callback for htab_traverse. A local result is the intermediate result
983 computed by a single
f0b5f617 984 thread, or the initial value in case no iteration was executed.
48e1416a 985 This function creates a phi node reflecting these values.
986 The phi's result will be stored in NEW_PHI field of the
987 reduction's data structure. */
cb7f680b 988
989static int
990create_phi_for_local_result (void **slot, void *data)
991{
45ba1503 992 struct reduction_info *const reduc = (struct reduction_info *) *slot;
993 const struct loop *const loop = (const struct loop *) data;
cb7f680b 994 edge e;
75a70cf9 995 gimple new_phi;
cb7f680b 996 basic_block store_bb;
997 tree local_res;
efbcb6de 998 source_location locus;
cb7f680b 999
48e1416a 1000 /* STORE_BB is the block where the phi
1001 should be stored. It is the destination of the loop exit.
75a70cf9 1002 (Find the fallthru edge from GIMPLE_OMP_CONTINUE). */
cb7f680b 1003 store_bb = FALLTHRU_EDGE (loop->latch)->dest;
1004
1005 /* STORE_BB has two predecessors. One coming from the loop
1006 (the reduction's result is computed at the loop),
48e1416a 1007 and another coming from a block preceding the loop,
1008 when no iterations
1009 are executed (the initial value should be taken). */
cb7f680b 1010 if (EDGE_PRED (store_bb, 0) == FALLTHRU_EDGE (loop->latch))
1011 e = EDGE_PRED (store_bb, 1);
1012 else
1013 e = EDGE_PRED (store_bb, 0);
7ecda5e8 1014 local_res = copy_ssa_name (gimple_assign_lhs (reduc->reduc_stmt), NULL);
efbcb6de 1015 locus = gimple_location (reduc->reduc_stmt);
cb7f680b 1016 new_phi = create_phi_node (local_res, store_bb);
60d535d2 1017 add_phi_arg (new_phi, reduc->init, e, locus);
75a70cf9 1018 add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
60d535d2 1019 FALLTHRU_EDGE (loop->latch), locus);
cb7f680b 1020 reduc->new_phi = new_phi;
1021
1022 return 1;
1023}
28c92cbb 1024
1025struct clsn_data
1026{
1027 tree store;
1028 tree load;
1029
1030 basic_block store_bb;
1031 basic_block load_bb;
1032};
1033
cb7f680b 1034/* Callback for htab_traverse. Create an atomic instruction for the
48e1416a 1035 reduction described in SLOT.
cb7f680b 1036 DATA annotates the place in memory the atomic operation relates to,
1037 and the basic block it needs to be generated in. */
1038
1039static int
1040create_call_for_reduction_1 (void **slot, void *data)
1041{
45ba1503 1042 struct reduction_info *const reduc = (struct reduction_info *) *slot;
1043 struct clsn_data *const clsn_data = (struct clsn_data *) data;
75a70cf9 1044 gimple_stmt_iterator gsi;
cb7f680b 1045 tree type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
cb7f680b 1046 tree load_struct;
1047 basic_block bb;
1048 basic_block new_bb;
1049 edge e;
f018d957 1050 tree t, addr, ref, x;
75a70cf9 1051 tree tmp_load, name;
1052 gimple load;
cb7f680b 1053
182cf5a9 1054 load_struct = build_simple_mem_ref (clsn_data->load);
cb7f680b 1055 t = build3 (COMPONENT_REF, type, load_struct, reduc->field, NULL_TREE);
cb7f680b 1056
1057 addr = build_addr (t, current_function_decl);
1058
1059 /* Create phi node. */
1060 bb = clsn_data->load_bb;
1061
1062 e = split_block (bb, t);
1063 new_bb = e->dest;
1064
1065 tmp_load = create_tmp_var (TREE_TYPE (TREE_TYPE (addr)), NULL);
cb7f680b 1066 tmp_load = make_ssa_name (tmp_load, NULL);
75a70cf9 1067 load = gimple_build_omp_atomic_load (tmp_load, addr);
cb7f680b 1068 SSA_NAME_DEF_STMT (tmp_load) = load;
75a70cf9 1069 gsi = gsi_start_bb (new_bb);
1070 gsi_insert_after (&gsi, load, GSI_NEW_STMT);
cb7f680b 1071
1072 e = split_block (new_bb, load);
1073 new_bb = e->dest;
75a70cf9 1074 gsi = gsi_start_bb (new_bb);
cb7f680b 1075 ref = tmp_load;
75a70cf9 1076 x = fold_build2 (reduc->reduction_code,
1077 TREE_TYPE (PHI_RESULT (reduc->new_phi)), ref,
1078 PHI_RESULT (reduc->new_phi));
cb7f680b 1079
75a70cf9 1080 name = force_gimple_operand_gsi (&gsi, x, true, NULL_TREE, true,
1081 GSI_CONTINUE_LINKING);
cb7f680b 1082
75a70cf9 1083 gsi_insert_after (&gsi, gimple_build_omp_atomic_store (name), GSI_NEW_STMT);
cb7f680b 1084 return 1;
1085}
1086
48e1416a 1087/* Create the atomic operation at the join point of the threads.
1088 REDUCTION_LIST describes the reductions in the LOOP.
1089 LD_ST_DATA describes the shared data structure where
cb7f680b 1090 shared data is stored in and loaded from. */
1091static void
48e1416a 1092create_call_for_reduction (struct loop *loop, htab_t reduction_list,
cb7f680b 1093 struct clsn_data *ld_st_data)
1094{
1095 htab_traverse (reduction_list, create_phi_for_local_result, loop);
75a70cf9 1096 /* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
cb7f680b 1097 ld_st_data->load_bb = FALLTHRU_EDGE (loop->latch)->dest;
1098 htab_traverse (reduction_list, create_call_for_reduction_1, ld_st_data);
1099}
1100
5bb62c99 1101/* Callback for htab_traverse. Loads the final reduction value at the
1102 join point of all threads, and inserts it in the right place. */
cb7f680b 1103
1104static int
1105create_loads_for_reductions (void **slot, void *data)
1106{
45ba1503 1107 struct reduction_info *const red = (struct reduction_info *) *slot;
1108 struct clsn_data *const clsn_data = (struct clsn_data *) data;
75a70cf9 1109 gimple stmt;
1110 gimple_stmt_iterator gsi;
1111 tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
cb7f680b 1112 tree load_struct;
5bb62c99 1113 tree name;
cb7f680b 1114 tree x;
1115
75a70cf9 1116 gsi = gsi_after_labels (clsn_data->load_bb);
182cf5a9 1117 load_struct = build_simple_mem_ref (clsn_data->load);
cb7f680b 1118 load_struct = build3 (COMPONENT_REF, type, load_struct, red->field,
1119 NULL_TREE);
cb7f680b 1120
5bb62c99 1121 x = load_struct;
cb7f680b 1122 name = PHI_RESULT (red->keep_res);
75a70cf9 1123 stmt = gimple_build_assign (name, x);
cb7f680b 1124 SSA_NAME_DEF_STMT (name) = stmt;
1125
75a70cf9 1126 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
cb7f680b 1127
75a70cf9 1128 for (gsi = gsi_start_phis (gimple_bb (red->keep_res));
1129 !gsi_end_p (gsi); gsi_next (&gsi))
1130 if (gsi_stmt (gsi) == red->keep_res)
1131 {
1132 remove_phi_node (&gsi, false);
1133 return 1;
1134 }
1135 gcc_unreachable ();
cb7f680b 1136}
1137
48e1416a 1138/* Load the reduction result that was stored in LD_ST_DATA.
cb7f680b 1139 REDUCTION_LIST describes the list of reductions that the
f0b5f617 1140 loads should be generated for. */
cb7f680b 1141static void
48e1416a 1142create_final_loads_for_reduction (htab_t reduction_list,
cb7f680b 1143 struct clsn_data *ld_st_data)
1144{
75a70cf9 1145 gimple_stmt_iterator gsi;
cb7f680b 1146 tree t;
75a70cf9 1147 gimple stmt;
cb7f680b 1148
75a70cf9 1149 gsi = gsi_after_labels (ld_st_data->load_bb);
cb7f680b 1150 t = build_fold_addr_expr (ld_st_data->store);
75a70cf9 1151 stmt = gimple_build_assign (ld_st_data->load, t);
cb7f680b 1152
75a70cf9 1153 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1154 SSA_NAME_DEF_STMT (ld_st_data->load) = stmt;
cb7f680b 1155
1156 htab_traverse (reduction_list, create_loads_for_reductions, ld_st_data);
1157
1158}
1159
848674d0 1160/* Callback for htab_traverse. Store the neutral value for the
1161 particular reduction's operation, e.g. 0 for PLUS_EXPR,
1162 1 for MULT_EXPR, etc. into the reduction field.
48e1416a 1163 The reduction is specified in SLOT. The store information is
1164 passed in DATA. */
848674d0 1165
1166static int
1167create_stores_for_reduction (void **slot, void *data)
1168{
45ba1503 1169 struct reduction_info *const red = (struct reduction_info *) *slot;
1170 struct clsn_data *const clsn_data = (struct clsn_data *) data;
75a70cf9 1171 tree t;
1172 gimple stmt;
1173 gimple_stmt_iterator gsi;
1174 tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
1175
1176 gsi = gsi_last_bb (clsn_data->store_bb);
1177 t = build3 (COMPONENT_REF, type, clsn_data->store, red->field, NULL_TREE);
1178 stmt = gimple_build_assign (t, red->initial_value);
75a70cf9 1179 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
848674d0 1180
1181 return 1;
1182}
1183
cb7f680b 1184/* Callback for htab_traverse. Creates loads to a field of LOAD in LOAD_BB and
1185 store to a field of STORE in STORE_BB for the ssa name and its duplicate
1186 specified in SLOT. */
1187
28c92cbb 1188static int
1189create_loads_and_stores_for_name (void **slot, void *data)
1190{
45ba1503 1191 struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
1192 struct clsn_data *const clsn_data = (struct clsn_data *) data;
75a70cf9 1193 tree t;
1194 gimple stmt;
1195 gimple_stmt_iterator gsi;
28c92cbb 1196 tree type = TREE_TYPE (elt->new_name);
28c92cbb 1197 tree load_struct;
1198
75a70cf9 1199 gsi = gsi_last_bb (clsn_data->store_bb);
1200 t = build3 (COMPONENT_REF, type, clsn_data->store, elt->field, NULL_TREE);
1201 stmt = gimple_build_assign (t, ssa_name (elt->version));
75a70cf9 1202 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1203
75a70cf9 1204 gsi = gsi_last_bb (clsn_data->load_bb);
182cf5a9 1205 load_struct = build_simple_mem_ref (clsn_data->load);
75a70cf9 1206 t = build3 (COMPONENT_REF, type, load_struct, elt->field, NULL_TREE);
1207 stmt = gimple_build_assign (elt->new_name, t);
28c92cbb 1208 SSA_NAME_DEF_STMT (elt->new_name) = stmt;
75a70cf9 1209 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1210
1211 return 1;
1212}
1213
1214/* Moves all the variables used in LOOP and defined outside of it (including
1215 the initial values of loop phi nodes, and *PER_THREAD if it is a ssa
1216 name) to a structure created for this purpose. The code
48e1416a 1217
28c92cbb 1218 while (1)
1219 {
1220 use (a);
1221 use (b);
1222 }
1223
1224 is transformed this way:
1225
1226 bb0:
1227 old.a = a;
1228 old.b = b;
1229
1230 bb1:
1231 a' = new->a;
1232 b' = new->b;
1233 while (1)
1234 {
1235 use (a');
1236 use (b');
1237 }
1238
1239 `old' is stored to *ARG_STRUCT and `new' is stored to NEW_ARG_STRUCT. The
1240 pointer `new' is intentionally not initialized (the loop will be split to a
1241 separate function later, and `new' will be initialized from its arguments).
cb7f680b 1242 LD_ST_DATA holds information about the shared data structure used to pass
48e1416a 1243 information among the threads. It is initialized here, and
1244 gen_parallel_loop will pass it to create_call_for_reduction that
1245 needs this information. REDUCTION_LIST describes the reductions
cb7f680b 1246 in LOOP. */
28c92cbb 1247
1248static void
e06f9c34 1249separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
48e1416a 1250 tree *arg_struct, tree *new_arg_struct,
e06f9c34 1251 struct clsn_data *ld_st_data)
cb7f680b 1252
28c92cbb 1253{
e06f9c34 1254 basic_block bb1 = split_edge (entry);
28c92cbb 1255 basic_block bb0 = single_pred (bb1);
1256 htab_t name_copies = htab_create (10, name_to_copy_elt_hash,
1257 name_to_copy_elt_eq, free);
1258 htab_t decl_copies = htab_create (10, int_tree_map_hash, int_tree_map_eq,
1259 free);
28c92cbb 1260 unsigned i;
75a70cf9 1261 tree type, type_name, nvar;
1262 gimple_stmt_iterator gsi;
28c92cbb 1263 struct clsn_data clsn_data;
e06f9c34 1264 VEC (basic_block, heap) *body = VEC_alloc (basic_block, heap, 3);
1265 basic_block bb;
1266 basic_block entry_bb = bb1;
1267 basic_block exit_bb = exit->dest;
9845d120 1268 bool has_debug_stmt = false;
28c92cbb 1269
75a70cf9 1270 entry = single_succ_edge (entry_bb);
e06f9c34 1271 gather_blocks_in_sese_region (entry_bb, exit_bb, &body);
28c92cbb 1272
48148244 1273 FOR_EACH_VEC_ELT (basic_block, body, i, bb)
e06f9c34 1274 {
48e1416a 1275 if (bb != entry_bb && bb != exit_bb)
e06f9c34 1276 {
75a70cf9 1277 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1278 separate_decls_in_region_stmt (entry, exit, gsi_stmt (gsi),
1279 name_copies, decl_copies);
1280
1281 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
9845d120 1282 {
1283 gimple stmt = gsi_stmt (gsi);
1284
1285 if (is_gimple_debug (stmt))
1286 has_debug_stmt = true;
1287 else
1288 separate_decls_in_region_stmt (entry, exit, stmt,
1289 name_copies, decl_copies);
1290 }
e06f9c34 1291 }
28c92cbb 1292 }
e06f9c34 1293
9845d120 1294 /* Now process debug bind stmts. We must not create decls while
1295 processing debug stmts, so we defer their processing so as to
1296 make sure we will have debug info for as many variables as
1297 possible (all of those that were dealt with in the loop above),
1298 and discard those for which we know there's nothing we can
1299 do. */
1300 if (has_debug_stmt)
48148244 1301 FOR_EACH_VEC_ELT (basic_block, body, i, bb)
9845d120 1302 if (bb != entry_bb && bb != exit_bb)
1303 {
1304 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1305 {
1306 gimple stmt = gsi_stmt (gsi);
1307
841424cc 1308 if (is_gimple_debug (stmt))
9845d120 1309 {
841424cc 1310 if (separate_decls_in_region_debug (stmt, name_copies,
1311 decl_copies))
9845d120 1312 {
1313 gsi_remove (&gsi, true);
1314 continue;
1315 }
1316 }
1317
1318 gsi_next (&gsi);
1319 }
1320 }
1321
e06f9c34 1322 VEC_free (basic_block, heap, body);
28c92cbb 1323
48e1416a 1324 if (htab_elements (name_copies) == 0 && htab_elements (reduction_list) == 0)
28c92cbb 1325 {
1326 /* It may happen that there is nothing to copy (if there are only
cb7f680b 1327 loop carried and external variables in the loop). */
28c92cbb 1328 *arg_struct = NULL;
1329 *new_arg_struct = NULL;
1330 }
1331 else
1332 {
1333 /* Create the type for the structure to store the ssa names to. */
1334 type = lang_hooks.types.make_type (RECORD_TYPE);
0aecb55e 1335 type_name = build_decl (UNKNOWN_LOCATION,
e60a6f7b 1336 TYPE_DECL, create_tmp_var_name (".paral_data"),
28c92cbb 1337 type);
1338 TYPE_NAME (type) = type_name;
1339
848674d0 1340 htab_traverse (name_copies, add_field_for_name, type);
e06f9c34 1341 if (reduction_list && htab_elements (reduction_list) > 0)
848674d0 1342 {
1343 /* Create the fields for reductions. */
1344 htab_traverse (reduction_list, add_field_for_reduction,
1345 type);
1346 }
28c92cbb 1347 layout_type (type);
48e1416a 1348
28c92cbb 1349 /* Create the loads and stores. */
1350 *arg_struct = create_tmp_var (type, ".paral_data_store");
28c92cbb 1351 nvar = create_tmp_var (build_pointer_type (type), ".paral_data_load");
75a70cf9 1352 *new_arg_struct = make_ssa_name (nvar, NULL);
28c92cbb 1353
cb7f680b 1354 ld_st_data->store = *arg_struct;
1355 ld_st_data->load = *new_arg_struct;
1356 ld_st_data->store_bb = bb0;
1357 ld_st_data->load_bb = bb1;
848674d0 1358
28c92cbb 1359 htab_traverse (name_copies, create_loads_and_stores_for_name,
cb7f680b 1360 ld_st_data);
1361
5bb62c99 1362 /* Load the calculation from memory (after the join of the threads). */
1363
e06f9c34 1364 if (reduction_list && htab_elements (reduction_list) > 0)
cb7f680b 1365 {
848674d0 1366 htab_traverse (reduction_list, create_stores_for_reduction,
48e1416a 1367 ld_st_data);
75a70cf9 1368 clsn_data.load = make_ssa_name (nvar, NULL);
e06f9c34 1369 clsn_data.load_bb = exit->dest;
cb7f680b 1370 clsn_data.store = ld_st_data->store;
1371 create_final_loads_for_reduction (reduction_list, &clsn_data);
1372 }
28c92cbb 1373 }
1374
1375 htab_delete (decl_copies);
1376 htab_delete (name_copies);
1377}
1378
1379/* Bitmap containing uids of functions created by parallelization. We cannot
1380 allocate it from the default obstack, as it must live across compilation
1381 of several functions; we make it gc allocated instead. */
1382
1383static GTY(()) bitmap parallelized_functions;
1384
1385/* Returns true if FN was created by create_loop_fn. */
1386
479a6d79 1387bool
28c92cbb 1388parallelized_function_p (tree fn)
1389{
1390 if (!parallelized_functions || !DECL_ARTIFICIAL (fn))
1391 return false;
1392
1393 return bitmap_bit_p (parallelized_functions, DECL_UID (fn));
1394}
1395
1396/* Creates and returns an empty function that will receive the body of
1397 a parallelized loop. */
1398
1399static tree
0aecb55e 1400create_loop_fn (location_t loc)
28c92cbb 1401{
1402 char buf[100];
1403 char *tname;
1404 tree decl, type, name, t;
1405 struct function *act_cfun = cfun;
1406 static unsigned loopfn_num;
1407
1408 snprintf (buf, 100, "%s.$loopfn", current_function_name ());
1409 ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
1410 clean_symbol_name (tname);
1411 name = get_identifier (tname);
1412 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1413
0aecb55e 1414 decl = build_decl (loc, FUNCTION_DECL, name, type);
28c92cbb 1415 if (!parallelized_functions)
1416 parallelized_functions = BITMAP_GGC_ALLOC ();
1417 bitmap_set_bit (parallelized_functions, DECL_UID (decl));
1418
1419 TREE_STATIC (decl) = 1;
1420 TREE_USED (decl) = 1;
1421 DECL_ARTIFICIAL (decl) = 1;
1422 DECL_IGNORED_P (decl) = 0;
1423 TREE_PUBLIC (decl) = 0;
1424 DECL_UNINLINABLE (decl) = 1;
1425 DECL_EXTERNAL (decl) = 0;
1426 DECL_CONTEXT (decl) = NULL_TREE;
1427 DECL_INITIAL (decl) = make_node (BLOCK);
1428
0aecb55e 1429 t = build_decl (loc, RESULT_DECL, NULL_TREE, void_type_node);
28c92cbb 1430 DECL_ARTIFICIAL (t) = 1;
1431 DECL_IGNORED_P (t) = 1;
1432 DECL_RESULT (decl) = t;
1433
0aecb55e 1434 t = build_decl (loc, PARM_DECL, get_identifier (".paral_data_param"),
28c92cbb 1435 ptr_type_node);
1436 DECL_ARTIFICIAL (t) = 1;
1437 DECL_ARG_TYPE (t) = ptr_type_node;
1438 DECL_CONTEXT (t) = decl;
1439 TREE_USED (t) = 1;
1440 DECL_ARGUMENTS (decl) = t;
1441
80f2ef47 1442 allocate_struct_function (decl, false);
28c92cbb 1443
1444 /* The call to allocate_struct_function clobbers CFUN, so we need to restore
1445 it. */
c8a152f6 1446 set_cfun (act_cfun);
28c92cbb 1447
1448 return decl;
1449}
1450
28c92cbb 1451/* Moves the exit condition of LOOP to the beginning of its header, and
1452 duplicates the part of the last iteration that gets disabled to the
1453 exit of the loop. NIT is the number of iterations of the loop
1454 (used to initialize the variables in the duplicated part).
48e1416a 1455
f0b5f617 1456 TODO: the common case is that latch of the loop is empty and immediately
28c92cbb 1457 follows the loop exit. In this case, it would be better not to copy the
1458 body of the loop, but only move the entry of the loop directly before the
1459 exit check and increase the number of iterations of the loop by one.
48e1416a 1460 This may need some additional preconditioning in case NIT = ~0.
cb7f680b 1461 REDUCTION_LIST describes the reductions in LOOP. */
28c92cbb 1462
1463static void
cb7f680b 1464transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit)
28c92cbb 1465{
1466 basic_block *bbs, *nbbs, ex_bb, orig_header;
1467 unsigned n;
1468 bool ok;
1469 edge exit = single_dom_exit (loop), hpred;
75a70cf9 1470 tree control, control_name, res, t;
b0fb253a 1471 gimple phi, nphi, cond_stmt, stmt, cond_nit;
75a70cf9 1472 gimple_stmt_iterator gsi;
b0fb253a 1473 tree nit_1;
28c92cbb 1474
1475 split_block_after_labels (loop->header);
1476 orig_header = single_succ (loop->header);
1477 hpred = single_succ_edge (loop->header);
1478
1479 cond_stmt = last_stmt (exit->src);
75a70cf9 1480 control = gimple_cond_lhs (cond_stmt);
1481 gcc_assert (gimple_cond_rhs (cond_stmt) == nit);
28c92cbb 1482
1483 /* Make sure that we have phi nodes on exit for all loop header phis
1484 (create_parallel_loop requires that). */
75a70cf9 1485 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
28c92cbb 1486 {
75a70cf9 1487 phi = gsi_stmt (gsi);
28c92cbb 1488 res = PHI_RESULT (phi);
874117c8 1489 t = copy_ssa_name (res, phi);
28c92cbb 1490 SET_PHI_RESULT (phi, t);
28c92cbb 1491 nphi = create_phi_node (res, orig_header);
60d535d2 1492 add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
28c92cbb 1493
1494 if (res == control)
1495 {
75a70cf9 1496 gimple_cond_set_lhs (cond_stmt, t);
28c92cbb 1497 update_stmt (cond_stmt);
1498 control = t;
1499 }
1500 }
2a556654 1501
28c92cbb 1502 bbs = get_loop_body_in_dom_order (loop);
b0fb253a 1503
89675e8c 1504 for (n = 0; bbs[n] != exit->src; n++)
1505 continue;
28c92cbb 1506 nbbs = XNEWVEC (basic_block, n);
75a70cf9 1507 ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
1508 bbs + 1, n, nbbs);
28c92cbb 1509 gcc_assert (ok);
1510 free (bbs);
1511 ex_bb = nbbs[0];
1512 free (nbbs);
1513
48e1416a 1514 /* Other than reductions, the only gimple reg that should be copied
75a70cf9 1515 out of the loop is the control variable. */
89675e8c 1516 exit = single_dom_exit (loop);
28c92cbb 1517 control_name = NULL_TREE;
75a70cf9 1518 for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); )
28c92cbb 1519 {
75a70cf9 1520 phi = gsi_stmt (gsi);
28c92cbb 1521 res = PHI_RESULT (phi);
1522 if (!is_gimple_reg (res))
75a70cf9 1523 {
1524 gsi_next (&gsi);
1525 continue;
1526 }
28c92cbb 1527
cb7f680b 1528 /* Check if it is a part of reduction. If it is,
48e1416a 1529 keep the phi at the reduction's keep_res field. The
1530 PHI_RESULT of this phi is the resulting value of the reduction
cb7f680b 1531 variable when exiting the loop. */
1532
48e1416a 1533 if (htab_elements (reduction_list) > 0)
cb7f680b 1534 {
1535 struct reduction_info *red;
1536
1537 tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
cb7f680b 1538 red = reduction_phi (reduction_list, SSA_NAME_DEF_STMT (val));
1539 if (red)
75a70cf9 1540 {
1541 red->keep_res = phi;
1542 gsi_next (&gsi);
1543 continue;
1544 }
cb7f680b 1545 }
75a70cf9 1546 gcc_assert (control_name == NULL_TREE
1547 && SSA_NAME_VAR (res) == SSA_NAME_VAR (control));
28c92cbb 1548 control_name = res;
75a70cf9 1549 remove_phi_node (&gsi, false);
28c92cbb 1550 }
1551 gcc_assert (control_name != NULL_TREE);
28c92cbb 1552
48e1416a 1553 /* Initialize the control variable to number of iterations
b0fb253a 1554 according to the rhs of the exit condition. */
75a70cf9 1555 gsi = gsi_after_labels (ex_bb);
48e1416a 1556 cond_nit = last_stmt (exit->src);
b0fb253a 1557 nit_1 = gimple_cond_rhs (cond_nit);
1558 nit_1 = force_gimple_operand_gsi (&gsi,
1559 fold_convert (TREE_TYPE (control_name), nit_1),
75a70cf9 1560 false, NULL_TREE, false, GSI_SAME_STMT);
b0fb253a 1561 stmt = gimple_build_assign (control_name, nit_1);
75a70cf9 1562 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1563 SSA_NAME_DEF_STMT (control_name) = stmt;
28c92cbb 1564}
1565
1566/* Create the parallel constructs for LOOP as described in gen_parallel_loop.
75a70cf9 1567 LOOP_FN and DATA are the arguments of GIMPLE_OMP_PARALLEL.
28c92cbb 1568 NEW_DATA is the variable that should be initialized from the argument
1569 of LOOP_FN. N_THREADS is the requested number of threads. Returns the
75a70cf9 1570 basic block containing GIMPLE_OMP_PARALLEL tree. */
28c92cbb 1571
1572static basic_block
1573create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
0aecb55e 1574 tree new_data, unsigned n_threads, location_t loc)
28c92cbb 1575{
75a70cf9 1576 gimple_stmt_iterator gsi;
28c92cbb 1577 basic_block bb, paral_bb, for_bb, ex_bb;
f018d957 1578 tree t, param;
75a70cf9 1579 gimple stmt, for_stmt, phi, cond_stmt;
1580 tree cvar, cvar_init, initvar, cvar_next, cvar_base, type;
28c92cbb 1581 edge exit, nexit, guard, end, e;
1582
75a70cf9 1583 /* Prepare the GIMPLE_OMP_PARALLEL statement. */
28c92cbb 1584 bb = loop_preheader_edge (loop)->src;
1585 paral_bb = single_pred (bb);
75a70cf9 1586 gsi = gsi_last_bb (paral_bb);
28c92cbb 1587
0aecb55e 1588 t = build_omp_clause (loc, OMP_CLAUSE_NUM_THREADS);
28c92cbb 1589 OMP_CLAUSE_NUM_THREADS_EXPR (t)
cb7f680b 1590 = build_int_cst (integer_type_node, n_threads);
75a70cf9 1591 stmt = gimple_build_omp_parallel (NULL, t, loop_fn, data);
0aecb55e 1592 gimple_set_location (stmt, loc);
28c92cbb 1593
75a70cf9 1594 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1595
1596 /* Initialize NEW_DATA. */
1597 if (data)
1598 {
75a70cf9 1599 gsi = gsi_after_labels (bb);
1600
1601 param = make_ssa_name (DECL_ARGUMENTS (loop_fn), NULL);
1602 stmt = gimple_build_assign (param, build_fold_addr_expr (data));
1603 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1604 SSA_NAME_DEF_STMT (param) = stmt;
1605
1606 stmt = gimple_build_assign (new_data,
1607 fold_convert (TREE_TYPE (new_data), param));
1608 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1609 SSA_NAME_DEF_STMT (new_data) = stmt;
28c92cbb 1610 }
1611
75a70cf9 1612 /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_PARALLEL. */
28c92cbb 1613 bb = split_loop_exit_edge (single_dom_exit (loop));
75a70cf9 1614 gsi = gsi_last_bb (bb);
0aecb55e 1615 stmt = gimple_build_omp_return (false);
1616 gimple_set_location (stmt, loc);
1617 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1618
75a70cf9 1619 /* Extract data for GIMPLE_OMP_FOR. */
28c92cbb 1620 gcc_assert (loop->header == single_dom_exit (loop)->src);
75a70cf9 1621 cond_stmt = last_stmt (loop->header);
28c92cbb 1622
75a70cf9 1623 cvar = gimple_cond_lhs (cond_stmt);
28c92cbb 1624 cvar_base = SSA_NAME_VAR (cvar);
1625 phi = SSA_NAME_DEF_STMT (cvar);
1626 cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
874117c8 1627 initvar = copy_ssa_name (cvar, NULL);
28c92cbb 1628 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, loop_preheader_edge (loop)),
1629 initvar);
1630 cvar_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
1631
4bcf12c5 1632 gsi = gsi_last_nondebug_bb (loop->latch);
75a70cf9 1633 gcc_assert (gsi_stmt (gsi) == SSA_NAME_DEF_STMT (cvar_next));
1634 gsi_remove (&gsi, true);
28c92cbb 1635
1636 /* Prepare cfg. */
1637 for_bb = split_edge (loop_preheader_edge (loop));
1638 ex_bb = split_loop_exit_edge (single_dom_exit (loop));
1639 extract_true_false_edges_from_block (loop->header, &nexit, &exit);
1640 gcc_assert (exit == single_dom_exit (loop));
1641
1642 guard = make_edge (for_bb, ex_bb, 0);
1643 single_succ_edge (loop->latch)->flags = 0;
1644 end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
75a70cf9 1645 for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
28c92cbb 1646 {
efbcb6de 1647 source_location locus;
1648 tree def;
75a70cf9 1649 phi = gsi_stmt (gsi);
75a70cf9 1650 stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
efbcb6de 1651
1652 def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop));
48e1416a 1653 locus = gimple_phi_arg_location_from_edge (stmt,
efbcb6de 1654 loop_preheader_edge (loop));
60d535d2 1655 add_phi_arg (phi, def, guard, locus);
efbcb6de 1656
1657 def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop));
1658 locus = gimple_phi_arg_location_from_edge (stmt, loop_latch_edge (loop));
60d535d2 1659 add_phi_arg (phi, def, end, locus);
28c92cbb 1660 }
1661 e = redirect_edge_and_branch (exit, nexit->dest);
1662 PENDING_STMT (e) = NULL;
1663
75a70cf9 1664 /* Emit GIMPLE_OMP_FOR. */
1665 gimple_cond_set_lhs (cond_stmt, cvar_base);
28c92cbb 1666 type = TREE_TYPE (cvar);
0aecb55e 1667 t = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
28c92cbb 1668 OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
1669
75a70cf9 1670 for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
0aecb55e 1671 gimple_set_location (for_stmt, loc);
75a70cf9 1672 gimple_omp_for_set_index (for_stmt, 0, initvar);
1673 gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
1674 gimple_omp_for_set_final (for_stmt, 0, gimple_cond_rhs (cond_stmt));
1675 gimple_omp_for_set_cond (for_stmt, 0, gimple_cond_code (cond_stmt));
1676 gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
1677 cvar_base,
1678 build_int_cst (type, 1)));
1679
1680 gsi = gsi_last_bb (for_bb);
1681 gsi_insert_after (&gsi, for_stmt, GSI_NEW_STMT);
28c92cbb 1682 SSA_NAME_DEF_STMT (initvar) = for_stmt;
1683
75a70cf9 1684 /* Emit GIMPLE_OMP_CONTINUE. */
1685 gsi = gsi_last_bb (loop->latch);
1686 stmt = gimple_build_omp_continue (cvar_next, cvar);
0aecb55e 1687 gimple_set_location (stmt, loc);
75a70cf9 1688 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1689 SSA_NAME_DEF_STMT (cvar_next) = stmt;
28c92cbb 1690
75a70cf9 1691 /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_FOR. */
1692 gsi = gsi_last_bb (ex_bb);
0aecb55e 1693 stmt = gimple_build_omp_return (true);
1694 gimple_set_location (stmt, loc);
1695 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
28c92cbb 1696
821ac701 1697 /* After the above dom info is hosed. Re-compute it. */
1698 free_dominance_info (CDI_DOMINATORS);
1699 calculate_dominance_info (CDI_DOMINATORS);
1700
28c92cbb 1701 return paral_bb;
1702}
1703
5fa90eea 1704/* Generates code to execute the iterations of LOOP in N_THREADS
1705 threads in parallel.
1706
1707 NITER describes number of iterations of LOOP.
f0b5f617 1708 REDUCTION_LIST describes the reductions existent in the LOOP. */
28c92cbb 1709
1710static void
5fa90eea 1711gen_parallel_loop (struct loop *loop, htab_t reduction_list,
cb7f680b 1712 unsigned n_threads, struct tree_niter_desc *niter)
28c92cbb 1713{
6f22df65 1714 loop_iterator li;
28c92cbb 1715 tree many_iterations_cond, type, nit;
75a70cf9 1716 tree arg_struct, new_arg_struct;
1717 gimple_seq stmts;
28c92cbb 1718 basic_block parallel_head;
e06f9c34 1719 edge entry, exit;
cb7f680b 1720 struct clsn_data clsn_data;
28c92cbb 1721 unsigned prob;
0aecb55e 1722 location_t loc;
1723 gimple cond_stmt;
362dc73c 1724 unsigned int m_p_thread=2;
28c92cbb 1725
1726 /* From
1727
1728 ---------------------------------------------------------------------
1729 loop
1730 {
1731 IV = phi (INIT, IV + STEP)
1732 BODY1;
1733 if (COND)
1734 break;
1735 BODY2;
1736 }
1737 ---------------------------------------------------------------------
1738
1739 with # of iterations NITER (possibly with MAY_BE_ZERO assumption),
1740 we generate the following code:
1741
1742 ---------------------------------------------------------------------
1743
1744 if (MAY_BE_ZERO
cb7f680b 1745 || NITER < MIN_PER_THREAD * N_THREADS)
1746 goto original;
28c92cbb 1747
1748 BODY1;
1749 store all local loop-invariant variables used in body of the loop to DATA.
75a70cf9 1750 GIMPLE_OMP_PARALLEL (OMP_CLAUSE_NUM_THREADS (N_THREADS), LOOPFN, DATA);
28c92cbb 1751 load the variables from DATA.
75a70cf9 1752 GIMPLE_OMP_FOR (IV = INIT; COND; IV += STEP) (OMP_CLAUSE_SCHEDULE (static))
28c92cbb 1753 BODY2;
1754 BODY1;
75a70cf9 1755 GIMPLE_OMP_CONTINUE;
1756 GIMPLE_OMP_RETURN -- GIMPLE_OMP_FOR
1757 GIMPLE_OMP_RETURN -- GIMPLE_OMP_PARALLEL
28c92cbb 1758 goto end;
1759
1760 original:
1761 loop
1762 {
1763 IV = phi (INIT, IV + STEP)
1764 BODY1;
1765 if (COND)
1766 break;
1767 BODY2;
1768 }
1769
1770 end:
1771
1772 */
1773
1774 /* Create two versions of the loop -- in the old one, we know that the
1775 number of iterations is large enough, and we will transform it into the
1776 loop that will be split to loop_fn, the new one will be used for the
1777 remaining iterations. */
cb7f680b 1778
362dc73c 1779 /* We should compute a better number-of-iterations value for outer loops.
1780 That is, if we have
1781
1782 for (i = 0; i < n; ++i)
1783 for (j = 0; j < m; ++j)
1784 ...
1785
1786 we should compute nit = n * m, not nit = n.
1787 Also may_be_zero handling would need to be adjusted. */
1788
28c92cbb 1789 type = TREE_TYPE (niter->niter);
1790 nit = force_gimple_operand (unshare_expr (niter->niter), &stmts, true,
1791 NULL_TREE);
1792 if (stmts)
75a70cf9 1793 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
28c92cbb 1794
362dc73c 1795 if (loop->inner)
1796 m_p_thread=2;
1797 else
1798 m_p_thread=MIN_PER_THREAD;
1799
1800 many_iterations_cond =
1801 fold_build2 (GE_EXPR, boolean_type_node,
1802 nit, build_int_cst (type, m_p_thread * n_threads));
1803
28c92cbb 1804 many_iterations_cond
cb7f680b 1805 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
1806 invert_truthvalue (unshare_expr (niter->may_be_zero)),
1807 many_iterations_cond);
28c92cbb 1808 many_iterations_cond
cb7f680b 1809 = force_gimple_operand (many_iterations_cond, &stmts, false, NULL_TREE);
28c92cbb 1810 if (stmts)
75a70cf9 1811 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
28c92cbb 1812 if (!is_gimple_condexpr (many_iterations_cond))
1813 {
1814 many_iterations_cond
cb7f680b 1815 = force_gimple_operand (many_iterations_cond, &stmts,
1816 true, NULL_TREE);
28c92cbb 1817 if (stmts)
75a70cf9 1818 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
28c92cbb 1819 }
1820
1821 initialize_original_copy_tables ();
1822
1823 /* We assume that the loop usually iterates a lot. */
1824 prob = 4 * REG_BR_PROB_BASE / 5;
f018d957 1825 loop_version (loop, many_iterations_cond, NULL,
1826 prob, prob, REG_BR_PROB_BASE - prob, true);
28c92cbb 1827 update_ssa (TODO_update_ssa);
1828 free_original_copy_tables ();
1829
1830 /* Base all the induction variables in LOOP on a single control one. */
0207206d 1831 canonicalize_loop_ivs (loop, &nit, true);
28c92cbb 1832
1833 /* Ensure that the exit condition is the first statement in the loop. */
cb7f680b 1834 transform_to_exit_first_loop (loop, reduction_list, nit);
1835
f0b5f617 1836 /* Generate initializations for reductions. */
48e1416a 1837 if (htab_elements (reduction_list) > 0)
cb7f680b 1838 htab_traverse (reduction_list, initialize_reductions, loop);
28c92cbb 1839
1840 /* Eliminate the references to local variables from the loop. */
e06f9c34 1841 gcc_assert (single_exit (loop));
1842 entry = loop_preheader_edge (loop);
1843 exit = single_dom_exit (loop);
28c92cbb 1844
e06f9c34 1845 eliminate_local_variables (entry, exit);
28c92cbb 1846 /* In the old loop, move all variables non-local to the loop to a structure
1847 and back, and create separate decls for the variables used in loop. */
48e1416a 1848 separate_decls_in_region (entry, exit, reduction_list, &arg_struct,
e06f9c34 1849 &new_arg_struct, &clsn_data);
28c92cbb 1850
1851 /* Create the parallel constructs. */
0aecb55e 1852 loc = UNKNOWN_LOCATION;
1853 cond_stmt = last_stmt (loop->header);
1854 if (cond_stmt)
1855 loc = gimple_location (cond_stmt);
1856 parallel_head = create_parallel_loop (loop, create_loop_fn (loc), arg_struct,
1857 new_arg_struct, n_threads, loc);
48e1416a 1858 if (htab_elements (reduction_list) > 0)
cb7f680b 1859 create_call_for_reduction (loop, reduction_list, &clsn_data);
28c92cbb 1860
1861 scev_reset ();
1862
1863 /* Cancel the loop (it is simpler to do it here rather than to teach the
1864 expander to do it). */
1865 cancel_loop_tree (loop);
1866
d46d3c1c 1867 /* Free loop bound estimations that could contain references to
1868 removed statements. */
1869 FOR_EACH_LOOP (li, loop, 0)
1870 free_numbers_of_iterations_estimates_loop (loop);
1871
28c92cbb 1872 /* Expand the parallel constructs. We do it directly here instead of running
1873 a separate expand_omp pass, since it is more efficient, and less likely to
1874 cause troubles with further analyses not being able to deal with the
1875 OMP trees. */
cb7f680b 1876
28c92cbb 1877 omp_expand_local (parallel_head);
1878}
1879
c968a07c 1880/* Returns true when LOOP contains vector phi nodes. */
1881
1882static bool
75a70cf9 1883loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED)
c968a07c 1884{
1885 unsigned i;
1886 basic_block *bbs = get_loop_body_in_dom_order (loop);
75a70cf9 1887 gimple_stmt_iterator gsi;
c968a07c 1888 bool res = true;
c968a07c 1889
1890 for (i = 0; i < loop->num_nodes; i++)
75a70cf9 1891 for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
1892 if (TREE_CODE (TREE_TYPE (PHI_RESULT (gsi_stmt (gsi)))) == VECTOR_TYPE)
c968a07c 1893 goto end;
1894
1895 res = false;
1896 end:
1897 free (bbs);
1898 return res;
1899}
1900
5fa90eea 1901/* Create a reduction_info struct, initialize it with REDUC_STMT
1902 and PHI, insert it to the REDUCTION_LIST. */
1903
1904static void
1905build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi)
1906{
1907 PTR *slot;
1908 struct reduction_info *new_reduction;
1909
1910 gcc_assert (reduc_stmt);
48e1416a 1911
5fa90eea 1912 if (dump_file && (dump_flags & TDF_DETAILS))
1913 {
1914 fprintf (dump_file,
1915 "Detected reduction. reduction stmt is: \n");
1916 print_gimple_stmt (dump_file, reduc_stmt, 0, 0);
1917 fprintf (dump_file, "\n");
1918 }
48e1416a 1919
5fa90eea 1920 new_reduction = XCNEW (struct reduction_info);
48e1416a 1921
5fa90eea 1922 new_reduction->reduc_stmt = reduc_stmt;
1923 new_reduction->reduc_phi = phi;
71fa519d 1924 new_reduction->reduc_version = SSA_NAME_VERSION (gimple_phi_result (phi));
5fa90eea 1925 new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt);
1926 slot = htab_find_slot (reduction_list, new_reduction, INSERT);
1927 *slot = new_reduction;
1928}
1929
71fa519d 1930/* Callback for htab_traverse. Sets gimple_uid of reduc_phi stmts. */
1931
1932static int
1933set_reduc_phi_uids (void **slot, void *data ATTRIBUTE_UNUSED)
1934{
1935 struct reduction_info *const red = (struct reduction_info *) *slot;
1936 gimple_set_uid (red->reduc_phi, red->reduc_version);
1937 return 1;
1938}
1939
5fa90eea 1940/* Detect all reductions in the LOOP, insert them into REDUCTION_LIST. */
1941
1942static void
1943gather_scalar_reductions (loop_p loop, htab_t reduction_list)
1944{
1945 gimple_stmt_iterator gsi;
1946 loop_vec_info simple_loop_info;
1947
1948 vect_dump = NULL;
1949 simple_loop_info = vect_analyze_loop_form (loop);
1950
1951 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
1952 {
1953 gimple phi = gsi_stmt (gsi);
1954 affine_iv iv;
1955 tree res = PHI_RESULT (phi);
1956 bool double_reduc;
1957
1958 if (!is_gimple_reg (res))
1959 continue;
1960
1961 if (!simple_iv (loop, loop, res, &iv, true)
1962 && simple_loop_info)
1963 {
f4a50267 1964 gimple reduc_stmt = vect_force_simple_reduction (simple_loop_info,
1965 phi, true,
1966 &double_reduc);
b0fb253a 1967 if (reduc_stmt && !double_reduc)
5fa90eea 1968 build_new_reduction (reduction_list, reduc_stmt, phi);
1969 }
1970 }
71fa519d 1971 destroy_loop_vec_info (simple_loop_info, true);
1972
1973 /* As gimple_uid is used by the vectorizer in between vect_analyze_loop_form
1974 and destroy_loop_vec_info, we can set gimple_uid of reduc_phi stmts
1975 only now. */
1976 htab_traverse (reduction_list, set_reduc_phi_uids, NULL);
5fa90eea 1977}
1978
1979/* Try to initialize NITER for code generation part. */
1980
1981static bool
1982try_get_loop_niter (loop_p loop, struct tree_niter_desc *niter)
1983{
1984 edge exit = single_dom_exit (loop);
1985
1986 gcc_assert (exit);
1987
1988 /* We need to know # of iterations, and there should be no uses of values
1989 defined inside loop outside of it, unless the values are invariants of
1990 the loop. */
1991 if (!number_of_iterations_exit (loop, exit, niter, false))
1992 {
1993 if (dump_file && (dump_flags & TDF_DETAILS))
1994 fprintf (dump_file, " FAILED: number of iterations not known\n");
1995 return false;
1996 }
1997
1998 return true;
1999}
2000
2001/* Try to initialize REDUCTION_LIST for code generation part.
2002 REDUCTION_LIST describes the reductions. */
2003
2004static bool
2005try_create_reduction_list (loop_p loop, htab_t reduction_list)
2006{
2007 edge exit = single_dom_exit (loop);
2008 gimple_stmt_iterator gsi;
2009
2010 gcc_assert (exit);
2011
2012 gather_scalar_reductions (loop, reduction_list);
2013
48e1416a 2014
5fa90eea 2015 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
2016 {
2017 gimple phi = gsi_stmt (gsi);
2018 struct reduction_info *red;
2019 imm_use_iterator imm_iter;
2020 use_operand_p use_p;
2021 gimple reduc_phi;
2022 tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
2023
2024 if (is_gimple_reg (val))
2025 {
2026 if (dump_file && (dump_flags & TDF_DETAILS))
2027 {
2028 fprintf (dump_file, "phi is ");
2029 print_gimple_stmt (dump_file, phi, 0, 0);
2030 fprintf (dump_file, "arg of phi to exit: value ");
2031 print_generic_expr (dump_file, val, 0);
2032 fprintf (dump_file, " used outside loop\n");
2033 fprintf (dump_file,
2034 " checking if it a part of reduction pattern: \n");
2035 }
2036 if (htab_elements (reduction_list) == 0)
2037 {
2038 if (dump_file && (dump_flags & TDF_DETAILS))
2039 fprintf (dump_file,
2040 " FAILED: it is not a part of reduction.\n");
2041 return false;
2042 }
2043 reduc_phi = NULL;
2044 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, val)
2045 {
43989e16 2046 if (!gimple_debug_bind_p (USE_STMT (use_p))
2047 && flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
5fa90eea 2048 {
2049 reduc_phi = USE_STMT (use_p);
2050 break;
2051 }
2052 }
2053 red = reduction_phi (reduction_list, reduc_phi);
2054 if (red == NULL)
2055 {
2056 if (dump_file && (dump_flags & TDF_DETAILS))
2057 fprintf (dump_file,
2058 " FAILED: it is not a part of reduction.\n");
2059 return false;
2060 }
2061 if (dump_file && (dump_flags & TDF_DETAILS))
2062 {
2063 fprintf (dump_file, "reduction phi is ");
2064 print_gimple_stmt (dump_file, red->reduc_phi, 0, 0);
2065 fprintf (dump_file, "reduction stmt is ");
2066 print_gimple_stmt (dump_file, red->reduc_stmt, 0, 0);
2067 }
2068 }
2069 }
2070
2071 /* The iterations of the loop may communicate only through bivs whose
2072 iteration space can be distributed efficiently. */
2073 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
2074 {
2075 gimple phi = gsi_stmt (gsi);
2076 tree def = PHI_RESULT (phi);
2077 affine_iv iv;
2078
2079 if (is_gimple_reg (def) && !simple_iv (loop, loop, def, &iv, true))
2080 {
2081 struct reduction_info *red;
2082
2083 red = reduction_phi (reduction_list, phi);
2084 if (red == NULL)
2085 {
2086 if (dump_file && (dump_flags & TDF_DETAILS))
2087 fprintf (dump_file,
2088 " FAILED: scalar dependency between iterations\n");
2089 return false;
2090 }
2091 }
2092 }
2093
2094
2095 return true;
2096}
2097
28c92cbb 2098/* Detect parallel loops and generate parallel code using libgomp
2099 primitives. Returns true if some loop was parallelized, false
2100 otherwise. */
2101
2102bool
2103parallelize_loops (void)
2104{
2105 unsigned n_threads = flag_tree_parallelize_loops;
2106 bool changed = false;
2107 struct loop *loop;
2108 struct tree_niter_desc niter_desc;
2109 loop_iterator li;
cb7f680b 2110 htab_t reduction_list;
1e33ad50 2111 struct obstack parloop_obstack;
fbbe5b51 2112 HOST_WIDE_INT estimated;
2113 LOC loop_loc;
1e33ad50 2114
28c92cbb 2115 /* Do not parallelize loops in the functions created by parallelization. */
2116 if (parallelized_function_p (cfun->decl))
2117 return false;
fbbe5b51 2118 if (cfun->has_nonlocal_label)
2119 return false;
28c92cbb 2120
1e33ad50 2121 gcc_obstack_init (&parloop_obstack);
cb7f680b 2122 reduction_list = htab_create (10, reduction_info_hash,
5fa90eea 2123 reduction_info_eq, free);
75a70cf9 2124 init_stmt_vec_info_vec ();
cb7f680b 2125
28c92cbb 2126 FOR_EACH_LOOP (li, loop, 0)
2127 {
cb7f680b 2128 htab_empty (reduction_list);
b0fb253a 2129 if (dump_file && (dump_flags & TDF_DETAILS))
2130 {
2131 fprintf (dump_file, "Trying loop %d as candidate\n",loop->num);
2132 if (loop->inner)
2133 fprintf (dump_file, "loop %d is not innermost\n",loop->num);
2134 else
2135 fprintf (dump_file, "loop %d is innermost\n",loop->num);
2136 }
48e1416a 2137
b0fb253a 2138 /* If we use autopar in graphite pass, we use its marked dependency
525c22c4 2139 checking results. */
2140 if (flag_loop_parallelize_all && !loop->can_be_parallel)
b0fb253a 2141 {
2142 if (dump_file && (dump_flags & TDF_DETAILS))
2143 fprintf (dump_file, "loop is not parallel according to graphite\n");
525c22c4 2144 continue;
b0fb253a 2145 }
525c22c4 2146
b0fb253a 2147 if (!single_dom_exit (loop))
2148 {
48e1416a 2149
b0fb253a 2150 if (dump_file && (dump_flags & TDF_DETAILS))
2151 fprintf (dump_file, "loop is !single_dom_exit\n");
48e1416a 2152
5fa90eea 2153 continue;
b0fb253a 2154 }
5fa90eea 2155
2156 if (/* And of course, the loop must be parallelizable. */
2157 !can_duplicate_loop_p (loop)
d4fcfd16 2158 || loop_has_blocks_with_irreducible_flag (loop)
fbbe5b51 2159 || (loop_preheader_edge (loop)->src->flags & BB_IRREDUCIBLE_LOOP)
c968a07c 2160 /* FIXME: the check for vector phi nodes could be removed. */
89675e8c 2161 || loop_has_vector_phi_nodes (loop))
5fa90eea 2162 continue;
b0b097b4 2163
fee017b3 2164 estimated = estimated_stmt_executions_int (loop);
b0b097b4 2165 if (estimated == -1)
2166 estimated = max_stmt_executions_int (loop);
525c22c4 2167 /* FIXME: Bypass this check as graphite doesn't update the
b0b097b4 2168 count and frequency correctly now. */
525c22c4 2169 if (!flag_loop_parallelize_all
b0b097b4 2170 && ((estimated != -1
2171 && estimated <= (HOST_WIDE_INT) n_threads * MIN_PER_THREAD)
525c22c4 2172 /* Do not bother with loops in cold areas. */
2173 || optimize_loop_nest_for_size_p (loop)))
5fa90eea 2174 continue;
48e1416a 2175
5fa90eea 2176 if (!try_get_loop_niter (loop, &niter_desc))
2177 continue;
2178
2179 if (!try_create_reduction_list (loop, reduction_list))
2180 continue;
2181
1e33ad50 2182 if (!flag_loop_parallelize_all
2183 && !loop_parallel_p (loop, &parloop_obstack))
28c92cbb 2184 continue;
2185
2186 changed = true;
b0fb253a 2187 if (dump_file && (dump_flags & TDF_DETAILS))
2188 {
b0fb253a 2189 if (loop->inner)
fbbe5b51 2190 fprintf (dump_file, "parallelizing outer loop %d\n",loop->header->index);
b0fb253a 2191 else
fbbe5b51 2192 fprintf (dump_file, "parallelizing inner loop %d\n",loop->header->index);
2193 loop_loc = find_loop_location (loop);
2194 if (loop_loc != UNKNOWN_LOC)
2195 fprintf (dump_file, "\nloop at %s:%d: ",
2196 LOC_FILE (loop_loc), LOC_LINE (loop_loc));
48e1416a 2197 }
2198 gen_parallel_loop (loop, reduction_list,
5fa90eea 2199 n_threads, &niter_desc);
ef0e6535 2200#ifdef ENABLE_CHECKING
28c92cbb 2201 verify_flow_info ();
28c92cbb 2202 verify_loop_structure ();
ca77c6ec 2203 verify_loop_closed_ssa (true);
ef0e6535 2204#endif
28c92cbb 2205 }
2206
75a70cf9 2207 free_stmt_vec_info_vec ();
cb7f680b 2208 htab_delete (reduction_list);
1e33ad50 2209 obstack_free (&parloop_obstack, NULL);
7f81b5ee 2210
2211 /* Parallelization will cause new function calls to be inserted through
cb245216 2212 which local variables will escape. Reset the points-to solution
2213 for ESCAPED. */
7f81b5ee 2214 if (changed)
cb245216 2215 pt_solution_reset (&cfun->gimple_df->escaped);
7f81b5ee 2216
28c92cbb 2217 return changed;
2218}
2219
2220#include "gt-tree-parloops.h"