diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2019-06-02 15:18:22 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2019-06-02 15:18:22 +0000 |
commit | 5d9c602d8374bd4330b53ae4dc6a2534199cc397 (patch) | |
tree | 1f6c9311416085b4463f65d6cccc0f52e1d64761 /gcc/fortran/trans-expr.c | |
parent | 5efdd6eeb65593900596592280b1be74b486e377 (diff) | |
download | gcc-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.c | 53 |
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; } |