blob: fb4d1df7cdb4713e150df4d042aff31d1509cf20 [file] [log] [blame]
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001/* Loop autoparallelization.
Nick Clifton6da7fc82009-02-10 17:59:08 +00002 Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02003 Contributed by Sebastian Pop <pop@cri.ensmp.fr> and
4 Zdenek Dvorak <dvorakz@suse.cz>.
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
Nick Clifton6da7fc82009-02-10 17:59:08 +000010Software Foundation; either version 3, or (at your option) any later
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +020011version.
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
Nick Clifton6da7fc82009-02-10 17:59:08 +000019along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +020021
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "tree.h"
27#include "rtl.h"
28#include "tree-flow.h"
29#include "cfgloop.h"
30#include "ggc.h"
31#include "tree-data-ref.h"
32#include "diagnostic.h"
33#include "tree-pass.h"
34#include "tree-scalar-evolution.h"
35#include "hashtab.h"
36#include "langhooks.h"
Razya Ladelskya509ebb2007-10-29 11:05:04 +000037#include "tree-vectorizer.h"
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +020038
39/* This pass tries to distribute iterations of loops into several threads.
40 The implementation is straightforward -- for each loop we test whether its
41 iterations are independent, and if it is the case (and some additional
42 conditions regarding profitability and correctness are satisfied), we
Richard Biener726a9892008-07-28 14:33:56 +000043 add GIMPLE_OMP_PARALLEL and GIMPLE_OMP_FOR codes and let omp expansion
44 machinery do its job.
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +020045
46 The most of the complexity is in bringing the code into shape expected
47 by the omp expanders:
Richard Biener726a9892008-07-28 14:33:56 +000048 -- for GIMPLE_OMP_FOR, ensuring that the loop has only one induction
49 variable and that the exit test is at the start of the loop body
50 -- for GIMPLE_OMP_PARALLEL, replacing the references to local addressable
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +020051 variables by accesses through pointers, and breaking up ssa chains
52 by storing the values incoming to the parallelized loop to a structure
53 passed to the new function as an argument (something similar is done
54 in omp gimplification, unfortunately only a small part of the code
55 can be shared).
56
57 TODO:
58 -- if there are several parallelizable loops in a function, it may be
59 possible to generate the threads just once (using synchronization to
60 ensure that cross-loop dependences are obeyed).
61 -- handling of common scalar dependence patterns (accumulation, ...)
62 -- handling of non-innermost loops */
63
Razya Ladelskya509ebb2007-10-29 11:05:04 +000064/*
65 Reduction handling:
66 currently we use vect_is_simple_reduction() to detect reduction patterns.
67 The code transformation will be introduced by an example.
68
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +000069
Razya Ladelskya509ebb2007-10-29 11:05:04 +000070parloop
71{
72 int sum=1;
73
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +000074 for (i = 0; i < N; i++)
Razya Ladelskya509ebb2007-10-29 11:05:04 +000075 {
76 x[i] = i + 3;
77 sum+=x[i];
78 }
79}
80
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +000081gimple-like code:
Razya Ladelskya509ebb2007-10-29 11:05:04 +000082header_bb:
83
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +000084 # sum_29 = PHI <sum_11(5), 1(3)>
85 # i_28 = PHI <i_12(5), 0(3)>
86 D.1795_8 = i_28 + 3;
87 x[i_28] = D.1795_8;
88 sum_11 = D.1795_8 + sum_29;
89 i_12 = i_28 + 1;
90 if (N_6(D) > i_12)
91 goto header_bb;
92
Razya Ladelskya509ebb2007-10-29 11:05:04 +000093
94exit_bb:
95
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +000096 # sum_21 = PHI <sum_11(4)>
97 printf (&"%d"[0], sum_21);
Razya Ladelskya509ebb2007-10-29 11:05:04 +000098
99
100after reduction transformation (only relevant parts):
101
102parloop
103{
104
105....
106
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000107
Ralf Wildenhuesfa10bee2008-06-06 05:42:00 +0000108 # Storing the initial value given by the user. #
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000109
Razya Ladelskyae0bce62007-12-18 11:21:48 +0000110 .paral_data_store.32.sum.27 = 1;
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000111
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000112 #pragma omp parallel num_threads(4)
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000113
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000114 #pragma omp for schedule(static)
Razya Ladelskyae0bce62007-12-18 11:21:48 +0000115
116 # The neutral element corresponding to the particular
117 reduction's operation, e.g. 0 for PLUS_EXPR,
118 1 for MULT_EXPR, etc. replaces the user's initial value. #
119
120 # sum.27_29 = PHI <sum.27_11, 0>
121
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000122 sum.27_11 = D.1827_8 + sum.27_29;
Razya Ladelskyae0bce62007-12-18 11:21:48 +0000123
Richard Biener726a9892008-07-28 14:33:56 +0000124 GIMPLE_OMP_CONTINUE
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000125
126 # Adding this reduction phi is done at create_phi_for_local_result() #
127 # sum.27_56 = PHI <sum.27_11, 0>
Richard Biener726a9892008-07-28 14:33:56 +0000128 GIMPLE_OMP_RETURN
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000129
130 # Creating the atomic operation is done at
131 create_call_for_reduction_1() #
132
133 #pragma omp atomic_load
134 D.1839_59 = *&.paral_data_load.33_51->reduction.23;
135 D.1840_60 = sum.27_56 + D.1839_59;
136 #pragma omp atomic_store (D.1840_60);
137
Richard Biener726a9892008-07-28 14:33:56 +0000138 GIMPLE_OMP_RETURN
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000139
140 # collecting the result after the join of the threads is done at
141 create_loads_for_reductions().
Razya Ladelskyae0bce62007-12-18 11:21:48 +0000142 The value computed by the threads is loaded from the
143 shared struct. #
144
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000145
146 .paral_data_load.33_52 = &.paral_data_store.32;
Razya Ladelskyae0bce62007-12-18 11:21:48 +0000147 sum_37 = .paral_data_load.33_52->sum.27;
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000148 sum_43 = D.1795_41 + sum_37;
149
150 exit bb:
151 # sum_21 = PHI <sum_43, sum_26>
152 printf (&"%d"[0], sum_21);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000153
154...
155
156}
157
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000158*/
159
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200160/* Minimal number of iterations of a loop that should be executed in each
161 thread. */
162#define MIN_PER_THREAD 100
163
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000164/* Element of the hashtable, representing a
165 reduction in the current loop. */
166struct reduction_info
167{
Richard Biener726a9892008-07-28 14:33:56 +0000168 gimple reduc_stmt; /* reduction statement. */
169 gimple reduc_phi; /* The phi node defining the reduction. */
170 enum tree_code reduction_code;/* code for the reduction operation. */
171 gimple keep_res; /* The PHI_RESULT of this phi is the resulting value
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000172 of the reduction variable when existing the loop. */
Razya Ladelskyae0bce62007-12-18 11:21:48 +0000173 tree initial_value; /* The initial value of the reduction var before entering the loop. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000174 tree field; /* the name of the field in the parloop data structure intended for reduction. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000175 tree init; /* reduction initialization value. */
Richard Biener726a9892008-07-28 14:33:56 +0000176 gimple new_phi; /* (helper field) Newly created phi node whose result
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000177 will be passed to the atomic operation. Represents
178 the local result each thread computed for the reduction
179 operation. */
180};
181
182/* Equality and hash functions for hashtab code. */
183
184static int
185reduction_info_eq (const void *aa, const void *bb)
186{
187 const struct reduction_info *a = (const struct reduction_info *) aa;
188 const struct reduction_info *b = (const struct reduction_info *) bb;
189
190 return (a->reduc_phi == b->reduc_phi);
191}
192
193static hashval_t
194reduction_info_hash (const void *aa)
195{
196 const struct reduction_info *a = (const struct reduction_info *) aa;
197
198 return htab_hash_pointer (a->reduc_phi);
199}
200
201static struct reduction_info *
Richard Biener726a9892008-07-28 14:33:56 +0000202reduction_phi (htab_t reduction_list, gimple phi)
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000203{
204 struct reduction_info tmpred, *red;
205
206 if (htab_elements (reduction_list) == 0)
207 return NULL;
208
209 tmpred.reduc_phi = phi;
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +0000210 red = (struct reduction_info *) htab_find (reduction_list, &tmpred);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000211
212 return red;
213}
214
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200215/* Element of hashtable of names to copy. */
216
217struct name_to_copy_elt
218{
219 unsigned version; /* The version of the name to copy. */
220 tree new_name; /* The new name used in the copy. */
221 tree field; /* The field of the structure used to pass the
222 value. */
223};
224
225/* Equality and hash functions for hashtab code. */
226
227static int
228name_to_copy_elt_eq (const void *aa, const void *bb)
229{
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000230 const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
231 const struct name_to_copy_elt *b = (const struct name_to_copy_elt *) bb;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200232
233 return a->version == b->version;
234}
235
236static hashval_t
237name_to_copy_elt_hash (const void *aa)
238{
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000239 const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200240
241 return (hashval_t) a->version;
242}
243
244/* Returns true if the iterations of LOOP are independent on each other (that
245 is, if we can execute them in parallel), and if LOOP satisfies other
246 conditions that we need to be able to parallelize it. Description of number
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000247 of iterations is stored to NITER. Reduction analysis is done, if
248 reductions are found, they are inserted to the REDUCTION_LIST. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200249
250static bool
Richard Biener726a9892008-07-28 14:33:56 +0000251loop_parallel_p (struct loop *loop, htab_t reduction_list,
252 struct tree_niter_desc *niter)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200253{
254 edge exit = single_dom_exit (loop);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000255 VEC (ddr_p, heap) * dependence_relations;
Richard Biener726a9892008-07-28 14:33:56 +0000256 VEC (data_reference_p, heap) *datarefs;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200257 lambda_trans_matrix trans;
258 bool ret = false;
Richard Biener726a9892008-07-28 14:33:56 +0000259 gimple_stmt_iterator gsi;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000260 loop_vec_info simple_loop_info;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200261
262 /* Only consider innermost loops with just one exit. The innermost-loop
263 restriction is not necessary, but it makes things simpler. */
264 if (loop->inner || !exit)
265 return false;
266
267 if (dump_file && (dump_flags & TDF_DETAILS))
268 fprintf (dump_file, "\nConsidering loop %d\n", loop->num);
269
270 /* We need to know # of iterations, and there should be no uses of values
271 defined inside loop outside of it, unless the values are invariants of
272 the loop. */
273 if (!number_of_iterations_exit (loop, exit, niter, false))
274 {
275 if (dump_file && (dump_flags & TDF_DETAILS))
276 fprintf (dump_file, " FAILED: number of iterations not known\n");
277 return false;
278 }
279
Razya Ladelskyc0399c42008-11-19 16:08:01 +0000280 vect_dump = NULL;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000281 simple_loop_info = vect_analyze_loop_form (loop);
282
Richard Biener726a9892008-07-28 14:33:56 +0000283 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000284 {
Richard Biener726a9892008-07-28 14:33:56 +0000285 gimple phi = gsi_stmt (gsi);
286 gimple reduc_stmt = NULL;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000287
288 /* ??? TODO: Change this into a generic function that
289 recognizes reductions. */
290 if (!is_gimple_reg (PHI_RESULT (phi)))
291 continue;
292 if (simple_loop_info)
293 reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi);
294
295 /* Create a reduction_info struct, initialize it and insert it to
296 the reduction list. */
297
298 if (reduc_stmt)
299 {
300 PTR *slot;
301 struct reduction_info *new_reduction;
302
303 if (dump_file && (dump_flags & TDF_DETAILS))
304 {
305 fprintf (dump_file,
306 "Detected reduction. reduction stmt is: \n");
Richard Biener726a9892008-07-28 14:33:56 +0000307 print_gimple_stmt (dump_file, reduc_stmt, 0, 0);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000308 fprintf (dump_file, "\n");
309 }
310
311 new_reduction = XCNEW (struct reduction_info);
312
313 new_reduction->reduc_stmt = reduc_stmt;
314 new_reduction->reduc_phi = phi;
Richard Biener726a9892008-07-28 14:33:56 +0000315 new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000316 slot = htab_find_slot (reduction_list, new_reduction, INSERT);
317 *slot = new_reduction;
318 }
319 }
320
Zdenek Dvorak72425602008-03-27 11:25:36 +0100321 /* Get rid of the information created by the vectorizer functions. */
322 destroy_loop_vec_info (simple_loop_info, true);
323
Richard Biener726a9892008-07-28 14:33:56 +0000324 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200325 {
Richard Biener726a9892008-07-28 14:33:56 +0000326 gimple phi = gsi_stmt (gsi);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000327 struct reduction_info *red;
328 imm_use_iterator imm_iter;
329 use_operand_p use_p;
Richard Biener726a9892008-07-28 14:33:56 +0000330 gimple reduc_phi;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200331 tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
332
333 if (is_gimple_reg (val))
334 {
335 if (dump_file && (dump_flags & TDF_DETAILS))
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000336 {
337 fprintf (dump_file, "phi is ");
Richard Biener726a9892008-07-28 14:33:56 +0000338 print_gimple_stmt (dump_file, phi, 0, 0);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000339 fprintf (dump_file, "arg of phi to exit: value ");
340 print_generic_expr (dump_file, val, 0);
341 fprintf (dump_file, " used outside loop\n");
342 fprintf (dump_file,
343 " checking if it a part of reduction pattern: \n");
344 }
345 if (htab_elements (reduction_list) == 0)
346 {
347 if (dump_file && (dump_flags & TDF_DETAILS))
348 fprintf (dump_file,
349 " FAILED: it is not a part of reduction.\n");
350 return false;
351 }
352 reduc_phi = NULL;
353 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, val)
354 {
Richard Biener726a9892008-07-28 14:33:56 +0000355 if (flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000356 {
357 reduc_phi = USE_STMT (use_p);
358 break;
359 }
360 }
361 red = reduction_phi (reduction_list, reduc_phi);
362 if (red == NULL)
363 {
364 if (dump_file && (dump_flags & TDF_DETAILS))
365 fprintf (dump_file,
366 " FAILED: it is not a part of reduction.\n");
367 return false;
368 }
369 if (dump_file && (dump_flags & TDF_DETAILS))
370 {
371 fprintf (dump_file, "reduction phi is ");
Richard Biener726a9892008-07-28 14:33:56 +0000372 print_gimple_stmt (dump_file, red->reduc_phi, 0, 0);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000373 fprintf (dump_file, "reduction stmt is ");
Richard Biener726a9892008-07-28 14:33:56 +0000374 print_gimple_stmt (dump_file, red->reduc_stmt, 0, 0);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000375 }
376
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200377 }
378 }
379
380 /* The iterations of the loop may communicate only through bivs whose
381 iteration space can be distributed efficiently. */
Richard Biener726a9892008-07-28 14:33:56 +0000382 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200383 {
Richard Biener726a9892008-07-28 14:33:56 +0000384 gimple phi = gsi_stmt (gsi);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200385 tree def = PHI_RESULT (phi);
386 affine_iv iv;
387
Zdenek Dvorakf017bf52009-03-04 18:50:20 +0100388 if (is_gimple_reg (def) && !simple_iv (loop, loop, def, &iv, true))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200389 {
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000390 struct reduction_info *red;
391
392 red = reduction_phi (reduction_list, phi);
393 if (red == NULL)
394 {
395 if (dump_file && (dump_flags & TDF_DETAILS))
396 fprintf (dump_file,
397 " FAILED: scalar dependency between iterations\n");
398 return false;
399 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200400 }
401 }
402
403 /* We need to version the loop to verify assumptions in runtime. */
404 if (!can_duplicate_loop_p (loop))
405 {
406 if (dump_file && (dump_flags & TDF_DETAILS))
407 fprintf (dump_file, " FAILED: cannot be duplicated\n");
408 return false;
409 }
410
411 /* Check for problems with dependences. If the loop can be reversed,
412 the iterations are independent. */
413 datarefs = VEC_alloc (data_reference_p, heap, 10);
414 dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
415 compute_data_dependences_for_loop (loop, true, &datarefs,
416 &dependence_relations);
417 if (dump_file && (dump_flags & TDF_DETAILS))
418 dump_data_dependence_relations (dump_file, dependence_relations);
419
420 trans = lambda_trans_matrix_new (1, 1);
421 LTM_MATRIX (trans)[0][0] = -1;
422
423 if (lambda_transform_legal_p (trans, 1, dependence_relations))
424 {
425 ret = true;
426 if (dump_file && (dump_flags & TDF_DETAILS))
427 fprintf (dump_file, " SUCCESS: may be parallelized\n");
428 }
429 else if (dump_file && (dump_flags & TDF_DETAILS))
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000430 fprintf (dump_file,
431 " FAILED: data dependencies exist across iterations\n");
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200432
433 free_dependence_relations (dependence_relations);
434 free_data_refs (datarefs);
435
436 return ret;
437}
438
Sebastian Pop1d4af1e2008-01-16 02:44:04 +0000439/* Return true when LOOP contains basic blocks marked with the
440 BB_IRREDUCIBLE_LOOP flag. */
441
442static inline bool
443loop_has_blocks_with_irreducible_flag (struct loop *loop)
444{
445 unsigned i;
446 basic_block *bbs = get_loop_body_in_dom_order (loop);
447 bool res = true;
448
449 for (i = 0; i < loop->num_nodes; i++)
450 if (bbs[i]->flags & BB_IRREDUCIBLE_LOOP)
451 goto end;
452
453 res = false;
454 end:
455 free (bbs);
456 return res;
457}
458
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100459/* Assigns the address of OBJ in TYPE to an ssa name, and returns this name.
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100460 The assignment statement is placed on edge ENTRY. DECL_ADDRESS maps decls
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100461 to their addresses that can be reused. The address of OBJ is known to
462 be invariant in the whole function. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200463
464static tree
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100465take_address_of (tree obj, tree type, edge entry, htab_t decl_address)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200466{
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100467 int uid;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200468 void **dslot;
469 struct int_tree_map ielt, *nielt;
Richard Biener726a9892008-07-28 14:33:56 +0000470 tree *var_p, name, bvar, addr;
471 gimple stmt;
472 gimple_seq stmts;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200473
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100474 /* Since the address of OBJ is invariant, the trees may be shared.
475 Avoid rewriting unrelated parts of the code. */
476 obj = unshare_expr (obj);
477 for (var_p = &obj;
478 handled_component_p (*var_p);
479 var_p = &TREE_OPERAND (*var_p, 0))
480 continue;
481 uid = DECL_UID (*var_p);
482
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200483 ielt.uid = uid;
484 dslot = htab_find_slot_with_hash (decl_address, &ielt, uid, INSERT);
485 if (!*dslot)
486 {
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100487 addr = build_addr (*var_p, current_function_decl);
488 bvar = create_tmp_var (TREE_TYPE (addr), get_name (*var_p));
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200489 add_referenced_var (bvar);
Richard Biener726a9892008-07-28 14:33:56 +0000490 stmt = gimple_build_assign (bvar, addr);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200491 name = make_ssa_name (bvar, stmt);
Richard Biener726a9892008-07-28 14:33:56 +0000492 gimple_assign_set_lhs (stmt, name);
493 gsi_insert_on_edge_immediate (entry, stmt);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200494
495 nielt = XNEW (struct int_tree_map);
496 nielt->uid = uid;
497 nielt->to = name;
498 *dslot = nielt;
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100499 }
500 else
501 name = ((struct int_tree_map *) *dslot)->to;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200502
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100503 if (var_p != &obj)
504 {
505 *var_p = build1 (INDIRECT_REF, TREE_TYPE (*var_p), name);
506 name = force_gimple_operand (build_addr (obj, current_function_decl),
Richard Biener726a9892008-07-28 14:33:56 +0000507 &stmts, true, NULL_TREE);
508 if (!gimple_seq_empty_p (stmts))
509 gsi_insert_seq_on_edge_immediate (entry, stmts);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200510 }
511
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100512 if (TREE_TYPE (name) != type)
513 {
Richard Biener726a9892008-07-28 14:33:56 +0000514 name = force_gimple_operand (fold_convert (type, name), &stmts, true,
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100515 NULL_TREE);
Richard Biener726a9892008-07-28 14:33:56 +0000516 if (!gimple_seq_empty_p (stmts))
517 gsi_insert_seq_on_edge_immediate (entry, stmts);
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100518 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200519
520 return name;
521}
522
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000523/* Callback for htab_traverse. Create the initialization statement
524 for reduction described in SLOT, and place it at the preheader of
525 the loop described in DATA. */
526
527static int
528initialize_reductions (void **slot, void *data)
529{
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000530 tree init, c;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000531 tree bvar, type, arg;
532 edge e;
533
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +0000534 struct reduction_info *const reduc = (struct reduction_info *) *slot;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000535 struct loop *loop = (struct loop *) data;
536
537 /* Create initialization in preheader:
538 reduction_variable = initialization value of reduction. */
539
540 /* In the phi node at the header, replace the argument coming
541 from the preheader with the reduction initialization value. */
542
543 /* Create a new variable to initialize the reduction. */
544 type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
545 bvar = create_tmp_var (type, "reduction");
546 add_referenced_var (bvar);
547
Aldy Hernandezc2255bc2009-06-12 22:06:47 +0000548 c = build_omp_clause (gimple_location (reduc->reduc_stmt),
549 OMP_CLAUSE_REDUCTION);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000550 OMP_CLAUSE_REDUCTION_CODE (c) = reduc->reduction_code;
Richard Biener726a9892008-07-28 14:33:56 +0000551 OMP_CLAUSE_DECL (c) = SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt));
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000552
553 init = omp_reduction_init (c, TREE_TYPE (bvar));
554 reduc->init = init;
555
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000556 /* Replace the argument representing the initialization value
557 with the initialization value for the reduction (neutral
558 element for the particular operation, e.g. 0 for PLUS_EXPR,
559 1 for MULT_EXPR, etc).
560 Keep the old value in a new variable "reduction_initial",
561 that will be taken in consideration after the parallel
562 computing is done. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000563
564 e = loop_preheader_edge (loop);
565 arg = PHI_ARG_DEF_FROM_EDGE (reduc->reduc_phi, e);
566 /* Create new variable to hold the initial value. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000567
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000568 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000569 (reduc->reduc_phi, loop_preheader_edge (loop)), init);
Razya Ladelskyae0bce62007-12-18 11:21:48 +0000570 reduc->initial_value = arg;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000571 return 1;
572}
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200573
574struct elv_data
575{
Richard Biener726a9892008-07-28 14:33:56 +0000576 struct walk_stmt_info info;
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100577 edge entry;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200578 htab_t decl_address;
579 bool changed;
580};
581
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100582/* Eliminates references to local variables in *TP out of the single
583 entry single exit region starting at DTA->ENTRY.
584 DECL_ADDRESS contains addresses of the references that had their
585 address taken already. If the expression is changed, CHANGED is
586 set to true. Callback for walk_tree. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000587
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200588static tree
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100589eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200590{
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +0000591 struct elv_data *const dta = (struct elv_data *) data;
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100592 tree t = *tp, var, addr, addr_type, type, obj;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200593
594 if (DECL_P (t))
595 {
596 *walk_subtrees = 0;
597
598 if (!SSA_VAR_P (t) || DECL_EXTERNAL (t))
599 return NULL_TREE;
600
601 type = TREE_TYPE (t);
602 addr_type = build_pointer_type (type);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100603 addr = take_address_of (t, addr_type, dta->entry, dta->decl_address);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200604 *tp = build1 (INDIRECT_REF, TREE_TYPE (*tp), addr);
605
606 dta->changed = true;
607 return NULL_TREE;
608 }
609
610 if (TREE_CODE (t) == ADDR_EXPR)
611 {
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100612 /* ADDR_EXPR may appear in two contexts:
613 -- as a gimple operand, when the address taken is a function invariant
614 -- as gimple rhs, when the resulting address in not a function
615 invariant
616 We do not need to do anything special in the latter case (the base of
617 the memory reference whose address is taken may be replaced in the
618 DECL_P case). The former case is more complicated, as we need to
619 ensure that the new address is still a gimple operand. Thus, it
620 is not sufficient to replace just the base of the memory reference --
621 we need to move the whole computation of the address out of the
622 loop. */
623 if (!is_gimple_val (t))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200624 return NULL_TREE;
625
626 *walk_subtrees = 0;
Zdenek Dvorak8a171a52007-12-19 16:01:19 +0100627 obj = TREE_OPERAND (t, 0);
628 var = get_base_address (obj);
629 if (!var || !SSA_VAR_P (var) || DECL_EXTERNAL (var))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200630 return NULL_TREE;
631
632 addr_type = TREE_TYPE (t);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100633 addr = take_address_of (obj, addr_type, dta->entry, dta->decl_address);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200634 *tp = addr;
635
636 dta->changed = true;
637 return NULL_TREE;
638 }
639
Richard Biener726a9892008-07-28 14:33:56 +0000640 if (!EXPR_P (t))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200641 *walk_subtrees = 0;
642
643 return NULL_TREE;
644}
645
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100646/* Moves the references to local variables in STMT out of the single
647 entry single exit region starting at ENTRY. DECL_ADDRESS contains
648 addresses of the references that had their address taken
649 already. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200650
651static void
Richard Biener726a9892008-07-28 14:33:56 +0000652eliminate_local_variables_stmt (edge entry, gimple stmt,
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200653 htab_t decl_address)
654{
655 struct elv_data dta;
656
Richard Biener726a9892008-07-28 14:33:56 +0000657 memset (&dta.info, '\0', sizeof (dta.info));
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100658 dta.entry = entry;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200659 dta.decl_address = decl_address;
660 dta.changed = false;
661
Richard Biener726a9892008-07-28 14:33:56 +0000662 walk_gimple_op (stmt, eliminate_local_variables_1, &dta.info);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200663
664 if (dta.changed)
665 update_stmt (stmt);
666}
667
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100668/* Eliminates the references to local variables from the single entry
669 single exit region between the ENTRY and EXIT edges.
670
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000671 This includes:
672 1) Taking address of a local variable -- these are moved out of the
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100673 region (and temporary variable is created to hold the address if
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000674 necessary).
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100675
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200676 2) Dereferencing a local variable -- these are replaced with indirect
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000677 references. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200678
679static void
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100680eliminate_local_variables (edge entry, edge exit)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200681{
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100682 basic_block bb;
683 VEC (basic_block, heap) *body = VEC_alloc (basic_block, heap, 3);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200684 unsigned i;
Richard Biener726a9892008-07-28 14:33:56 +0000685 gimple_stmt_iterator gsi;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200686 htab_t decl_address = htab_create (10, int_tree_map_hash, int_tree_map_eq,
687 free);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100688 basic_block entry_bb = entry->src;
689 basic_block exit_bb = exit->dest;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200690
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100691 gather_blocks_in_sese_region (entry_bb, exit_bb, &body);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200692
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100693 for (i = 0; VEC_iterate (basic_block, body, i, bb); i++)
694 if (bb != entry_bb && bb != exit_bb)
Richard Biener726a9892008-07-28 14:33:56 +0000695 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
696 eliminate_local_variables_stmt (entry, gsi_stmt (gsi),
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100697 decl_address);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200698
699 htab_delete (decl_address);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100700 VEC_free (basic_block, heap, body);
701}
702
703/* Returns true if expression EXPR is not defined between ENTRY and
704 EXIT, i.e. if all its operands are defined outside of the region. */
705
706static bool
707expr_invariant_in_region_p (edge entry, edge exit, tree expr)
708{
709 basic_block entry_bb = entry->src;
710 basic_block exit_bb = exit->dest;
711 basic_block def_bb;
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100712
713 if (is_gimple_min_invariant (expr))
714 return true;
715
716 if (TREE_CODE (expr) == SSA_NAME)
717 {
Richard Biener726a9892008-07-28 14:33:56 +0000718 def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100719 if (def_bb
720 && dominated_by_p (CDI_DOMINATORS, def_bb, entry_bb)
721 && !dominated_by_p (CDI_DOMINATORS, def_bb, exit_bb))
722 return false;
723
724 return true;
725 }
726
Richard Biener726a9892008-07-28 14:33:56 +0000727 return false;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200728}
729
730/* If COPY_NAME_P is true, creates and returns a duplicate of NAME.
731 The copies are stored to NAME_COPIES, if NAME was already duplicated,
732 its duplicate stored in NAME_COPIES is returned.
733
734 Regardless of COPY_NAME_P, the decl used as a base of the ssa name is also
735 duplicated, storing the copies in DECL_COPIES. */
736
737static tree
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100738separate_decls_in_region_name (tree name,
739 htab_t name_copies, htab_t decl_copies,
740 bool copy_name_p)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200741{
742 tree copy, var, var_copy;
743 unsigned idx, uid, nuid;
744 struct int_tree_map ielt, *nielt;
745 struct name_to_copy_elt elt, *nelt;
746 void **slot, **dslot;
747
748 if (TREE_CODE (name) != SSA_NAME)
749 return name;
750
751 idx = SSA_NAME_VERSION (name);
752 elt.version = idx;
753 slot = htab_find_slot_with_hash (name_copies, &elt, idx,
754 copy_name_p ? INSERT : NO_INSERT);
755 if (slot && *slot)
756 return ((struct name_to_copy_elt *) *slot)->new_name;
757
758 var = SSA_NAME_VAR (name);
759 uid = DECL_UID (var);
760 ielt.uid = uid;
761 dslot = htab_find_slot_with_hash (decl_copies, &ielt, uid, INSERT);
762 if (!*dslot)
763 {
764 var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
Jakub Jelinek36ad7922007-12-03 23:35:39 +0100765 DECL_GIMPLE_REG_P (var_copy) = DECL_GIMPLE_REG_P (var);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200766 add_referenced_var (var_copy);
767 nielt = XNEW (struct int_tree_map);
768 nielt->uid = uid;
769 nielt->to = var_copy;
770 *dslot = nielt;
771
772 /* Ensure that when we meet this decl next time, we won't duplicate
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000773 it again. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200774 nuid = DECL_UID (var_copy);
775 ielt.uid = nuid;
776 dslot = htab_find_slot_with_hash (decl_copies, &ielt, nuid, INSERT);
777 gcc_assert (!*dslot);
778 nielt = XNEW (struct int_tree_map);
779 nielt->uid = nuid;
780 nielt->to = var_copy;
781 *dslot = nielt;
782 }
783 else
784 var_copy = ((struct int_tree_map *) *dslot)->to;
785
786 if (copy_name_p)
787 {
Richard Biener726a9892008-07-28 14:33:56 +0000788 copy = duplicate_ssa_name (name, NULL);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200789 nelt = XNEW (struct name_to_copy_elt);
790 nelt->version = idx;
791 nelt->new_name = copy;
792 nelt->field = NULL_TREE;
793 *slot = nelt;
794 }
795 else
796 {
797 gcc_assert (!slot);
798 copy = name;
799 }
800
801 SSA_NAME_VAR (copy) = var_copy;
802 return copy;
803}
804
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100805/* Finds the ssa names used in STMT that are defined outside the
806 region between ENTRY and EXIT and replaces such ssa names with
807 their duplicates. The duplicates are stored to NAME_COPIES. Base
808 decls of all ssa names used in STMT (including those defined in
809 LOOP) are replaced with the new temporary variables; the
810 replacement decls are stored in DECL_COPIES. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200811
812static void
Richard Biener726a9892008-07-28 14:33:56 +0000813separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100814 htab_t name_copies, htab_t decl_copies)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200815{
816 use_operand_p use;
817 def_operand_p def;
818 ssa_op_iter oi;
819 tree name, copy;
820 bool copy_name_p;
821
822 mark_virtual_ops_for_renaming (stmt);
823
824 FOR_EACH_PHI_OR_STMT_DEF (def, stmt, oi, SSA_OP_DEF)
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000825 {
826 name = DEF_FROM_PTR (def);
827 gcc_assert (TREE_CODE (name) == SSA_NAME);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100828 copy = separate_decls_in_region_name (name, name_copies, decl_copies,
829 false);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000830 gcc_assert (copy == name);
831 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200832
833 FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE)
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000834 {
835 name = USE_FROM_PTR (use);
836 if (TREE_CODE (name) != SSA_NAME)
837 continue;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200838
Antoniu Pop9f9f72a2008-04-24 16:23:51 +0100839 copy_name_p = expr_invariant_in_region_p (entry, exit, name);
840 copy = separate_decls_in_region_name (name, name_copies, decl_copies,
841 copy_name_p);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000842 SET_USE (use, copy);
843 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200844}
845
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000846/* Callback for htab_traverse. Adds a field corresponding to the reduction
847 specified in SLOT. The type is passed in DATA. */
848
849static int
850add_field_for_reduction (void **slot, void *data)
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000851{
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000852
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +0000853 struct reduction_info *const red = (struct reduction_info *) *slot;
854 tree const type = (tree) data;
Richard Biener726a9892008-07-28 14:33:56 +0000855 tree var = SSA_NAME_VAR (gimple_assign_lhs (red->reduc_stmt));
Aldy Hernandezc2255bc2009-06-12 22:06:47 +0000856 tree field = build_decl (gimple_location (red->reduc_stmt),
857 FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000858
859 insert_field_into_struct (type, field);
860
861 red->field = field;
862
863 return 1;
864}
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000865
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200866/* Callback for htab_traverse. Adds a field corresponding to a ssa name
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +0000867 described in SLOT. The type is passed in DATA. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200868
869static int
870add_field_for_name (void **slot, void *data)
871{
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +0000872 struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
873 tree type = (tree) data;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200874 tree name = ssa_name (elt->version);
875 tree var = SSA_NAME_VAR (name);
Aldy Hernandezc2255bc2009-06-12 22:06:47 +0000876 tree field = build_decl (DECL_SOURCE_LOCATION (var),
877 FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200878
879 insert_field_into_struct (type, field);
880 elt->field = field;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000881
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200882 return 1;
883}
884
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000885/* Callback for htab_traverse. A local result is the intermediate result
886 computed by a single
Ralf Wildenhuesfa10bee2008-06-06 05:42:00 +0000887 thread, or the initial value in case no iteration was executed.
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000888 This function creates a phi node reflecting these values.
889 The phi's result will be stored in NEW_PHI field of the
890 reduction's data structure. */
891
892static int
893create_phi_for_local_result (void **slot, void *data)
894{
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +0000895 struct reduction_info *const reduc = (struct reduction_info *) *slot;
896 const struct loop *const loop = (const struct loop *) data;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000897 edge e;
Richard Biener726a9892008-07-28 14:33:56 +0000898 gimple new_phi;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000899 basic_block store_bb;
900 tree local_res;
901
902 /* STORE_BB is the block where the phi
903 should be stored. It is the destination of the loop exit.
Richard Biener726a9892008-07-28 14:33:56 +0000904 (Find the fallthru edge from GIMPLE_OMP_CONTINUE). */
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000905 store_bb = FALLTHRU_EDGE (loop->latch)->dest;
906
907 /* STORE_BB has two predecessors. One coming from the loop
908 (the reduction's result is computed at the loop),
909 and another coming from a block preceding the loop,
910 when no iterations
911 are executed (the initial value should be taken). */
912 if (EDGE_PRED (store_bb, 0) == FALLTHRU_EDGE (loop->latch))
913 e = EDGE_PRED (store_bb, 1);
914 else
915 e = EDGE_PRED (store_bb, 0);
Richard Biener726a9892008-07-28 14:33:56 +0000916 local_res
917 = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
918 NULL);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000919 new_phi = create_phi_node (local_res, store_bb);
920 SSA_NAME_DEF_STMT (local_res) = new_phi;
921 add_phi_arg (new_phi, reduc->init, e);
Richard Biener726a9892008-07-28 14:33:56 +0000922 add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000923 FALLTHRU_EDGE (loop->latch));
924 reduc->new_phi = new_phi;
925
926 return 1;
927}
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +0200928
929struct clsn_data
930{
931 tree store;
932 tree load;
933
934 basic_block store_bb;
935 basic_block load_bb;
936};
937
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000938/* Callback for htab_traverse. Create an atomic instruction for the
939 reduction described in SLOT.
940 DATA annotates the place in memory the atomic operation relates to,
941 and the basic block it needs to be generated in. */
942
943static int
944create_call_for_reduction_1 (void **slot, void *data)
945{
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +0000946 struct reduction_info *const reduc = (struct reduction_info *) *slot;
947 struct clsn_data *const clsn_data = (struct clsn_data *) data;
Richard Biener726a9892008-07-28 14:33:56 +0000948 gimple_stmt_iterator gsi;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000949 tree type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
950 tree struct_type = TREE_TYPE (TREE_TYPE (clsn_data->load));
951 tree load_struct;
952 basic_block bb;
953 basic_block new_bb;
954 edge e;
955 tree t, addr, addr_type, ref, x;
Richard Biener726a9892008-07-28 14:33:56 +0000956 tree tmp_load, name;
957 gimple load;
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000958
959 load_struct = fold_build1 (INDIRECT_REF, struct_type, clsn_data->load);
960 t = build3 (COMPONENT_REF, type, load_struct, reduc->field, NULL_TREE);
961 addr_type = build_pointer_type (type);
962
963 addr = build_addr (t, current_function_decl);
964
965 /* Create phi node. */
966 bb = clsn_data->load_bb;
967
968 e = split_block (bb, t);
969 new_bb = e->dest;
970
971 tmp_load = create_tmp_var (TREE_TYPE (TREE_TYPE (addr)), NULL);
972 add_referenced_var (tmp_load);
973 tmp_load = make_ssa_name (tmp_load, NULL);
Richard Biener726a9892008-07-28 14:33:56 +0000974 load = gimple_build_omp_atomic_load (tmp_load, addr);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000975 SSA_NAME_DEF_STMT (tmp_load) = load;
Richard Biener726a9892008-07-28 14:33:56 +0000976 gsi = gsi_start_bb (new_bb);
977 gsi_insert_after (&gsi, load, GSI_NEW_STMT);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000978
979 e = split_block (new_bb, load);
980 new_bb = e->dest;
Richard Biener726a9892008-07-28 14:33:56 +0000981 gsi = gsi_start_bb (new_bb);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000982 ref = tmp_load;
Richard Biener726a9892008-07-28 14:33:56 +0000983 x = fold_build2 (reduc->reduction_code,
984 TREE_TYPE (PHI_RESULT (reduc->new_phi)), ref,
985 PHI_RESULT (reduc->new_phi));
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000986
Richard Biener726a9892008-07-28 14:33:56 +0000987 name = force_gimple_operand_gsi (&gsi, x, true, NULL_TREE, true,
988 GSI_CONTINUE_LINKING);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000989
Richard Biener726a9892008-07-28 14:33:56 +0000990 gsi_insert_after (&gsi, gimple_build_omp_atomic_store (name), GSI_NEW_STMT);
Razya Ladelskya509ebb2007-10-29 11:05:04 +0000991 return 1;
992}
993
994/* Create the atomic operation at the join point of the threads.
995 REDUCTION_LIST describes the reductions in the LOOP.
996 LD_ST_DATA describes the shared data structure where
997 shared data is stored in and loaded from. */
998static void
999create_call_for_reduction (struct loop *loop, htab_t reduction_list,
1000 struct clsn_data *ld_st_data)
1001{
1002 htab_traverse (reduction_list, create_phi_for_local_result, loop);
Richard Biener726a9892008-07-28 14:33:56 +00001003 /* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001004 ld_st_data->load_bb = FALLTHRU_EDGE (loop->latch)->dest;
1005 htab_traverse (reduction_list, create_call_for_reduction_1, ld_st_data);
1006}
1007
Razya Ladelskyae0bce62007-12-18 11:21:48 +00001008/* Callback for htab_traverse. Loads the final reduction value at the
1009 join point of all threads, and inserts it in the right place. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001010
1011static int
1012create_loads_for_reductions (void **slot, void *data)
1013{
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +00001014 struct reduction_info *const red = (struct reduction_info *) *slot;
1015 struct clsn_data *const clsn_data = (struct clsn_data *) data;
Richard Biener726a9892008-07-28 14:33:56 +00001016 gimple stmt;
1017 gimple_stmt_iterator gsi;
1018 tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001019 tree struct_type = TREE_TYPE (TREE_TYPE (clsn_data->load));
1020 tree load_struct;
Razya Ladelskyae0bce62007-12-18 11:21:48 +00001021 tree name;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001022 tree x;
1023
Richard Biener726a9892008-07-28 14:33:56 +00001024 gsi = gsi_after_labels (clsn_data->load_bb);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001025 load_struct = fold_build1 (INDIRECT_REF, struct_type, clsn_data->load);
1026 load_struct = build3 (COMPONENT_REF, type, load_struct, red->field,
1027 NULL_TREE);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001028
Razya Ladelskyae0bce62007-12-18 11:21:48 +00001029 x = load_struct;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001030 name = PHI_RESULT (red->keep_res);
Richard Biener726a9892008-07-28 14:33:56 +00001031 stmt = gimple_build_assign (name, x);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001032 SSA_NAME_DEF_STMT (name) = stmt;
1033
Richard Biener726a9892008-07-28 14:33:56 +00001034 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001035
Richard Biener726a9892008-07-28 14:33:56 +00001036 for (gsi = gsi_start_phis (gimple_bb (red->keep_res));
1037 !gsi_end_p (gsi); gsi_next (&gsi))
1038 if (gsi_stmt (gsi) == red->keep_res)
1039 {
1040 remove_phi_node (&gsi, false);
1041 return 1;
1042 }
1043 gcc_unreachable ();
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001044}
1045
1046/* Load the reduction result that was stored in LD_ST_DATA.
1047 REDUCTION_LIST describes the list of reductions that the
Ralf Wildenhuesfa10bee2008-06-06 05:42:00 +00001048 loads should be generated for. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001049static void
1050create_final_loads_for_reduction (htab_t reduction_list,
1051 struct clsn_data *ld_st_data)
1052{
Richard Biener726a9892008-07-28 14:33:56 +00001053 gimple_stmt_iterator gsi;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001054 tree t;
Richard Biener726a9892008-07-28 14:33:56 +00001055 gimple stmt;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001056
Richard Biener726a9892008-07-28 14:33:56 +00001057 gsi = gsi_after_labels (ld_st_data->load_bb);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001058 t = build_fold_addr_expr (ld_st_data->store);
Richard Biener726a9892008-07-28 14:33:56 +00001059 stmt = gimple_build_assign (ld_st_data->load, t);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001060
Richard Biener726a9892008-07-28 14:33:56 +00001061 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1062 SSA_NAME_DEF_STMT (ld_st_data->load) = stmt;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001063
1064 htab_traverse (reduction_list, create_loads_for_reductions, ld_st_data);
1065
1066}
1067
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001068/* Callback for htab_traverse. Store the neutral value for the
1069 particular reduction's operation, e.g. 0 for PLUS_EXPR,
1070 1 for MULT_EXPR, etc. into the reduction field.
1071 The reduction is specified in SLOT. The store information is
1072 passed in DATA. */
1073
1074static int
1075create_stores_for_reduction (void **slot, void *data)
1076{
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +00001077 struct reduction_info *const red = (struct reduction_info *) *slot;
1078 struct clsn_data *const clsn_data = (struct clsn_data *) data;
Richard Biener726a9892008-07-28 14:33:56 +00001079 tree t;
1080 gimple stmt;
1081 gimple_stmt_iterator gsi;
1082 tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
1083
1084 gsi = gsi_last_bb (clsn_data->store_bb);
1085 t = build3 (COMPONENT_REF, type, clsn_data->store, red->field, NULL_TREE);
1086 stmt = gimple_build_assign (t, red->initial_value);
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001087 mark_virtual_ops_for_renaming (stmt);
Richard Biener726a9892008-07-28 14:33:56 +00001088 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001089
1090 return 1;
1091}
1092
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001093/* Callback for htab_traverse. Creates loads to a field of LOAD in LOAD_BB and
1094 store to a field of STORE in STORE_BB for the ssa name and its duplicate
1095 specified in SLOT. */
1096
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001097static int
1098create_loads_and_stores_for_name (void **slot, void *data)
1099{
Kaveh R. Ghazi3d9a9f92008-06-20 18:34:07 +00001100 struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
1101 struct clsn_data *const clsn_data = (struct clsn_data *) data;
Richard Biener726a9892008-07-28 14:33:56 +00001102 tree t;
1103 gimple stmt;
1104 gimple_stmt_iterator gsi;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001105 tree type = TREE_TYPE (elt->new_name);
1106 tree struct_type = TREE_TYPE (TREE_TYPE (clsn_data->load));
1107 tree load_struct;
1108
Richard Biener726a9892008-07-28 14:33:56 +00001109 gsi = gsi_last_bb (clsn_data->store_bb);
1110 t = build3 (COMPONENT_REF, type, clsn_data->store, elt->field, NULL_TREE);
1111 stmt = gimple_build_assign (t, ssa_name (elt->version));
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001112 mark_virtual_ops_for_renaming (stmt);
Richard Biener726a9892008-07-28 14:33:56 +00001113 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001114
Richard Biener726a9892008-07-28 14:33:56 +00001115 gsi = gsi_last_bb (clsn_data->load_bb);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001116 load_struct = fold_build1 (INDIRECT_REF, struct_type, clsn_data->load);
Richard Biener726a9892008-07-28 14:33:56 +00001117 t = build3 (COMPONENT_REF, type, load_struct, elt->field, NULL_TREE);
1118 stmt = gimple_build_assign (elt->new_name, t);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001119 SSA_NAME_DEF_STMT (elt->new_name) = stmt;
Richard Biener726a9892008-07-28 14:33:56 +00001120 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001121
1122 return 1;
1123}
1124
1125/* Moves all the variables used in LOOP and defined outside of it (including
1126 the initial values of loop phi nodes, and *PER_THREAD if it is a ssa
1127 name) to a structure created for this purpose. The code
1128
1129 while (1)
1130 {
1131 use (a);
1132 use (b);
1133 }
1134
1135 is transformed this way:
1136
1137 bb0:
1138 old.a = a;
1139 old.b = b;
1140
1141 bb1:
1142 a' = new->a;
1143 b' = new->b;
1144 while (1)
1145 {
1146 use (a');
1147 use (b');
1148 }
1149
1150 `old' is stored to *ARG_STRUCT and `new' is stored to NEW_ARG_STRUCT. The
1151 pointer `new' is intentionally not initialized (the loop will be split to a
1152 separate function later, and `new' will be initialized from its arguments).
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001153 LD_ST_DATA holds information about the shared data structure used to pass
1154 information among the threads. It is initialized here, and
1155 gen_parallel_loop will pass it to create_call_for_reduction that
1156 needs this information. REDUCTION_LIST describes the reductions
1157 in LOOP. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001158
1159static void
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001160separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
1161 tree *arg_struct, tree *new_arg_struct,
1162 struct clsn_data *ld_st_data)
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001163
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001164{
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001165 basic_block bb1 = split_edge (entry);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001166 basic_block bb0 = single_pred (bb1);
1167 htab_t name_copies = htab_create (10, name_to_copy_elt_hash,
1168 name_to_copy_elt_eq, free);
1169 htab_t decl_copies = htab_create (10, int_tree_map_hash, int_tree_map_eq,
1170 free);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001171 unsigned i;
Richard Biener726a9892008-07-28 14:33:56 +00001172 tree type, type_name, nvar;
1173 gimple_stmt_iterator gsi;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001174 struct clsn_data clsn_data;
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001175 VEC (basic_block, heap) *body = VEC_alloc (basic_block, heap, 3);
1176 basic_block bb;
1177 basic_block entry_bb = bb1;
1178 basic_block exit_bb = exit->dest;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001179
Richard Biener726a9892008-07-28 14:33:56 +00001180 entry = single_succ_edge (entry_bb);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001181 gather_blocks_in_sese_region (entry_bb, exit_bb, &body);
1182
1183 for (i = 0; VEC_iterate (basic_block, body, i, bb); i++)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001184 {
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001185 if (bb != entry_bb && bb != exit_bb)
1186 {
Richard Biener726a9892008-07-28 14:33:56 +00001187 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1188 separate_decls_in_region_stmt (entry, exit, gsi_stmt (gsi),
1189 name_copies, decl_copies);
1190
1191 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1192 separate_decls_in_region_stmt (entry, exit, gsi_stmt (gsi),
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001193 name_copies, decl_copies);
1194 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001195 }
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001196
1197 VEC_free (basic_block, heap, body);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001198
Razya Ladelskyc0399c42008-11-19 16:08:01 +00001199 if (htab_elements (name_copies) == 0 && reduction_list == 0)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001200 {
1201 /* It may happen that there is nothing to copy (if there are only
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001202 loop carried and external variables in the loop). */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001203 *arg_struct = NULL;
1204 *new_arg_struct = NULL;
1205 }
1206 else
1207 {
1208 /* Create the type for the structure to store the ssa names to. */
1209 type = lang_hooks.types.make_type (RECORD_TYPE);
Aldy Hernandezc2255bc2009-06-12 22:06:47 +00001210 type_name = build_decl (BUILTINS_LOCATION,
1211 TYPE_DECL, create_tmp_var_name (".paral_data"),
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001212 type);
1213 TYPE_NAME (type) = type_name;
1214
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001215 htab_traverse (name_copies, add_field_for_name, type);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001216 if (reduction_list && htab_elements (reduction_list) > 0)
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001217 {
1218 /* Create the fields for reductions. */
1219 htab_traverse (reduction_list, add_field_for_reduction,
1220 type);
1221 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001222 layout_type (type);
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001223
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001224 /* Create the loads and stores. */
1225 *arg_struct = create_tmp_var (type, ".paral_data_store");
1226 add_referenced_var (*arg_struct);
1227 nvar = create_tmp_var (build_pointer_type (type), ".paral_data_load");
1228 add_referenced_var (nvar);
Richard Biener726a9892008-07-28 14:33:56 +00001229 *new_arg_struct = make_ssa_name (nvar, NULL);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001230
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001231 ld_st_data->store = *arg_struct;
1232 ld_st_data->load = *new_arg_struct;
1233 ld_st_data->store_bb = bb0;
1234 ld_st_data->load_bb = bb1;
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001235
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001236 htab_traverse (name_copies, create_loads_and_stores_for_name,
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001237 ld_st_data);
1238
Razya Ladelskyae0bce62007-12-18 11:21:48 +00001239 /* Load the calculation from memory (after the join of the threads). */
1240
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001241 if (reduction_list && htab_elements (reduction_list) > 0)
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001242 {
Razya Ladelsky0eb7e7a2007-11-06 10:29:12 +00001243 htab_traverse (reduction_list, create_stores_for_reduction,
1244 ld_st_data);
Richard Biener726a9892008-07-28 14:33:56 +00001245 clsn_data.load = make_ssa_name (nvar, NULL);
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001246 clsn_data.load_bb = exit->dest;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001247 clsn_data.store = ld_st_data->store;
1248 create_final_loads_for_reduction (reduction_list, &clsn_data);
1249 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001250 }
1251
1252 htab_delete (decl_copies);
1253 htab_delete (name_copies);
1254}
1255
1256/* Bitmap containing uids of functions created by parallelization. We cannot
1257 allocate it from the default obstack, as it must live across compilation
1258 of several functions; we make it gc allocated instead. */
1259
1260static GTY(()) bitmap parallelized_functions;
1261
1262/* Returns true if FN was created by create_loop_fn. */
1263
1264static bool
1265parallelized_function_p (tree fn)
1266{
1267 if (!parallelized_functions || !DECL_ARTIFICIAL (fn))
1268 return false;
1269
1270 return bitmap_bit_p (parallelized_functions, DECL_UID (fn));
1271}
1272
1273/* Creates and returns an empty function that will receive the body of
1274 a parallelized loop. */
1275
1276static tree
1277create_loop_fn (void)
1278{
1279 char buf[100];
1280 char *tname;
1281 tree decl, type, name, t;
1282 struct function *act_cfun = cfun;
1283 static unsigned loopfn_num;
1284
1285 snprintf (buf, 100, "%s.$loopfn", current_function_name ());
1286 ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
1287 clean_symbol_name (tname);
1288 name = get_identifier (tname);
1289 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1290
Aldy Hernandezc2255bc2009-06-12 22:06:47 +00001291 decl = build_decl (BUILTINS_LOCATION,
1292 FUNCTION_DECL, name, type);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001293 if (!parallelized_functions)
1294 parallelized_functions = BITMAP_GGC_ALLOC ();
1295 bitmap_set_bit (parallelized_functions, DECL_UID (decl));
1296
1297 TREE_STATIC (decl) = 1;
1298 TREE_USED (decl) = 1;
1299 DECL_ARTIFICIAL (decl) = 1;
1300 DECL_IGNORED_P (decl) = 0;
1301 TREE_PUBLIC (decl) = 0;
1302 DECL_UNINLINABLE (decl) = 1;
1303 DECL_EXTERNAL (decl) = 0;
1304 DECL_CONTEXT (decl) = NULL_TREE;
1305 DECL_INITIAL (decl) = make_node (BLOCK);
1306
Aldy Hernandezc2255bc2009-06-12 22:06:47 +00001307 t = build_decl (BUILTINS_LOCATION,
1308 RESULT_DECL, NULL_TREE, void_type_node);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001309 DECL_ARTIFICIAL (t) = 1;
1310 DECL_IGNORED_P (t) = 1;
1311 DECL_RESULT (decl) = t;
1312
Aldy Hernandezc2255bc2009-06-12 22:06:47 +00001313 t = build_decl (BUILTINS_LOCATION,
1314 PARM_DECL, get_identifier (".paral_data_param"),
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001315 ptr_type_node);
1316 DECL_ARTIFICIAL (t) = 1;
1317 DECL_ARG_TYPE (t) = ptr_type_node;
1318 DECL_CONTEXT (t) = decl;
1319 TREE_USED (t) = 1;
1320 DECL_ARGUMENTS (decl) = t;
1321
Andreas Krebbel182e0d72007-11-26 17:33:23 +00001322 allocate_struct_function (decl, false);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001323
1324 /* The call to allocate_struct_function clobbers CFUN, so we need to restore
1325 it. */
Tom Tromey5576d6f2007-11-16 00:11:47 +00001326 set_cfun (act_cfun);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001327
1328 return decl;
1329}
1330
Sebastian Pop7d4fba42009-03-03 03:47:22 +00001331/* Bases all the induction variables in LOOP on a single induction
1332 variable (unsigned with base 0 and step 1), whose final value is
1333 compared with *NIT. When the IV type precision has to be larger
1334 than *NIT type precision, *NIT is converted to the larger type, the
1335 conversion code is inserted before the loop, and *NIT is updated to
1336 the new definition. The induction variable is incremented in the
1337 loop latch. REDUCTION_LIST describes the reductions in LOOP.
1338 Return the induction variable that was created. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001339
Sebastian Pop81b822d2008-12-11 07:23:02 +00001340tree
Sebastian Pop7d4fba42009-03-03 03:47:22 +00001341canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree *nit)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001342{
Sebastian Pop7d4fba42009-03-03 03:47:22 +00001343 unsigned precision = TYPE_PRECISION (TREE_TYPE (*nit));
1344 unsigned original_precision = precision;
Richard Biener726a9892008-07-28 14:33:56 +00001345 tree res, type, var_before, val, atype, mtype;
1346 gimple_stmt_iterator gsi, psi;
1347 gimple phi, stmt;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001348 bool ok;
1349 affine_iv iv;
1350 edge exit = single_dom_exit (loop);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001351 struct reduction_info *red;
Sebastian Pop7d4fba42009-03-03 03:47:22 +00001352 gimple_seq stmts;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001353
Richard Biener726a9892008-07-28 14:33:56 +00001354 for (psi = gsi_start_phis (loop->header);
1355 !gsi_end_p (psi); gsi_next (&psi))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001356 {
Richard Biener726a9892008-07-28 14:33:56 +00001357 phi = gsi_stmt (psi);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001358 res = PHI_RESULT (phi);
1359
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001360 if (is_gimple_reg (res) && TYPE_PRECISION (TREE_TYPE (res)) > precision)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001361 precision = TYPE_PRECISION (TREE_TYPE (res));
1362 }
1363
1364 type = lang_hooks.types.type_for_size (precision, 1);
1365
Sebastian Pop7d4fba42009-03-03 03:47:22 +00001366 if (original_precision != precision)
1367 {
1368 *nit = fold_convert (type, *nit);
1369 *nit = force_gimple_operand (*nit, &stmts, true, NULL_TREE);
1370 if (stmts)
1371 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
1372 }
1373
Richard Biener726a9892008-07-28 14:33:56 +00001374 gsi = gsi_last_bb (loop->latch);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001375 create_iv (build_int_cst_type (type, 0), build_int_cst (type, 1), NULL_TREE,
Richard Biener726a9892008-07-28 14:33:56 +00001376 loop, &gsi, true, &var_before, NULL);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001377
Richard Biener726a9892008-07-28 14:33:56 +00001378 gsi = gsi_after_labels (loop->header);
1379 for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); )
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001380 {
Richard Biener726a9892008-07-28 14:33:56 +00001381 phi = gsi_stmt (psi);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001382 res = PHI_RESULT (phi);
1383
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001384 if (!is_gimple_reg (res) || res == var_before)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001385 {
Richard Biener726a9892008-07-28 14:33:56 +00001386 gsi_next (&psi);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001387 continue;
1388 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001389
Zdenek Dvorakf017bf52009-03-04 18:50:20 +01001390 ok = simple_iv (loop, loop, res, &iv, true);
Sebastian Pop81b822d2008-12-11 07:23:02 +00001391
1392 if (reduction_list)
1393 red = reduction_phi (reduction_list, phi);
1394 else
1395 red = NULL;
1396
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001397 /* We preserve the reduction phi nodes. */
1398 if (!ok && red)
1399 {
Richard Biener726a9892008-07-28 14:33:56 +00001400 gsi_next (&psi);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001401 continue;
1402 }
1403 else
1404 gcc_assert (ok);
Richard Biener726a9892008-07-28 14:33:56 +00001405 remove_phi_node (&psi, false);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001406
1407 atype = TREE_TYPE (res);
Jakub Jelinek36ad7922007-12-03 23:35:39 +01001408 mtype = POINTER_TYPE_P (atype) ? sizetype : atype;
1409 val = fold_build2 (MULT_EXPR, mtype, unshare_expr (iv.step),
1410 fold_convert (mtype, var_before));
1411 val = fold_build2 (POINTER_TYPE_P (atype)
1412 ? POINTER_PLUS_EXPR : PLUS_EXPR,
1413 atype, unshare_expr (iv.base), val);
Richard Biener726a9892008-07-28 14:33:56 +00001414 val = force_gimple_operand_gsi (&gsi, val, false, NULL_TREE, true,
1415 GSI_SAME_STMT);
1416 stmt = gimple_build_assign (res, val);
1417 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1418 SSA_NAME_DEF_STMT (res) = stmt;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001419 }
1420
Richard Biener726a9892008-07-28 14:33:56 +00001421 stmt = last_stmt (exit->src);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001422 /* Make the loop exit if the control condition is not satisfied. */
1423 if (exit->flags & EDGE_TRUE_VALUE)
1424 {
1425 edge te, fe;
1426
1427 extract_true_false_edges_from_block (exit->src, &te, &fe);
1428 te->flags = EDGE_FALSE_VALUE;
1429 fe->flags = EDGE_TRUE_VALUE;
1430 }
Richard Biener726a9892008-07-28 14:33:56 +00001431 gimple_cond_set_code (stmt, LT_EXPR);
1432 gimple_cond_set_lhs (stmt, var_before);
Sebastian Pop7d4fba42009-03-03 03:47:22 +00001433 gimple_cond_set_rhs (stmt, *nit);
Sebastian Pop81b822d2008-12-11 07:23:02 +00001434 update_stmt (stmt);
1435
1436 return var_before;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001437}
1438
1439/* Moves the exit condition of LOOP to the beginning of its header, and
1440 duplicates the part of the last iteration that gets disabled to the
1441 exit of the loop. NIT is the number of iterations of the loop
1442 (used to initialize the variables in the duplicated part).
1443
Ralf Wildenhuesfa10bee2008-06-06 05:42:00 +00001444 TODO: the common case is that latch of the loop is empty and immediately
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001445 follows the loop exit. In this case, it would be better not to copy the
1446 body of the loop, but only move the entry of the loop directly before the
1447 exit check and increase the number of iterations of the loop by one.
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001448 This may need some additional preconditioning in case NIT = ~0.
1449 REDUCTION_LIST describes the reductions in LOOP. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001450
1451static void
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001452transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001453{
1454 basic_block *bbs, *nbbs, ex_bb, orig_header;
1455 unsigned n;
1456 bool ok;
1457 edge exit = single_dom_exit (loop), hpred;
Richard Biener726a9892008-07-28 14:33:56 +00001458 tree control, control_name, res, t;
1459 gimple phi, nphi, cond_stmt, stmt;
1460 gimple_stmt_iterator gsi;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001461
1462 split_block_after_labels (loop->header);
1463 orig_header = single_succ (loop->header);
1464 hpred = single_succ_edge (loop->header);
1465
1466 cond_stmt = last_stmt (exit->src);
Richard Biener726a9892008-07-28 14:33:56 +00001467 control = gimple_cond_lhs (cond_stmt);
1468 gcc_assert (gimple_cond_rhs (cond_stmt) == nit);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001469
1470 /* Make sure that we have phi nodes on exit for all loop header phis
1471 (create_parallel_loop requires that). */
Richard Biener726a9892008-07-28 14:33:56 +00001472 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001473 {
Richard Biener726a9892008-07-28 14:33:56 +00001474 phi = gsi_stmt (gsi);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001475 res = PHI_RESULT (phi);
1476 t = make_ssa_name (SSA_NAME_VAR (res), phi);
1477 SET_PHI_RESULT (phi, t);
1478
1479 nphi = create_phi_node (res, orig_header);
1480 SSA_NAME_DEF_STMT (res) = nphi;
1481 add_phi_arg (nphi, t, hpred);
1482
1483 if (res == control)
1484 {
Richard Biener726a9892008-07-28 14:33:56 +00001485 gimple_cond_set_lhs (cond_stmt, t);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001486 update_stmt (cond_stmt);
1487 control = t;
1488 }
1489 }
1490
1491 bbs = get_loop_body_in_dom_order (loop);
1492 for (n = 0; bbs[n] != exit->src; n++)
1493 continue;
1494 nbbs = XNEWVEC (basic_block, n);
Richard Biener726a9892008-07-28 14:33:56 +00001495 ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
1496 bbs + 1, n, nbbs);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001497 gcc_assert (ok);
1498 free (bbs);
1499 ex_bb = nbbs[0];
1500 free (nbbs);
1501
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001502 /* Other than reductions, the only gimple reg that should be copied
Richard Biener726a9892008-07-28 14:33:56 +00001503 out of the loop is the control variable. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001504
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001505 control_name = NULL_TREE;
Richard Biener726a9892008-07-28 14:33:56 +00001506 for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); )
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001507 {
Richard Biener726a9892008-07-28 14:33:56 +00001508 phi = gsi_stmt (gsi);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001509 res = PHI_RESULT (phi);
1510 if (!is_gimple_reg (res))
Richard Biener726a9892008-07-28 14:33:56 +00001511 {
1512 gsi_next (&gsi);
1513 continue;
1514 }
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001515
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001516 /* Check if it is a part of reduction. If it is,
1517 keep the phi at the reduction's keep_res field. The
1518 PHI_RESULT of this phi is the resulting value of the reduction
1519 variable when exiting the loop. */
1520
1521 exit = single_dom_exit (loop);
1522
1523 if (htab_elements (reduction_list) > 0)
1524 {
1525 struct reduction_info *red;
1526
1527 tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
1528
1529 red = reduction_phi (reduction_list, SSA_NAME_DEF_STMT (val));
1530 if (red)
Richard Biener726a9892008-07-28 14:33:56 +00001531 {
1532 red->keep_res = phi;
1533 gsi_next (&gsi);
1534 continue;
1535 }
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001536 }
Richard Biener726a9892008-07-28 14:33:56 +00001537 gcc_assert (control_name == NULL_TREE
1538 && SSA_NAME_VAR (res) == SSA_NAME_VAR (control));
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001539 control_name = res;
Richard Biener726a9892008-07-28 14:33:56 +00001540 remove_phi_node (&gsi, false);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001541 }
1542 gcc_assert (control_name != NULL_TREE);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001543
1544 /* Initialize the control variable to NIT. */
Richard Biener726a9892008-07-28 14:33:56 +00001545 gsi = gsi_after_labels (ex_bb);
1546 nit = force_gimple_operand_gsi (&gsi,
Zdenek Dvorak29ac1d92008-01-12 14:43:21 +01001547 fold_convert (TREE_TYPE (control_name), nit),
Richard Biener726a9892008-07-28 14:33:56 +00001548 false, NULL_TREE, false, GSI_SAME_STMT);
1549 stmt = gimple_build_assign (control_name, nit);
1550 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1551 SSA_NAME_DEF_STMT (control_name) = stmt;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001552}
1553
1554/* Create the parallel constructs for LOOP as described in gen_parallel_loop.
Richard Biener726a9892008-07-28 14:33:56 +00001555 LOOP_FN and DATA are the arguments of GIMPLE_OMP_PARALLEL.
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001556 NEW_DATA is the variable that should be initialized from the argument
1557 of LOOP_FN. N_THREADS is the requested number of threads. Returns the
Richard Biener726a9892008-07-28 14:33:56 +00001558 basic block containing GIMPLE_OMP_PARALLEL tree. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001559
1560static basic_block
1561create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
1562 tree new_data, unsigned n_threads)
1563{
Richard Biener726a9892008-07-28 14:33:56 +00001564 gimple_stmt_iterator gsi;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001565 basic_block bb, paral_bb, for_bb, ex_bb;
Richard Biener726a9892008-07-28 14:33:56 +00001566 tree t, param, res;
1567 gimple stmt, for_stmt, phi, cond_stmt;
1568 tree cvar, cvar_init, initvar, cvar_next, cvar_base, type;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001569 edge exit, nexit, guard, end, e;
1570
Richard Biener726a9892008-07-28 14:33:56 +00001571 /* Prepare the GIMPLE_OMP_PARALLEL statement. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001572 bb = loop_preheader_edge (loop)->src;
1573 paral_bb = single_pred (bb);
Richard Biener726a9892008-07-28 14:33:56 +00001574 gsi = gsi_last_bb (paral_bb);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001575
Aldy Hernandezc2255bc2009-06-12 22:06:47 +00001576 t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_NUM_THREADS);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001577 OMP_CLAUSE_NUM_THREADS_EXPR (t)
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001578 = build_int_cst (integer_type_node, n_threads);
Richard Biener726a9892008-07-28 14:33:56 +00001579 stmt = gimple_build_omp_parallel (NULL, t, loop_fn, data);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001580
Richard Biener726a9892008-07-28 14:33:56 +00001581 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001582
1583 /* Initialize NEW_DATA. */
1584 if (data)
1585 {
Richard Biener726a9892008-07-28 14:33:56 +00001586 gsi = gsi_after_labels (bb);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001587
Richard Biener726a9892008-07-28 14:33:56 +00001588 param = make_ssa_name (DECL_ARGUMENTS (loop_fn), NULL);
1589 stmt = gimple_build_assign (param, build_fold_addr_expr (data));
1590 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1591 SSA_NAME_DEF_STMT (param) = stmt;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001592
Richard Biener726a9892008-07-28 14:33:56 +00001593 stmt = gimple_build_assign (new_data,
1594 fold_convert (TREE_TYPE (new_data), param));
1595 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1596 SSA_NAME_DEF_STMT (new_data) = stmt;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001597 }
1598
Richard Biener726a9892008-07-28 14:33:56 +00001599 /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_PARALLEL. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001600 bb = split_loop_exit_edge (single_dom_exit (loop));
Richard Biener726a9892008-07-28 14:33:56 +00001601 gsi = gsi_last_bb (bb);
1602 gsi_insert_after (&gsi, gimple_build_omp_return (false), GSI_NEW_STMT);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001603
Richard Biener726a9892008-07-28 14:33:56 +00001604 /* Extract data for GIMPLE_OMP_FOR. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001605 gcc_assert (loop->header == single_dom_exit (loop)->src);
Richard Biener726a9892008-07-28 14:33:56 +00001606 cond_stmt = last_stmt (loop->header);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001607
Richard Biener726a9892008-07-28 14:33:56 +00001608 cvar = gimple_cond_lhs (cond_stmt);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001609 cvar_base = SSA_NAME_VAR (cvar);
1610 phi = SSA_NAME_DEF_STMT (cvar);
1611 cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
Richard Biener726a9892008-07-28 14:33:56 +00001612 initvar = make_ssa_name (cvar_base, NULL);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001613 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, loop_preheader_edge (loop)),
1614 initvar);
1615 cvar_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
1616
Richard Biener726a9892008-07-28 14:33:56 +00001617 gsi = gsi_last_bb (loop->latch);
1618 gcc_assert (gsi_stmt (gsi) == SSA_NAME_DEF_STMT (cvar_next));
1619 gsi_remove (&gsi, true);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001620
1621 /* Prepare cfg. */
1622 for_bb = split_edge (loop_preheader_edge (loop));
1623 ex_bb = split_loop_exit_edge (single_dom_exit (loop));
1624 extract_true_false_edges_from_block (loop->header, &nexit, &exit);
1625 gcc_assert (exit == single_dom_exit (loop));
1626
1627 guard = make_edge (for_bb, ex_bb, 0);
1628 single_succ_edge (loop->latch)->flags = 0;
1629 end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
Richard Biener726a9892008-07-28 14:33:56 +00001630 for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001631 {
Richard Biener726a9892008-07-28 14:33:56 +00001632 phi = gsi_stmt (gsi);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001633 res = PHI_RESULT (phi);
Richard Biener726a9892008-07-28 14:33:56 +00001634 stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
1635 add_phi_arg (phi,
1636 PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)),
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001637 guard);
Richard Biener726a9892008-07-28 14:33:56 +00001638 add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)),
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001639 end);
1640 }
1641 e = redirect_edge_and_branch (exit, nexit->dest);
1642 PENDING_STMT (e) = NULL;
1643
Richard Biener726a9892008-07-28 14:33:56 +00001644 /* Emit GIMPLE_OMP_FOR. */
1645 gimple_cond_set_lhs (cond_stmt, cvar_base);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001646 type = TREE_TYPE (cvar);
Aldy Hernandezc2255bc2009-06-12 22:06:47 +00001647 t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_SCHEDULE);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001648 OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
1649
Richard Biener726a9892008-07-28 14:33:56 +00001650 for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
1651 gimple_omp_for_set_index (for_stmt, 0, initvar);
1652 gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
1653 gimple_omp_for_set_final (for_stmt, 0, gimple_cond_rhs (cond_stmt));
1654 gimple_omp_for_set_cond (for_stmt, 0, gimple_cond_code (cond_stmt));
1655 gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
1656 cvar_base,
1657 build_int_cst (type, 1)));
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001658
Richard Biener726a9892008-07-28 14:33:56 +00001659 gsi = gsi_last_bb (for_bb);
1660 gsi_insert_after (&gsi, for_stmt, GSI_NEW_STMT);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001661 SSA_NAME_DEF_STMT (initvar) = for_stmt;
1662
Richard Biener726a9892008-07-28 14:33:56 +00001663 /* Emit GIMPLE_OMP_CONTINUE. */
1664 gsi = gsi_last_bb (loop->latch);
1665 stmt = gimple_build_omp_continue (cvar_next, cvar);
1666 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1667 SSA_NAME_DEF_STMT (cvar_next) = stmt;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001668
Richard Biener726a9892008-07-28 14:33:56 +00001669 /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_FOR. */
1670 gsi = gsi_last_bb (ex_bb);
1671 gsi_insert_after (&gsi, gimple_build_omp_return (true), GSI_NEW_STMT);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001672
1673 return paral_bb;
1674}
1675
1676/* Generates code to execute the iterations of LOOP in N_THREADS threads in
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001677 parallel. NITER describes number of iterations of LOOP.
Ralf Wildenhuesfa10bee2008-06-06 05:42:00 +00001678 REDUCTION_LIST describes the reductions existent in the LOOP. */
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001679
1680static void
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001681gen_parallel_loop (struct loop *loop, htab_t reduction_list,
1682 unsigned n_threads, struct tree_niter_desc *niter)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001683{
1684 struct loop *nloop;
Jerry DeLisle93262362008-01-16 04:04:37 +00001685 loop_iterator li;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001686 tree many_iterations_cond, type, nit;
Richard Biener726a9892008-07-28 14:33:56 +00001687 tree arg_struct, new_arg_struct;
1688 gimple_seq stmts;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001689 basic_block parallel_head;
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001690 edge entry, exit;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001691 struct clsn_data clsn_data;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001692 unsigned prob;
1693
1694 /* From
1695
1696 ---------------------------------------------------------------------
1697 loop
1698 {
1699 IV = phi (INIT, IV + STEP)
1700 BODY1;
1701 if (COND)
1702 break;
1703 BODY2;
1704 }
1705 ---------------------------------------------------------------------
1706
1707 with # of iterations NITER (possibly with MAY_BE_ZERO assumption),
1708 we generate the following code:
1709
1710 ---------------------------------------------------------------------
1711
1712 if (MAY_BE_ZERO
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001713 || NITER < MIN_PER_THREAD * N_THREADS)
1714 goto original;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001715
1716 BODY1;
1717 store all local loop-invariant variables used in body of the loop to DATA.
Richard Biener726a9892008-07-28 14:33:56 +00001718 GIMPLE_OMP_PARALLEL (OMP_CLAUSE_NUM_THREADS (N_THREADS), LOOPFN, DATA);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001719 load the variables from DATA.
Richard Biener726a9892008-07-28 14:33:56 +00001720 GIMPLE_OMP_FOR (IV = INIT; COND; IV += STEP) (OMP_CLAUSE_SCHEDULE (static))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001721 BODY2;
1722 BODY1;
Richard Biener726a9892008-07-28 14:33:56 +00001723 GIMPLE_OMP_CONTINUE;
1724 GIMPLE_OMP_RETURN -- GIMPLE_OMP_FOR
1725 GIMPLE_OMP_RETURN -- GIMPLE_OMP_PARALLEL
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001726 goto end;
1727
1728 original:
1729 loop
1730 {
1731 IV = phi (INIT, IV + STEP)
1732 BODY1;
1733 if (COND)
1734 break;
1735 BODY2;
1736 }
1737
1738 end:
1739
1740 */
1741
1742 /* Create two versions of the loop -- in the old one, we know that the
1743 number of iterations is large enough, and we will transform it into the
1744 loop that will be split to loop_fn, the new one will be used for the
1745 remaining iterations. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001746
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001747 type = TREE_TYPE (niter->niter);
1748 nit = force_gimple_operand (unshare_expr (niter->niter), &stmts, true,
1749 NULL_TREE);
1750 if (stmts)
Richard Biener726a9892008-07-28 14:33:56 +00001751 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001752
1753 many_iterations_cond =
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001754 fold_build2 (GE_EXPR, boolean_type_node,
1755 nit, build_int_cst (type, MIN_PER_THREAD * n_threads));
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001756 many_iterations_cond
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001757 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
1758 invert_truthvalue (unshare_expr (niter->may_be_zero)),
1759 many_iterations_cond);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001760 many_iterations_cond
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001761 = force_gimple_operand (many_iterations_cond, &stmts, false, NULL_TREE);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001762 if (stmts)
Richard Biener726a9892008-07-28 14:33:56 +00001763 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001764 if (!is_gimple_condexpr (many_iterations_cond))
1765 {
1766 many_iterations_cond
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001767 = force_gimple_operand (many_iterations_cond, &stmts,
1768 true, NULL_TREE);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001769 if (stmts)
Richard Biener726a9892008-07-28 14:33:56 +00001770 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001771 }
1772
1773 initialize_original_copy_tables ();
1774
1775 /* We assume that the loop usually iterates a lot. */
1776 prob = 4 * REG_BR_PROB_BASE / 5;
1777 nloop = loop_version (loop, many_iterations_cond, NULL,
1778 prob, prob, REG_BR_PROB_BASE - prob, true);
1779 update_ssa (TODO_update_ssa);
1780 free_original_copy_tables ();
1781
1782 /* Base all the induction variables in LOOP on a single control one. */
Sebastian Pop7d4fba42009-03-03 03:47:22 +00001783 canonicalize_loop_ivs (loop, reduction_list, &nit);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001784
1785 /* Ensure that the exit condition is the first statement in the loop. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001786 transform_to_exit_first_loop (loop, reduction_list, nit);
1787
Ralf Wildenhuesfa10bee2008-06-06 05:42:00 +00001788 /* Generate initializations for reductions. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001789 if (htab_elements (reduction_list) > 0)
1790 htab_traverse (reduction_list, initialize_reductions, loop);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001791
1792 /* Eliminate the references to local variables from the loop. */
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001793 gcc_assert (single_exit (loop));
1794 entry = loop_preheader_edge (loop);
1795 exit = single_dom_exit (loop);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001796
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001797 eliminate_local_variables (entry, exit);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001798 /* In the old loop, move all variables non-local to the loop to a structure
1799 and back, and create separate decls for the variables used in loop. */
Antoniu Pop9f9f72a2008-04-24 16:23:51 +01001800 separate_decls_in_region (entry, exit, reduction_list, &arg_struct,
1801 &new_arg_struct, &clsn_data);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001802
1803 /* Create the parallel constructs. */
1804 parallel_head = create_parallel_loop (loop, create_loop_fn (), arg_struct,
1805 new_arg_struct, n_threads);
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001806 if (htab_elements (reduction_list) > 0)
1807 create_call_for_reduction (loop, reduction_list, &clsn_data);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001808
1809 scev_reset ();
1810
1811 /* Cancel the loop (it is simpler to do it here rather than to teach the
1812 expander to do it). */
1813 cancel_loop_tree (loop);
1814
Sebastian Pop92a6bdb2008-01-16 02:46:46 +00001815 /* Free loop bound estimations that could contain references to
1816 removed statements. */
1817 FOR_EACH_LOOP (li, loop, 0)
1818 free_numbers_of_iterations_estimates_loop (loop);
1819
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001820 /* Expand the parallel constructs. We do it directly here instead of running
1821 a separate expand_omp pass, since it is more efficient, and less likely to
1822 cause troubles with further analyses not being able to deal with the
1823 OMP trees. */
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001824
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001825 omp_expand_local (parallel_head);
1826}
1827
Sebastian Pop98572282008-05-20 19:17:12 +00001828/* Returns true when LOOP contains vector phi nodes. */
1829
1830static bool
Richard Biener726a9892008-07-28 14:33:56 +00001831loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED)
Sebastian Pop98572282008-05-20 19:17:12 +00001832{
1833 unsigned i;
1834 basic_block *bbs = get_loop_body_in_dom_order (loop);
Richard Biener726a9892008-07-28 14:33:56 +00001835 gimple_stmt_iterator gsi;
Sebastian Pop98572282008-05-20 19:17:12 +00001836 bool res = true;
Sebastian Pop98572282008-05-20 19:17:12 +00001837
1838 for (i = 0; i < loop->num_nodes; i++)
Richard Biener726a9892008-07-28 14:33:56 +00001839 for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
1840 if (TREE_CODE (TREE_TYPE (PHI_RESULT (gsi_stmt (gsi)))) == VECTOR_TYPE)
Sebastian Pop98572282008-05-20 19:17:12 +00001841 goto end;
1842
1843 res = false;
1844 end:
1845 free (bbs);
1846 return res;
1847}
1848
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001849/* Detect parallel loops and generate parallel code using libgomp
1850 primitives. Returns true if some loop was parallelized, false
1851 otherwise. */
1852
1853bool
1854parallelize_loops (void)
1855{
1856 unsigned n_threads = flag_tree_parallelize_loops;
1857 bool changed = false;
1858 struct loop *loop;
1859 struct tree_niter_desc niter_desc;
1860 loop_iterator li;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001861 htab_t reduction_list;
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001862
1863 /* Do not parallelize loops in the functions created by parallelization. */
1864 if (parallelized_function_p (cfun->decl))
1865 return false;
1866
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001867 reduction_list = htab_create (10, reduction_info_hash,
1868 reduction_info_eq, free);
Richard Biener726a9892008-07-28 14:33:56 +00001869 init_stmt_vec_info_vec ();
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001870
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001871 FOR_EACH_LOOP (li, loop, 0)
1872 {
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001873 htab_empty (reduction_list);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001874 if (/* Do not bother with loops in cold areas. */
Jan Hubickaefd8f752008-08-29 12:35:57 +02001875 optimize_loop_nest_for_size_p (loop)
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001876 /* Or loops that roll too little. */
1877 || expected_loop_iterations (loop) <= n_threads
1878 /* And of course, the loop must be parallelizable. */
1879 || !can_duplicate_loop_p (loop)
Sebastian Pop1d4af1e2008-01-16 02:44:04 +00001880 || loop_has_blocks_with_irreducible_flag (loop)
Sebastian Pop98572282008-05-20 19:17:12 +00001881 /* FIXME: the check for vector phi nodes could be removed. */
1882 || loop_has_vector_phi_nodes (loop)
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001883 || !loop_parallel_p (loop, reduction_list, &niter_desc))
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001884 continue;
1885
1886 changed = true;
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001887 gen_parallel_loop (loop, reduction_list, n_threads, &niter_desc);
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001888 verify_flow_info ();
1889 verify_dominators (CDI_DOMINATORS);
1890 verify_loop_structure ();
1891 verify_loop_closed_ssa ();
1892 }
1893
Richard Biener726a9892008-07-28 14:33:56 +00001894 free_stmt_vec_info_vec ();
Razya Ladelskya509ebb2007-10-29 11:05:04 +00001895 htab_delete (reduction_list);
Richard Guenther6b8ed142009-05-25 13:35:10 +00001896
1897 /* Parallelization will cause new function calls to be inserted through
1898 which local variables will escape. Reset the points-to solutions
1899 for ESCAPED and CALLUSED. */
1900 if (changed)
1901 {
1902 pt_solution_reset (&cfun->gimple_df->escaped);
1903 pt_solution_reset (&cfun->gimple_df->callused);
1904 }
1905
Zdenek Dvorak5f40b3c2007-09-15 23:53:45 +02001906 return changed;
1907}
1908
1909#include "gt-tree-parloops.h"