leslie3d terminates itself with STOP which translates to a noreturn function. This causes our edge hot/cold prediction machinery to not apply any predictions based on paths to noreturn functions (because there is no path that does not lead to a noreturn function). This in turn makes us predict the error path for ALLOCATE statements as likely, leading to the tail of the function becoming cold. This is because the error path is guarded by a if (ptr != 0) which is predicted as likely - that is quite unusual, so we should mark those tests as unlikely. Done with the following patch.
Bootstrapped and tested on x86_64-unknown-linux-gnu. Ok for trunk? Thanks, Richard. 2011-06-09 Richard Guenther <rguent...@suse.de> * trans.c (gfc_allocate_array_with_status): Mark error path as unlikely. Index: gcc/fortran/trans.c =================================================================== --- gcc/fortran/trans.c (revision 174746) +++ gcc/fortran/trans.c (working copy) @@ -697,8 +697,9 @@ gfc_allocate_array_with_status (stmtbloc /* Create a variable to hold the result. */ res = gfc_create_var (type, NULL); - null_mem = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, mem, - build_int_cst (type, 0)); + null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR, + boolean_type_node, mem, + build_int_cst (type, 0))); /* If mem is NULL, we call gfc_allocate_with_status. */ gfc_start_block (&alloc_block); @@ -751,7 +752,7 @@ gfc_allocate_array_with_status (stmtbloc } tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem, - alloc, error); + error, alloc); gfc_add_expr_to_block (block, tmp); return res;