1 /* OpenMP directive translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "coretypes.h"
27 #include "tree-gimple.h"
33 #include "trans-stmt.h"
34 #include "trans-types.h"
35 #include "trans-array.h"
36 #include "trans-const.h"
40 /* True if OpenMP should privatize what this DECL points to rather
41 than the DECL itself. */
44 gfc_omp_privatize_by_reference (tree decl
)
46 tree type
= TREE_TYPE (decl
);
48 if (TREE_CODE (type
) == REFERENCE_TYPE
)
51 if (TREE_CODE (type
) == POINTER_TYPE
)
53 /* POINTER/ALLOCATABLE have aggregate types, all user variables
54 that have POINTER_TYPE type are supposed to be privatized
56 if (!DECL_ARTIFICIAL (decl
))
59 /* Some arrays are expanded as DECL_ARTIFICIAL pointers
61 if (DECL_LANG_SPECIFIC (decl
)
62 && GFC_DECL_SAVED_DESCRIPTOR (decl
))
69 /* True if OpenMP sharing attribute of DECL is predetermined. */
71 enum omp_clause_default_kind
72 gfc_omp_predetermined_sharing (tree decl
)
74 if (DECL_ARTIFICIAL (decl
) && ! GFC_DECL_RESULT (decl
))
75 return OMP_CLAUSE_DEFAULT_SHARED
;
77 /* Cray pointees shouldn't be listed in any clauses and should be
78 gimplified to dereference of the corresponding Cray pointer.
79 Make them all private, so that they are emitted in the debug
81 if (GFC_DECL_CRAY_POINTEE (decl
))
82 return OMP_CLAUSE_DEFAULT_PRIVATE
;
84 /* COMMON and EQUIVALENCE decls are shared. They
85 are only referenced through DECL_VALUE_EXPR of the variables
86 contained in them. If those are privatized, they will not be
87 gimplified to the COMMON or EQUIVALENCE decls. */
88 if (GFC_DECL_COMMON_OR_EQUIV (decl
) && ! DECL_HAS_VALUE_EXPR_P (decl
))
89 return OMP_CLAUSE_DEFAULT_SHARED
;
91 if (GFC_DECL_RESULT (decl
) && ! DECL_HAS_VALUE_EXPR_P (decl
))
92 return OMP_CLAUSE_DEFAULT_SHARED
;
94 return OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
98 /* Return code to initialize DECL with its default constructor, or
99 NULL if there's nothing to do. */
102 gfc_omp_clause_default_ctor (tree clause ATTRIBUTE_UNUSED
, tree decl
)
104 tree type
= TREE_TYPE (decl
);
107 if (! GFC_DESCRIPTOR_TYPE_P (type
))
110 /* Allocatable arrays in PRIVATE clauses need to be set to
111 "not currently allocated" allocation status. */
112 gfc_init_block (&block
);
114 gfc_conv_descriptor_data_set_tuples (&block
, decl
, null_pointer_node
);
116 return gfc_finish_block (&block
);
120 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
121 disregarded in OpenMP construct, because it is going to be
122 remapped during OpenMP lowering. SHARED is true if DECL
123 is going to be shared, false if it is going to be privatized. */
126 gfc_omp_disregard_value_expr (tree decl
, bool shared
)
128 if (GFC_DECL_COMMON_OR_EQUIV (decl
)
129 && DECL_HAS_VALUE_EXPR_P (decl
))
131 tree value
= DECL_VALUE_EXPR (decl
);
133 if (TREE_CODE (value
) == COMPONENT_REF
134 && TREE_CODE (TREE_OPERAND (value
, 0)) == VAR_DECL
135 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value
, 0)))
137 /* If variable in COMMON or EQUIVALENCE is privatized, return
138 true, as just that variable is supposed to be privatized,
139 not the whole COMMON or whole EQUIVALENCE.
140 For shared variables in COMMON or EQUIVALENCE, let them be
141 gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
142 from the same COMMON or EQUIVALENCE just one sharing of the
143 whole COMMON or EQUIVALENCE is enough. */
148 if (GFC_DECL_RESULT (decl
) && DECL_HAS_VALUE_EXPR_P (decl
))
154 /* Return true if DECL that is shared iff SHARED is true should
155 be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
159 gfc_omp_private_debug_clause (tree decl
, bool shared
)
161 if (GFC_DECL_CRAY_POINTEE (decl
))
164 if (GFC_DECL_COMMON_OR_EQUIV (decl
)
165 && DECL_HAS_VALUE_EXPR_P (decl
))
167 tree value
= DECL_VALUE_EXPR (decl
);
169 if (TREE_CODE (value
) == COMPONENT_REF
170 && TREE_CODE (TREE_OPERAND (value
, 0)) == VAR_DECL
171 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value
, 0)))
178 /* Register language specific type size variables as potentially OpenMP
179 firstprivate variables. */
182 gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx
*ctx
, tree type
)
184 if (GFC_ARRAY_TYPE_P (type
) || GFC_DESCRIPTOR_TYPE_P (type
))
188 gcc_assert (TYPE_LANG_SPECIFIC (type
) != NULL
);
189 for (r
= 0; r
< GFC_TYPE_ARRAY_RANK (type
); r
++)
191 omp_firstprivatize_variable (ctx
, GFC_TYPE_ARRAY_LBOUND (type
, r
));
192 omp_firstprivatize_variable (ctx
, GFC_TYPE_ARRAY_UBOUND (type
, r
));
193 omp_firstprivatize_variable (ctx
, GFC_TYPE_ARRAY_STRIDE (type
, r
));
195 omp_firstprivatize_variable (ctx
, GFC_TYPE_ARRAY_SIZE (type
));
196 omp_firstprivatize_variable (ctx
, GFC_TYPE_ARRAY_OFFSET (type
));
202 gfc_trans_add_clause (tree node
, tree tail
)
204 OMP_CLAUSE_CHAIN (node
) = tail
;
209 gfc_trans_omp_variable (gfc_symbol
*sym
)
211 tree t
= gfc_get_symbol_decl (sym
);
215 bool alternate_entry
;
218 return_value
= sym
->attr
.function
&& sym
->result
== sym
;
219 alternate_entry
= sym
->attr
.function
&& sym
->attr
.entry
220 && sym
->result
== sym
;
221 entry_master
= sym
->attr
.result
222 && sym
->ns
->proc_name
->attr
.entry_master
223 && !gfc_return_by_reference (sym
->ns
->proc_name
);
224 parent_decl
= DECL_CONTEXT (current_function_decl
);
226 if ((t
== parent_decl
&& return_value
)
227 || (sym
->ns
&& sym
->ns
->proc_name
228 && sym
->ns
->proc_name
->backend_decl
== parent_decl
229 && (alternate_entry
|| entry_master
)))
234 /* Special case for assigning the return value of a function.
235 Self recursive functions must have an explicit return value. */
236 if (return_value
&& (t
== current_function_decl
|| parent_flag
))
237 t
= gfc_get_fake_result_decl (sym
, parent_flag
);
239 /* Similarly for alternate entry points. */
240 else if (alternate_entry
241 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
244 gfc_entry_list
*el
= NULL
;
246 for (el
= sym
->ns
->entries
; el
; el
= el
->next
)
249 t
= gfc_get_fake_result_decl (sym
, parent_flag
);
254 else if (entry_master
255 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
257 t
= gfc_get_fake_result_decl (sym
, parent_flag
);
263 gfc_trans_omp_variable_list (enum omp_clause_code code
, gfc_namelist
*namelist
,
266 for (; namelist
!= NULL
; namelist
= namelist
->next
)
267 if (namelist
->sym
->attr
.referenced
)
269 tree t
= gfc_trans_omp_variable (namelist
->sym
);
270 if (t
!= error_mark_node
)
272 tree node
= build_omp_clause (code
);
273 OMP_CLAUSE_DECL (node
) = t
;
274 list
= gfc_trans_add_clause (node
, list
);
281 gfc_trans_omp_array_reduction (tree c
, gfc_symbol
*sym
, locus where
)
283 gfc_symtree
*root1
= NULL
, *root2
= NULL
, *root3
= NULL
, *root4
= NULL
;
284 gfc_symtree
*symtree1
, *symtree2
, *symtree3
, *symtree4
= NULL
;
285 gfc_symbol init_val_sym
, outer_sym
, intrinsic_sym
;
286 gfc_expr
*e1
, *e2
, *e3
, *e4
;
288 tree decl
, backend_decl
, stmt
;
289 locus old_loc
= gfc_current_locus
;
293 decl
= OMP_CLAUSE_DECL (c
);
294 gfc_current_locus
= where
;
296 /* Create a fake symbol for init value. */
297 memset (&init_val_sym
, 0, sizeof (init_val_sym
));
298 init_val_sym
.ns
= sym
->ns
;
299 init_val_sym
.name
= sym
->name
;
300 init_val_sym
.ts
= sym
->ts
;
301 init_val_sym
.attr
.referenced
= 1;
302 init_val_sym
.declared_at
= where
;
303 init_val_sym
.attr
.flavor
= FL_VARIABLE
;
304 backend_decl
= omp_reduction_init (c
, gfc_sym_type (&init_val_sym
));
305 init_val_sym
.backend_decl
= backend_decl
;
307 /* Create a fake symbol for the outer array reference. */
309 outer_sym
.as
= gfc_copy_array_spec (sym
->as
);
310 outer_sym
.attr
.dummy
= 0;
311 outer_sym
.attr
.result
= 0;
312 outer_sym
.attr
.flavor
= FL_VARIABLE
;
313 outer_sym
.backend_decl
= create_tmp_var_raw (TREE_TYPE (decl
), NULL
);
315 /* Create fake symtrees for it. */
316 symtree1
= gfc_new_symtree (&root1
, sym
->name
);
317 symtree1
->n
.sym
= sym
;
318 gcc_assert (symtree1
== root1
);
320 symtree2
= gfc_new_symtree (&root2
, sym
->name
);
321 symtree2
->n
.sym
= &init_val_sym
;
322 gcc_assert (symtree2
== root2
);
324 symtree3
= gfc_new_symtree (&root3
, sym
->name
);
325 symtree3
->n
.sym
= &outer_sym
;
326 gcc_assert (symtree3
== root3
);
328 /* Create expressions. */
329 e1
= gfc_get_expr ();
330 e1
->expr_type
= EXPR_VARIABLE
;
332 e1
->symtree
= symtree1
;
334 e1
->ref
= ref
= gfc_get_ref ();
335 ref
->u
.ar
.where
= where
;
336 ref
->u
.ar
.as
= sym
->as
;
337 ref
->u
.ar
.type
= AR_FULL
;
339 t
= gfc_resolve_expr (e1
);
340 gcc_assert (t
== SUCCESS
);
342 e2
= gfc_get_expr ();
343 e2
->expr_type
= EXPR_VARIABLE
;
345 e2
->symtree
= symtree2
;
347 t
= gfc_resolve_expr (e2
);
348 gcc_assert (t
== SUCCESS
);
350 e3
= gfc_copy_expr (e1
);
351 e3
->symtree
= symtree3
;
352 t
= gfc_resolve_expr (e3
);
353 gcc_assert (t
== SUCCESS
);
356 switch (OMP_CLAUSE_REDUCTION_CODE (c
))
360 e4
= gfc_add (e3
, e1
);
363 e4
= gfc_multiply (e3
, e1
);
365 case TRUTH_ANDIF_EXPR
:
366 e4
= gfc_and (e3
, e1
);
368 case TRUTH_ORIF_EXPR
:
369 e4
= gfc_or (e3
, e1
);
372 e4
= gfc_eqv (e3
, e1
);
375 e4
= gfc_neqv (e3
, e1
);
397 memset (&intrinsic_sym
, 0, sizeof (intrinsic_sym
));
398 intrinsic_sym
.ns
= sym
->ns
;
399 intrinsic_sym
.name
= iname
;
400 intrinsic_sym
.ts
= sym
->ts
;
401 intrinsic_sym
.attr
.referenced
= 1;
402 intrinsic_sym
.attr
.intrinsic
= 1;
403 intrinsic_sym
.attr
.function
= 1;
404 intrinsic_sym
.result
= &intrinsic_sym
;
405 intrinsic_sym
.declared_at
= where
;
407 symtree4
= gfc_new_symtree (&root4
, iname
);
408 symtree4
->n
.sym
= &intrinsic_sym
;
409 gcc_assert (symtree4
== root4
);
411 e4
= gfc_get_expr ();
412 e4
->expr_type
= EXPR_FUNCTION
;
414 e4
->symtree
= symtree4
;
415 e4
->value
.function
.isym
= gfc_find_function (iname
);
416 e4
->value
.function
.actual
= gfc_get_actual_arglist ();
417 e4
->value
.function
.actual
->expr
= e3
;
418 e4
->value
.function
.actual
->next
= gfc_get_actual_arglist ();
419 e4
->value
.function
.actual
->next
->expr
= e1
;
421 /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
422 e1
= gfc_copy_expr (e1
);
423 e3
= gfc_copy_expr (e3
);
424 t
= gfc_resolve_expr (e4
);
425 gcc_assert (t
== SUCCESS
);
427 /* Create the init statement list. */
429 stmt
= gfc_trans_assignment (e1
, e2
, false);
430 if (TREE_CODE (stmt
) != BIND_EXPR
)
431 stmt
= build3_v (BIND_EXPR
, NULL
, stmt
, poplevel (1, 0, 0));
434 OMP_CLAUSE_REDUCTION_INIT (c
) = stmt
;
436 /* Create the merge statement list. */
438 stmt
= gfc_trans_assignment (e3
, e4
, false);
439 if (TREE_CODE (stmt
) != BIND_EXPR
)
440 stmt
= build3_v (BIND_EXPR
, NULL
, stmt
, poplevel (1, 0, 0));
443 OMP_CLAUSE_REDUCTION_MERGE (c
) = stmt
;
445 /* And stick the placeholder VAR_DECL into the clause as well. */
446 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
) = outer_sym
.backend_decl
;
448 gfc_current_locus
= old_loc
;
459 gfc_free_array_spec (outer_sym
.as
);
463 gfc_trans_omp_reduction_list (gfc_namelist
*namelist
, tree list
,
464 enum tree_code reduction_code
, locus where
)
466 for (; namelist
!= NULL
; namelist
= namelist
->next
)
467 if (namelist
->sym
->attr
.referenced
)
469 tree t
= gfc_trans_omp_variable (namelist
->sym
);
470 if (t
!= error_mark_node
)
472 tree node
= build_omp_clause (OMP_CLAUSE_REDUCTION
);
473 OMP_CLAUSE_DECL (node
) = t
;
474 OMP_CLAUSE_REDUCTION_CODE (node
) = reduction_code
;
475 if (namelist
->sym
->attr
.dimension
)
476 gfc_trans_omp_array_reduction (node
, namelist
->sym
, where
);
477 list
= gfc_trans_add_clause (node
, list
);
484 gfc_trans_omp_clauses (stmtblock_t
*block
, gfc_omp_clauses
*clauses
,
487 tree omp_clauses
= NULL_TREE
, chunk_size
, c
, old_clauses
;
489 enum omp_clause_code clause_code
;
495 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
497 gfc_namelist
*n
= clauses
->lists
[list
];
501 if (list
>= OMP_LIST_REDUCTION_FIRST
502 && list
<= OMP_LIST_REDUCTION_LAST
)
504 enum tree_code reduction_code
;
508 reduction_code
= PLUS_EXPR
;
511 reduction_code
= MULT_EXPR
;
514 reduction_code
= MINUS_EXPR
;
517 reduction_code
= TRUTH_ANDIF_EXPR
;
520 reduction_code
= TRUTH_ORIF_EXPR
;
523 reduction_code
= EQ_EXPR
;
526 reduction_code
= NE_EXPR
;
529 reduction_code
= MAX_EXPR
;
532 reduction_code
= MIN_EXPR
;
535 reduction_code
= BIT_AND_EXPR
;
538 reduction_code
= BIT_IOR_EXPR
;
541 reduction_code
= BIT_XOR_EXPR
;
546 old_clauses
= omp_clauses
;
548 = gfc_trans_omp_reduction_list (n
, omp_clauses
, reduction_code
,
554 case OMP_LIST_PRIVATE
:
555 clause_code
= OMP_CLAUSE_PRIVATE
;
557 case OMP_LIST_SHARED
:
558 clause_code
= OMP_CLAUSE_SHARED
;
560 case OMP_LIST_FIRSTPRIVATE
:
561 clause_code
= OMP_CLAUSE_FIRSTPRIVATE
;
563 case OMP_LIST_LASTPRIVATE
:
564 clause_code
= OMP_CLAUSE_LASTPRIVATE
;
566 case OMP_LIST_COPYIN
:
567 clause_code
= OMP_CLAUSE_COPYIN
;
569 case OMP_LIST_COPYPRIVATE
:
570 clause_code
= OMP_CLAUSE_COPYPRIVATE
;
574 = gfc_trans_omp_variable_list (clause_code
, n
, omp_clauses
);
581 if (clauses
->if_expr
)
585 gfc_init_se (&se
, NULL
);
586 gfc_conv_expr (&se
, clauses
->if_expr
);
587 gfc_add_block_to_block (block
, &se
.pre
);
588 if_var
= gfc_evaluate_now (se
.expr
, block
);
589 gfc_add_block_to_block (block
, &se
.post
);
591 c
= build_omp_clause (OMP_CLAUSE_IF
);
592 OMP_CLAUSE_IF_EXPR (c
) = if_var
;
593 omp_clauses
= gfc_trans_add_clause (c
, omp_clauses
);
596 if (clauses
->num_threads
)
600 gfc_init_se (&se
, NULL
);
601 gfc_conv_expr (&se
, clauses
->num_threads
);
602 gfc_add_block_to_block (block
, &se
.pre
);
603 num_threads
= gfc_evaluate_now (se
.expr
, block
);
604 gfc_add_block_to_block (block
, &se
.post
);
606 c
= build_omp_clause (OMP_CLAUSE_NUM_THREADS
);
607 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = num_threads
;
608 omp_clauses
= gfc_trans_add_clause (c
, omp_clauses
);
611 chunk_size
= NULL_TREE
;
612 if (clauses
->chunk_size
)
614 gfc_init_se (&se
, NULL
);
615 gfc_conv_expr (&se
, clauses
->chunk_size
);
616 gfc_add_block_to_block (block
, &se
.pre
);
617 chunk_size
= gfc_evaluate_now (se
.expr
, block
);
618 gfc_add_block_to_block (block
, &se
.post
);
621 if (clauses
->sched_kind
!= OMP_SCHED_NONE
)
623 c
= build_omp_clause (OMP_CLAUSE_SCHEDULE
);
624 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = chunk_size
;
625 switch (clauses
->sched_kind
)
627 case OMP_SCHED_STATIC
:
628 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
630 case OMP_SCHED_DYNAMIC
:
631 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
633 case OMP_SCHED_GUIDED
:
634 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
636 case OMP_SCHED_RUNTIME
:
637 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
642 omp_clauses
= gfc_trans_add_clause (c
, omp_clauses
);
645 if (clauses
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
647 c
= build_omp_clause (OMP_CLAUSE_DEFAULT
);
648 switch (clauses
->default_sharing
)
650 case OMP_DEFAULT_NONE
:
651 OMP_CLAUSE_DEFAULT_KIND (c
) = OMP_CLAUSE_DEFAULT_NONE
;
653 case OMP_DEFAULT_SHARED
:
654 OMP_CLAUSE_DEFAULT_KIND (c
) = OMP_CLAUSE_DEFAULT_SHARED
;
656 case OMP_DEFAULT_PRIVATE
:
657 OMP_CLAUSE_DEFAULT_KIND (c
) = OMP_CLAUSE_DEFAULT_PRIVATE
;
662 omp_clauses
= gfc_trans_add_clause (c
, omp_clauses
);
667 c
= build_omp_clause (OMP_CLAUSE_NOWAIT
);
668 omp_clauses
= gfc_trans_add_clause (c
, omp_clauses
);
671 if (clauses
->ordered
)
673 c
= build_omp_clause (OMP_CLAUSE_ORDERED
);
674 omp_clauses
= gfc_trans_add_clause (c
, omp_clauses
);
680 /* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
683 gfc_trans_omp_code (gfc_code
*code
, bool force_empty
)
688 stmt
= gfc_trans_code (code
);
689 if (TREE_CODE (stmt
) != BIND_EXPR
)
691 if (!IS_EMPTY_STMT (stmt
) || force_empty
)
693 tree block
= poplevel (1, 0, 0);
694 stmt
= build3_v (BIND_EXPR
, NULL
, stmt
, block
);
705 static tree
gfc_trans_omp_sections (gfc_code
*, gfc_omp_clauses
*);
706 static tree
gfc_trans_omp_workshare (gfc_code
*, gfc_omp_clauses
*);
709 gfc_trans_omp_atomic (gfc_code
*code
)
716 tree lhsaddr
, type
, rhs
, x
;
717 enum tree_code op
= ERROR_MARK
;
718 bool var_on_left
= false;
720 code
= code
->block
->next
;
721 gcc_assert (code
->op
== EXEC_ASSIGN
);
722 gcc_assert (code
->next
== NULL
);
723 var
= code
->expr
->symtree
->n
.sym
;
725 gfc_init_se (&lse
, NULL
);
726 gfc_init_se (&rse
, NULL
);
727 gfc_start_block (&block
);
729 gfc_conv_expr (&lse
, code
->expr
);
730 gfc_add_block_to_block (&block
, &lse
.pre
);
731 type
= TREE_TYPE (lse
.expr
);
732 lhsaddr
= gfc_build_addr_expr (NULL
, lse
.expr
);
735 if (expr2
->expr_type
== EXPR_FUNCTION
736 && expr2
->value
.function
.isym
->generic_id
== GFC_ISYM_CONVERSION
)
737 expr2
= expr2
->value
.function
.actual
->expr
;
739 if (expr2
->expr_type
== EXPR_OP
)
742 switch (expr2
->value
.op
.operator)
747 case INTRINSIC_TIMES
:
750 case INTRINSIC_MINUS
:
753 case INTRINSIC_DIVIDE
:
754 if (expr2
->ts
.type
== BT_INTEGER
)
760 op
= TRUTH_ANDIF_EXPR
;
763 op
= TRUTH_ORIF_EXPR
;
774 e
= expr2
->value
.op
.op1
;
775 if (e
->expr_type
== EXPR_FUNCTION
776 && e
->value
.function
.isym
->generic_id
== GFC_ISYM_CONVERSION
)
777 e
= e
->value
.function
.actual
->expr
;
778 if (e
->expr_type
== EXPR_VARIABLE
779 && e
->symtree
!= NULL
780 && e
->symtree
->n
.sym
== var
)
782 expr2
= expr2
->value
.op
.op2
;
787 e
= expr2
->value
.op
.op2
;
788 if (e
->expr_type
== EXPR_FUNCTION
789 && e
->value
.function
.isym
->generic_id
== GFC_ISYM_CONVERSION
)
790 e
= e
->value
.function
.actual
->expr
;
791 gcc_assert (e
->expr_type
== EXPR_VARIABLE
792 && e
->symtree
!= NULL
793 && e
->symtree
->n
.sym
== var
);
794 expr2
= expr2
->value
.op
.op1
;
797 gfc_conv_expr (&rse
, expr2
);
798 gfc_add_block_to_block (&block
, &rse
.pre
);
802 gcc_assert (expr2
->expr_type
== EXPR_FUNCTION
);
803 switch (expr2
->value
.function
.isym
->generic_id
)
823 e
= expr2
->value
.function
.actual
->expr
;
824 gcc_assert (e
->expr_type
== EXPR_VARIABLE
825 && e
->symtree
!= NULL
826 && e
->symtree
->n
.sym
== var
);
828 gfc_conv_expr (&rse
, expr2
->value
.function
.actual
->next
->expr
);
829 gfc_add_block_to_block (&block
, &rse
.pre
);
830 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
832 tree accum
= gfc_create_var (TREE_TYPE (rse
.expr
), NULL
);
833 gfc_actual_arglist
*arg
;
835 gfc_add_modify_stmt (&block
, accum
, rse
.expr
);
836 for (arg
= expr2
->value
.function
.actual
->next
->next
; arg
;
839 gfc_init_block (&rse
.pre
);
840 gfc_conv_expr (&rse
, arg
->expr
);
841 gfc_add_block_to_block (&block
, &rse
.pre
);
842 x
= fold_build2 (op
, TREE_TYPE (accum
), accum
, rse
.expr
);
843 gfc_add_modify_stmt (&block
, accum
, x
);
849 expr2
= expr2
->value
.function
.actual
->next
->expr
;
852 lhsaddr
= save_expr (lhsaddr
);
853 rhs
= gfc_evaluate_now (rse
.expr
, &block
);
854 x
= convert (TREE_TYPE (rhs
), build_fold_indirect_ref (lhsaddr
));
857 x
= fold_build2 (op
, TREE_TYPE (rhs
), x
, rhs
);
859 x
= fold_build2 (op
, TREE_TYPE (rhs
), rhs
, x
);
861 if (TREE_CODE (TREE_TYPE (rhs
)) == COMPLEX_TYPE
862 && TREE_CODE (type
) != COMPLEX_TYPE
)
863 x
= build1 (REALPART_EXPR
, TREE_TYPE (TREE_TYPE (rhs
)), x
);
865 x
= build2_v (OMP_ATOMIC
, lhsaddr
, convert (type
, x
));
866 gfc_add_expr_to_block (&block
, x
);
868 gfc_add_block_to_block (&block
, &lse
.pre
);
869 gfc_add_block_to_block (&block
, &rse
.pre
);
871 return gfc_finish_block (&block
);
875 gfc_trans_omp_barrier (void)
877 tree decl
= built_in_decls
[BUILT_IN_GOMP_BARRIER
];
878 return build_function_call_expr (decl
, NULL
);
882 gfc_trans_omp_critical (gfc_code
*code
)
884 tree name
= NULL_TREE
, stmt
;
885 if (code
->ext
.omp_name
!= NULL
)
886 name
= get_identifier (code
->ext
.omp_name
);
887 stmt
= gfc_trans_code (code
->block
->next
);
888 return build2_v (OMP_CRITICAL
, stmt
, name
);
892 gfc_trans_omp_do (gfc_code
*code
, stmtblock_t
*pblock
,
893 gfc_omp_clauses
*do_clauses
)
896 tree dovar
, stmt
, from
, to
, step
, type
, init
, cond
, incr
;
897 tree count
= NULL_TREE
, cycle_label
, tmp
, omp_clauses
;
901 bool dovar_found
= false;
902 gfc_omp_clauses
*clauses
= code
->ext
.omp_clauses
;
904 code
= code
->block
->next
;
905 gcc_assert (code
->op
== EXEC_DO
);
909 gfc_start_block (&block
);
913 omp_clauses
= gfc_trans_omp_clauses (pblock
, do_clauses
, code
->loc
);
917 for (n
= clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
!= NULL
; n
= n
->next
)
918 if (code
->ext
.iterator
->var
->symtree
->n
.sym
== n
->sym
)
921 for (n
= clauses
->lists
[OMP_LIST_PRIVATE
]; n
!= NULL
; n
= n
->next
)
922 if (code
->ext
.iterator
->var
->symtree
->n
.sym
== n
->sym
)
928 /* Evaluate all the expressions in the iterator. */
929 gfc_init_se (&se
, NULL
);
930 gfc_conv_expr_lhs (&se
, code
->ext
.iterator
->var
);
931 gfc_add_block_to_block (pblock
, &se
.pre
);
933 type
= TREE_TYPE (dovar
);
934 gcc_assert (TREE_CODE (type
) == INTEGER_TYPE
);
936 gfc_init_se (&se
, NULL
);
937 gfc_conv_expr_val (&se
, code
->ext
.iterator
->start
);
938 gfc_add_block_to_block (pblock
, &se
.pre
);
939 from
= gfc_evaluate_now (se
.expr
, pblock
);
941 gfc_init_se (&se
, NULL
);
942 gfc_conv_expr_val (&se
, code
->ext
.iterator
->end
);
943 gfc_add_block_to_block (pblock
, &se
.pre
);
944 to
= gfc_evaluate_now (se
.expr
, pblock
);
946 gfc_init_se (&se
, NULL
);
947 gfc_conv_expr_val (&se
, code
->ext
.iterator
->step
);
948 gfc_add_block_to_block (pblock
, &se
.pre
);
949 step
= gfc_evaluate_now (se
.expr
, pblock
);
951 /* Special case simple loops. */
952 if (integer_onep (step
))
954 else if (tree_int_cst_equal (step
, integer_minus_one_node
))
960 init
= build2_v (GIMPLE_MODIFY_STMT
, dovar
, from
);
961 cond
= build2 (simple
> 0 ? LE_EXPR
: GE_EXPR
, boolean_type_node
,
963 incr
= fold_build2 (PLUS_EXPR
, type
, dovar
, step
);
964 incr
= fold_build2 (GIMPLE_MODIFY_STMT
, type
, dovar
, incr
);
965 if (pblock
!= &block
)
968 gfc_start_block (&block
);
970 gfc_start_block (&body
);
974 /* STEP is not 1 or -1. Use:
975 for (count = 0; count < (to + step - from) / step; count++)
977 dovar = from + count * step;
981 tmp
= fold_build2 (MINUS_EXPR
, type
, step
, from
);
982 tmp
= fold_build2 (PLUS_EXPR
, type
, to
, tmp
);
983 tmp
= fold_build2 (TRUNC_DIV_EXPR
, type
, tmp
, step
);
984 tmp
= gfc_evaluate_now (tmp
, pblock
);
985 count
= gfc_create_var (type
, "count");
986 init
= build2_v (GIMPLE_MODIFY_STMT
, count
, build_int_cst (type
, 0));
987 cond
= build2 (LT_EXPR
, boolean_type_node
, count
, tmp
);
988 incr
= fold_build2 (PLUS_EXPR
, type
, count
, build_int_cst (type
, 1));
989 incr
= fold_build2 (GIMPLE_MODIFY_STMT
, type
, count
, incr
);
991 if (pblock
!= &block
)
994 gfc_start_block (&block
);
996 gfc_start_block (&body
);
998 /* Initialize DOVAR. */
999 tmp
= fold_build2 (MULT_EXPR
, type
, count
, step
);
1000 tmp
= build2 (PLUS_EXPR
, type
, from
, tmp
);
1001 gfc_add_modify_stmt (&body
, dovar
, tmp
);
1006 tmp
= build_omp_clause (OMP_CLAUSE_PRIVATE
);
1007 OMP_CLAUSE_DECL (tmp
) = dovar
;
1008 omp_clauses
= gfc_trans_add_clause (tmp
, omp_clauses
);
1012 tmp
= build_omp_clause (OMP_CLAUSE_PRIVATE
);
1013 OMP_CLAUSE_DECL (tmp
) = count
;
1014 omp_clauses
= gfc_trans_add_clause (tmp
, omp_clauses
);
1017 /* Cycle statement is implemented with a goto. Exit statement must not be
1018 present for this loop. */
1019 cycle_label
= gfc_build_label_decl (NULL_TREE
);
1021 /* Put these labels where they can be found later. We put the
1022 labels in a TREE_LIST node (because TREE_CHAIN is already
1023 used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
1024 label in TREE_VALUE (backend_decl). */
1026 code
->block
->backend_decl
= tree_cons (cycle_label
, NULL
, NULL
);
1028 /* Main loop body. */
1029 tmp
= gfc_trans_omp_code (code
->block
->next
, true);
1030 gfc_add_expr_to_block (&body
, tmp
);
1032 /* Label for cycle statements (if needed). */
1033 if (TREE_USED (cycle_label
))
1035 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
1036 gfc_add_expr_to_block (&body
, tmp
);
1039 /* End of loop body. */
1040 stmt
= make_node (OMP_FOR
);
1042 TREE_TYPE (stmt
) = void_type_node
;
1043 OMP_FOR_BODY (stmt
) = gfc_finish_block (&body
);
1044 OMP_FOR_CLAUSES (stmt
) = omp_clauses
;
1045 OMP_FOR_INIT (stmt
) = init
;
1046 OMP_FOR_COND (stmt
) = cond
;
1047 OMP_FOR_INCR (stmt
) = incr
;
1048 gfc_add_expr_to_block (&block
, stmt
);
1050 return gfc_finish_block (&block
);
1054 gfc_trans_omp_flush (void)
1056 tree decl
= built_in_decls
[BUILT_IN_SYNCHRONIZE
];
1057 return build_function_call_expr (decl
, NULL
);
1061 gfc_trans_omp_master (gfc_code
*code
)
1063 tree stmt
= gfc_trans_code (code
->block
->next
);
1064 if (IS_EMPTY_STMT (stmt
))
1066 return build1_v (OMP_MASTER
, stmt
);
1070 gfc_trans_omp_ordered (gfc_code
*code
)
1072 return build1_v (OMP_ORDERED
, gfc_trans_code (code
->block
->next
));
1076 gfc_trans_omp_parallel (gfc_code
*code
)
1079 tree stmt
, omp_clauses
;
1081 gfc_start_block (&block
);
1082 omp_clauses
= gfc_trans_omp_clauses (&block
, code
->ext
.omp_clauses
,
1084 stmt
= gfc_trans_omp_code (code
->block
->next
, true);
1085 stmt
= build4_v (OMP_PARALLEL
, stmt
, omp_clauses
, NULL
, NULL
);
1086 gfc_add_expr_to_block (&block
, stmt
);
1087 return gfc_finish_block (&block
);
1091 gfc_trans_omp_parallel_do (gfc_code
*code
)
1093 stmtblock_t block
, *pblock
= NULL
;
1094 gfc_omp_clauses parallel_clauses
, do_clauses
;
1095 tree stmt
, omp_clauses
= NULL_TREE
;
1097 gfc_start_block (&block
);
1099 memset (&do_clauses
, 0, sizeof (do_clauses
));
1100 if (code
->ext
.omp_clauses
!= NULL
)
1102 memcpy (¶llel_clauses
, code
->ext
.omp_clauses
,
1103 sizeof (parallel_clauses
));
1104 do_clauses
.sched_kind
= parallel_clauses
.sched_kind
;
1105 do_clauses
.chunk_size
= parallel_clauses
.chunk_size
;
1106 do_clauses
.ordered
= parallel_clauses
.ordered
;
1107 parallel_clauses
.sched_kind
= OMP_SCHED_NONE
;
1108 parallel_clauses
.chunk_size
= NULL
;
1109 parallel_clauses
.ordered
= false;
1110 omp_clauses
= gfc_trans_omp_clauses (&block
, ¶llel_clauses
,
1113 do_clauses
.nowait
= true;
1114 if (!do_clauses
.ordered
&& do_clauses
.sched_kind
!= OMP_SCHED_STATIC
)
1118 stmt
= gfc_trans_omp_do (code
, pblock
, &do_clauses
);
1119 if (TREE_CODE (stmt
) != BIND_EXPR
)
1120 stmt
= build3_v (BIND_EXPR
, NULL
, stmt
, poplevel (1, 0, 0));
1123 stmt
= build4_v (OMP_PARALLEL
, stmt
, omp_clauses
, NULL
, NULL
);
1124 OMP_PARALLEL_COMBINED (stmt
) = 1;
1125 gfc_add_expr_to_block (&block
, stmt
);
1126 return gfc_finish_block (&block
);
1130 gfc_trans_omp_parallel_sections (gfc_code
*code
)
1133 gfc_omp_clauses section_clauses
;
1134 tree stmt
, omp_clauses
;
1136 memset (§ion_clauses
, 0, sizeof (section_clauses
));
1137 section_clauses
.nowait
= true;
1139 gfc_start_block (&block
);
1140 omp_clauses
= gfc_trans_omp_clauses (&block
, code
->ext
.omp_clauses
,
1143 stmt
= gfc_trans_omp_sections (code
, §ion_clauses
);
1144 if (TREE_CODE (stmt
) != BIND_EXPR
)
1145 stmt
= build3_v (BIND_EXPR
, NULL
, stmt
, poplevel (1, 0, 0));
1148 stmt
= build4_v (OMP_PARALLEL
, stmt
, omp_clauses
, NULL
, NULL
);
1149 OMP_PARALLEL_COMBINED (stmt
) = 1;
1150 gfc_add_expr_to_block (&block
, stmt
);
1151 return gfc_finish_block (&block
);
1155 gfc_trans_omp_parallel_workshare (gfc_code
*code
)
1158 gfc_omp_clauses workshare_clauses
;
1159 tree stmt
, omp_clauses
;
1161 memset (&workshare_clauses
, 0, sizeof (workshare_clauses
));
1162 workshare_clauses
.nowait
= true;
1164 gfc_start_block (&block
);
1165 omp_clauses
= gfc_trans_omp_clauses (&block
, code
->ext
.omp_clauses
,
1168 stmt
= gfc_trans_omp_workshare (code
, &workshare_clauses
);
1169 if (TREE_CODE (stmt
) != BIND_EXPR
)
1170 stmt
= build3_v (BIND_EXPR
, NULL
, stmt
, poplevel (1, 0, 0));
1173 stmt
= build4_v (OMP_PARALLEL
, stmt
, omp_clauses
, NULL
, NULL
);
1174 OMP_PARALLEL_COMBINED (stmt
) = 1;
1175 gfc_add_expr_to_block (&block
, stmt
);
1176 return gfc_finish_block (&block
);
1180 gfc_trans_omp_sections (gfc_code
*code
, gfc_omp_clauses
*clauses
)
1182 stmtblock_t block
, body
;
1183 tree omp_clauses
, stmt
;
1184 bool has_lastprivate
= clauses
->lists
[OMP_LIST_LASTPRIVATE
] != NULL
;
1186 gfc_start_block (&block
);
1188 omp_clauses
= gfc_trans_omp_clauses (&block
, clauses
, code
->loc
);
1190 gfc_init_block (&body
);
1191 for (code
= code
->block
; code
; code
= code
->block
)
1193 /* Last section is special because of lastprivate, so even if it
1194 is empty, chain it in. */
1195 stmt
= gfc_trans_omp_code (code
->next
,
1196 has_lastprivate
&& code
->block
== NULL
);
1197 if (! IS_EMPTY_STMT (stmt
))
1199 stmt
= build1_v (OMP_SECTION
, stmt
);
1200 gfc_add_expr_to_block (&body
, stmt
);
1203 stmt
= gfc_finish_block (&body
);
1205 stmt
= build2_v (OMP_SECTIONS
, stmt
, omp_clauses
);
1206 gfc_add_expr_to_block (&block
, stmt
);
1208 return gfc_finish_block (&block
);
1212 gfc_trans_omp_single (gfc_code
*code
, gfc_omp_clauses
*clauses
)
1214 tree omp_clauses
= gfc_trans_omp_clauses (NULL
, clauses
, code
->loc
);
1215 tree stmt
= gfc_trans_omp_code (code
->block
->next
, true);
1216 stmt
= build2_v (OMP_SINGLE
, stmt
, omp_clauses
);
1221 gfc_trans_omp_workshare (gfc_code
*code
, gfc_omp_clauses
*clauses
)
1224 return gfc_trans_omp_single (code
, clauses
);
1228 gfc_trans_omp_directive (gfc_code
*code
)
1232 case EXEC_OMP_ATOMIC
:
1233 return gfc_trans_omp_atomic (code
);
1234 case EXEC_OMP_BARRIER
:
1235 return gfc_trans_omp_barrier ();
1236 case EXEC_OMP_CRITICAL
:
1237 return gfc_trans_omp_critical (code
);
1239 return gfc_trans_omp_do (code
, NULL
, code
->ext
.omp_clauses
);
1240 case EXEC_OMP_FLUSH
:
1241 return gfc_trans_omp_flush ();
1242 case EXEC_OMP_MASTER
:
1243 return gfc_trans_omp_master (code
);
1244 case EXEC_OMP_ORDERED
:
1245 return gfc_trans_omp_ordered (code
);
1246 case EXEC_OMP_PARALLEL
:
1247 return gfc_trans_omp_parallel (code
);
1248 case EXEC_OMP_PARALLEL_DO
:
1249 return gfc_trans_omp_parallel_do (code
);
1250 case EXEC_OMP_PARALLEL_SECTIONS
:
1251 return gfc_trans_omp_parallel_sections (code
);
1252 case EXEC_OMP_PARALLEL_WORKSHARE
:
1253 return gfc_trans_omp_parallel_workshare (code
);
1254 case EXEC_OMP_SECTIONS
:
1255 return gfc_trans_omp_sections (code
, code
->ext
.omp_clauses
);
1256 case EXEC_OMP_SINGLE
:
1257 return gfc_trans_omp_single (code
, code
->ext
.omp_clauses
);
1258 case EXEC_OMP_WORKSHARE
:
1259 return gfc_trans_omp_workshare (code
, code
->ext
.omp_clauses
);