aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2019-06-02 15:18:22 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2019-06-02 15:18:22 +0000
commit5d9c602d8374bd4330b53ae4dc6a2534199cc397 (patch)
tree1f6c9311416085b4463f65d6cccc0f52e1d64761 /gcc/fortran/trans-expr.c
parent5efdd6eeb65593900596592280b1be74b486e377 (diff)
downloadgcc-5d9c602d8374bd4330b53ae4dc6a2534199cc397.zip
gcc-5d9c602d8374bd4330b53ae4dc6a2534199cc397.tar.gz
gcc-5d9c602d8374bd4330b53ae4dc6a2534199cc397.tar.bz2
re PR fortran/90539 (481.wrf slowdown by 25% on Intel Kaby with -Ofast -march=native starting with r271377)
2019-06-02 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/90539 * trans-expr.c (gfc_conv_subref_array_arg): If the size of the expression can be determined to be one, treat it as contiguous. Set likelyhood of presence of an actual argument according to PRED_FORTRAN_ABSENT_DUMMY and likelyhood of being contiguous according to PRED_FORTRAN_CONTIGUOUS. 2019-06-02 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/90539 * predict.def (PRED_FORTRAN_CONTIGUOUS): New predictor. 2019-06-02 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/90539 * gfortran.dg/internal_pack_24.f90: New test. From-SVN: r271844
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 5183029..d23520f 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -4922,15 +4922,35 @@ class_array_fcn:
gfc_se cont_se, array_se;
stmtblock_t if_block, else_block;
tree if_stmt, else_stmt;
+ mpz_t size;
+ bool size_set;
cont_var = gfc_create_var (boolean_type_node, "contiguous");
- /* cont_var = is_contiguous (expr); . */
- gfc_init_se (&cont_se, parmse);
- gfc_conv_is_contiguous_expr (&cont_se, expr);
- gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
- gfc_add_modify (&se->pre, cont_var, cont_se.expr);
- gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
+ /* If the size is known to be one at compile-time, set
+ cont_var to true unconditionally. This may look
+ inelegant, but we're only doing this during
+ optimization, so the statements will be optimized away,
+ and this saves complexity here. */
+
+ size_set = gfc_array_size (expr, &size);
+ if (size_set && mpz_cmp_ui (size, 1) == 0)
+ {
+ gfc_add_modify (&se->pre, cont_var,
+ build_one_cst (boolean_type_node));
+ }
+ else
+ {
+ /* cont_var = is_contiguous (expr); . */
+ gfc_init_se (&cont_se, parmse);
+ gfc_conv_is_contiguous_expr (&cont_se, expr);
+ gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
+ gfc_add_modify (&se->pre, cont_var, cont_se.expr);
+ gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
+ }
+
+ if (size_set)
+ mpz_clear (size);
/* arrayse->expr = descriptor of a. */
gfc_init_se (&array_se, se);
@@ -4953,7 +4973,9 @@ class_array_fcn:
/* And put the above into an if statement. */
pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
- cont_var, if_stmt, else_stmt);
+ gfc_likely (cont_var,
+ PRED_FORTRAN_CONTIGUOUS),
+ if_stmt, else_stmt);
}
else
{
@@ -4976,11 +4998,11 @@ class_array_fcn:
gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
else_stmt = gfc_finish_block (&else_block);
- tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, present_var,
+ tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
+ gfc_likely (present_var,
+ PRED_FORTRAN_ABSENT_DUMMY),
pre_stmts, else_stmt);
gfc_add_expr_to_block (&se->pre, tmp);
-
-
}
else
gfc_add_expr_to_block (&se->pre, pre_stmts);
@@ -4995,9 +5017,16 @@ class_array_fcn:
tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
cont_var,
build_zero_cst (boolean_type_node));
+ tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
+
if (pass_optional)
- post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
- boolean_type_node, present_var, tmp);
+ {
+ tree present_likely = gfc_likely (present_var,
+ PRED_FORTRAN_ABSENT_DUMMY);
+ post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
+ boolean_type_node, present_likely,
+ tmp);
+ }
else
post_cond = tmp;
}