From e97c99f15937e5762a973b25192aab824126a6d3 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Tue, 2 Sep 2014 15:29:57 -0700 Subject: [gcc-4.9] Merge svn r214745 from google/gcc-4_9 branch. Merge gcc-4_9 source r214745 from google/gcc-4_9 branch. Change-Id: Ie6fa0fd72f4b4eec3adc4db4bb922e652d1c2605 --- gcc-4.9/gcc/fortran/ChangeLog | 56 +++++++++++++++++++++++++++++++++++ gcc-4.9/gcc/fortran/frontend-passes.c | 30 +++++++++++++++---- gcc-4.9/gcc/fortran/gfortran.h | 2 +- gcc-4.9/gcc/fortran/openmp.c | 9 ++++-- gcc-4.9/gcc/fortran/simplify.c | 11 ++++++- gcc-4.9/gcc/fortran/trans-expr.c | 4 +-- gcc-4.9/gcc/fortran/trans-openmp.c | 32 +++++++++++++++++++- 7 files changed, 132 insertions(+), 12 deletions(-) (limited to 'gcc-4.9/gcc/fortran') diff --git a/gcc-4.9/gcc/fortran/ChangeLog b/gcc-4.9/gcc/fortran/ChangeLog index d2e070b78..9f4bec74e 100644 --- a/gcc-4.9/gcc/fortran/ChangeLog +++ b/gcc-4.9/gcc/fortran/ChangeLog @@ -1,3 +1,59 @@ +2014-08-21 Thomas Koenig + + Backport from trunk + PR fortran/62214 + * frontend-passes.c (optimize_binop_array_assignment): + Do not try to optimize the array assignment for string + concatenation. + +2014-08-16 Thomas Koenig + + Backport from trunk + PR fortran/62142 + * trans-expr.c (is_runtime_conformable): Add NULL pointer checks. + +2014-08-15 Thomas Koenig + + Backport from trunk + PR fortran/62106 + * gfortran.h (symbol_attribute): Add fe_temp flag. + * frontend-passes.c (is_fe_temp): New function. + (create_var): Don't add a temporary for an already + created variable or for a constant. + (combine_ARRAY_constructor): Remove special handling + for constants. + +2014-08-15 Jakub Jelinek + Tobias Burnus + + PR fortran/62131 + * openmp.c (resolve_omp_atomic): Only complain if code->expr1's attr + is allocatable, rather than whenever var->attr.allocatable. + +2014-08-15 Jakub Jelinek + + PR fortran/62107 + * trans-openmp.c (gfc_omp_finish_clause): Handle scalar pointer + or allocatable passed by reference. + (gfc_trans_omp_clauses) : Likewise. + +2014-08-14 Jakub Jelinek + + PR fortran/62076 + * openmp.c (gfc_match_omp_clauses): When failed to match + operator name, defined op name or name, set buffer to + empty string. Don't call gfc_find_omp_udr if buffer is empty + string. + (gfc_match_omp_declare_reduction): Call gfc_undo_symbols () + before calling gfc_free_omp_udr. + +2014-08-10 Thomas Koenig + + Backport from trunk + PR fortran/61999 + * simplify.c (gfc_simplify_dot_product): Convert types of + vectors before calculating the result. + 2014-07-19 Paul Thomas Backport from mainline diff --git a/gcc-4.9/gcc/fortran/frontend-passes.c b/gcc-4.9/gcc/fortran/frontend-passes.c index 4646cc33f..23a8ece17 100644 --- a/gcc-4.9/gcc/fortran/frontend-passes.c +++ b/gcc-4.9/gcc/fortran/frontend-passes.c @@ -430,11 +430,26 @@ cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, return 0; } +/* Auxiliary function to check if an expression is a temporary created by + create var. */ + +static bool +is_fe_temp (gfc_expr *e) +{ + if (e->expr_type != EXPR_VARIABLE) + return false; + + return e->symtree->n.sym->attr.fe_temp; +} + + /* Returns a new expression (a variable) to be used in place of the old one, with an assignment statement before the current statement to set the value of the variable. Creates a new BLOCK for the statement if that hasn't already been done and puts the statement, plus the - newly created variables, in that block. */ + newly created variables, in that block. Special cases: If the + expression is constant or a temporary which has already + been created, just copy it. */ static gfc_expr* create_var (gfc_expr * e) @@ -448,6 +463,9 @@ create_var (gfc_expr * e) gfc_namespace *ns; int i; + if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e)) + return gfc_copy_expr (e); + /* If the block hasn't already been created, do so. */ if (inserted_block == NULL) { @@ -522,6 +540,7 @@ create_var (gfc_expr * e) symbol->attr.flavor = FL_VARIABLE; symbol->attr.referenced = 1; symbol->attr.dimension = e->rank > 0; + symbol->attr.fe_temp = 1; gfc_commit_symbol (symbol); result = gfc_get_expr (); @@ -884,6 +903,10 @@ optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op) return true; break; + case INTRINSIC_CONCAT: + /* Do not do string concatenations. */ + break; + default: /* Binary operators. */ if (optimize_binop_array_assignment (c, &e->value.op.op1, true)) @@ -1082,10 +1105,7 @@ combine_array_constructor (gfc_expr *e) if (op2->ts.type == BT_CHARACTER) return false; - if (op2->expr_type == EXPR_CONSTANT) - scalar = gfc_copy_expr (op2); - else - scalar = create_var (gfc_copy_expr (op2)); + scalar = create_var (gfc_copy_expr (op2)); oldbase = op1->value.constructor; newbase = NULL; diff --git a/gcc-4.9/gcc/fortran/gfortran.h b/gcc-4.9/gcc/fortran/gfortran.h index 6b88aec38..a193f53fe 100644 --- a/gcc-4.9/gcc/fortran/gfortran.h +++ b/gcc-4.9/gcc/fortran/gfortran.h @@ -724,7 +724,7 @@ typedef struct optional:1, pointer:1, target:1, value:1, volatile_:1, temporary:1, dummy:1, result:1, assign:1, threadprivate:1, not_always_present:1, implied_index:1, subref_array_pointer:1, proc_pointer:1, asynchronous:1, - contiguous:1; + contiguous:1, fe_temp: 1; /* For CLASS containers, the pointer attribute is sometimes set internally even though it was not directly specified. In this case, keep the diff --git a/gcc-4.9/gcc/fortran/openmp.c b/gcc-4.9/gcc/fortran/openmp.c index 68ba70f7e..58aaf6623 100644 --- a/gcc-4.9/gcc/fortran/openmp.c +++ b/gcc-4.9/gcc/fortran/openmp.c @@ -464,7 +464,11 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned int mask, || !gfc_add_intrinsic (&sym->attr, NULL))) rop = OMP_REDUCTION_NONE; } - gfc_omp_udr *udr = gfc_find_omp_udr (gfc_current_ns, buffer, NULL); + else + buffer[0] = '\0'; + gfc_omp_udr *udr + = (buffer[0] + ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL); gfc_omp_namelist **head = NULL; if (rop == OMP_REDUCTION_NONE && udr) rop = OMP_REDUCTION_USER; @@ -1240,6 +1244,7 @@ gfc_match_omp_declare_reduction (void) syntax: gfc_current_locus = old_loc; gfc_current_ns = combiner_ns->parent; + gfc_undo_symbols (); gfc_free_omp_udr (omp_udr); return MATCH_ERROR; } @@ -2739,7 +2744,7 @@ resolve_omp_atomic (gfc_code *code) break; } - if (var->attr.allocatable) + if (gfc_expr_attr (code->expr1).allocatable) { gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L", &code->loc); diff --git a/gcc-4.9/gcc/fortran/simplify.c b/gcc-4.9/gcc/fortran/simplify.c index 96d0f21f3..d20552327 100644 --- a/gcc-4.9/gcc/fortran/simplify.c +++ b/gcc-4.9/gcc/fortran/simplify.c @@ -1878,13 +1878,22 @@ gfc_simplify_dim (gfc_expr *x, gfc_expr *y) gfc_expr* gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b) { + + gfc_expr temp; + if (!is_constant_array_expr (vector_a) || !is_constant_array_expr (vector_b)) return NULL; gcc_assert (vector_a->rank == 1); gcc_assert (vector_b->rank == 1); - gcc_assert (gfc_compare_types (&vector_a->ts, &vector_b->ts)); + + temp.expr_type = EXPR_OP; + gfc_clear_ts (&temp.ts); + temp.value.op.op = INTRINSIC_NONE; + temp.value.op.op1 = vector_a; + temp.value.op.op2 = vector_b; + gfc_type_convert_binary (&temp, 1); return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0, true); } diff --git a/gcc-4.9/gcc/fortran/trans-expr.c b/gcc-4.9/gcc/fortran/trans-expr.c index dbfde1bdc..824ab785b 100644 --- a/gcc-4.9/gcc/fortran/trans-expr.c +++ b/gcc-4.9/gcc/fortran/trans-expr.c @@ -7842,7 +7842,7 @@ is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2) for (a = expr2->value.function.actual; a != NULL; a = a->next) { e1 = a->expr; - if (e1->rank > 0 && !is_runtime_conformable (expr1, e1)) + if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1)) return false; } return true; @@ -7853,7 +7853,7 @@ is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2) for (a = expr2->value.function.actual; a != NULL; a = a->next) { e1 = a->expr; - if (e1->rank > 0 && !is_runtime_conformable (expr1, e1)) + if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1)) return false; } return true; diff --git a/gcc-4.9/gcc/fortran/trans-openmp.c b/gcc-4.9/gcc/fortran/trans-openmp.c index da01a9034..548b5d3a4 100644 --- a/gcc-4.9/gcc/fortran/trans-openmp.c +++ b/gcc-4.9/gcc/fortran/trans-openmp.c @@ -1022,6 +1022,7 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p) && !GFC_DECL_CRAY_POINTEE (decl) && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) return; + tree orig_decl = decl; c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); OMP_CLAUSE_MAP_KIND (c4) = OMP_CLAUSE_MAP_POINTER; OMP_CLAUSE_DECL (c4) = decl; @@ -1029,6 +1030,17 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p) decl = build_fold_indirect_ref (decl); OMP_CLAUSE_DECL (c) = decl; OMP_CLAUSE_SIZE (c) = NULL_TREE; + if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE + && (GFC_DECL_GET_SCALAR_POINTER (orig_decl) + || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl))) + { + c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); + OMP_CLAUSE_MAP_KIND (c3) = OMP_CLAUSE_MAP_POINTER; + OMP_CLAUSE_DECL (c3) = unshare_expr (decl); + OMP_CLAUSE_SIZE (c3) = size_int (0); + decl = build_fold_indirect_ref (decl); + OMP_CLAUSE_DECL (c) = decl; + } } if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) { @@ -1884,14 +1896,32 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, TREE_ADDRESSABLE (decl) = 1; if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL) { - if (POINTER_TYPE_P (TREE_TYPE (decl))) + if (POINTER_TYPE_P (TREE_TYPE (decl)) + && (gfc_omp_privatize_by_reference (decl) + || GFC_DECL_GET_SCALAR_POINTER (decl) + || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl) + || GFC_DECL_CRAY_POINTEE (decl) + || GFC_DESCRIPTOR_TYPE_P + (TREE_TYPE (TREE_TYPE (decl))))) { + tree orig_decl = decl; node4 = build_omp_clause (input_location, OMP_CLAUSE_MAP); OMP_CLAUSE_MAP_KIND (node4) = OMP_CLAUSE_MAP_POINTER; OMP_CLAUSE_DECL (node4) = decl; OMP_CLAUSE_SIZE (node4) = size_int (0); decl = build_fold_indirect_ref (decl); + if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE + && (GFC_DECL_GET_SCALAR_POINTER (orig_decl) + || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl))) + { + node3 = build_omp_clause (input_location, + OMP_CLAUSE_MAP); + OMP_CLAUSE_MAP_KIND (node3) = OMP_CLAUSE_MAP_POINTER; + OMP_CLAUSE_DECL (node3) = decl; + OMP_CLAUSE_SIZE (node3) = size_int (0); + decl = build_fold_indirect_ref (decl); + } } if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) { -- cgit v1.2.3