Re: [patch, fortran] PR 54833 Don't wrap calls to free(a) in if (a != NULL)
Thomas Koenig tkoe...@netcologne.de writes: PR fortran/54833 * trans.c (gfc_call_free): Do not wrap the call to __builtin_free in check for NULL. (gfc_deallocate_with_status): For automatic deallocation without status for non-coarrays, don't wrap call to __builtin_free in check for NULL. spawn /home/andreas/src/gcc/m68k/gcc/testsuite/gfortran/../../gfortran -B/home/andreas/src/gcc/m68k/gcc/testsuite/gfortran/../../ -B/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/ /home/andreas/src/gcc/gcc/gcc/testsuite/gfortran.dg/alloc_comp_assign_1.f90 -fno-diagnostics-show-caret -Os -pedantic-errors -B/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/.libs -L/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/.libs -L/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/.libs -lm -o ./alloc_comp_assign_1.exe /home/andreas/src/gcc/gcc/gcc/testsuite/gfortran.dg/alloc_comp_assign_1.f90: In function 'main': /home/andreas/src/gcc/gcc/gcc/testsuite/gfortran.dg/alloc_comp_assign_1.f90:57:0: internal compiler error: in cselib_record_set, at cselib.c:2379 0x1029ac87 cselib_record_set ../../gcc/gcc/cselib.c:2379 0x1029ac87 cselib_record_sets ../../gcc/gcc/cselib.c:2596 0x1029b417 cselib_process_insn(rtx_def*) ../../gcc/gcc/cselib.c:2649 0x104ec9ab reload_cse_regs_1 ../../gcc/gcc/postreload.c:224 0x104ee1db reload_cse_regs ../../gcc/gcc/postreload.c:70 0x104ee1db rest_of_handle_postreload ../../gcc/gcc/postreload.c:2289 0x104ee1db rest_of_handle_postreload ../../gcc/gcc/postreload.c:2283 Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different.
Re: [patch, fortran] PR 54833 Don't wrap calls to free(a) in if (a != NULL)
Hi Andreas, Thomas Koenig tkoe...@netcologne.de writes: PR fortran/54833 * trans.c (gfc_call_free): Do not wrap the call to __builtin_free in check for NULL. (gfc_deallocate_with_status): For automatic deallocation without status for non-coarrays, don't wrap call to __builtin_free in check for NULL. spawn /home/andreas/src/gcc/m68k/gcc/testsuite/gfortran/../../gfortran -B/home/andreas/src/gcc/m68k/gcc/testsuite/gfortran/../../ -B/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/ /home/andreas/src/gcc/gcc/gcc/testsuite/gfortran.dg/alloc_comp_assign_1.f90 -fno-diagnostics-show-caret -Os -pedantic-errors -B/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/.libs -L/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/.libs -L/home/andreas/src/gcc/m68k/m68k-linux/./libgfortran/.libs -lm -o ./alloc_comp_assign_1.exe /home/andreas/src/gcc/gcc/gcc/testsuite/gfortran.dg/alloc_comp_assign_1.f90: In function 'main': /home/andreas/src/gcc/gcc/gcc/testsuite/gfortran.dg/alloc_comp_assign_1.f90:57:0: internal compiler error: in cselib_record_set, at cselib.c:2379 0x1029ac87 cselib_record_set ../../gcc/gcc/cselib.c:2379 Strange, this looks more like a bug that is exposed through the patch. I also don't see how such a change to the Fortran front end can result in something invalid in postreload. Does not happen on the architectures that I used, and I do not have access to that architecture. Does a (rougly) equivalent C case compile? Thomas
Re: [patch, fortran] PR 54833 Don't wrap calls to free(a) in if (a != NULL)
Thomas Koenig tkoe...@netcologne.de writes: Does not happen on the architectures that I used, and I do not have access to that architecture. A cross compiler is enough. Does a (rougly) equivalent C case compile? How does a (rougly) equivalent C case look like? Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different.
Re: [patch, fortran] PR 54833 Don't wrap calls to free(a) in if (a != NULL)
On Sat, Oct 27, 2012 at 7:41 PM, Andreas Schwab sch...@linux-m68k.org wrote: How does a (rougly) equivalent C case look like? Usually something can be constructed from the -fdump-tree-gimple dump. Ciao! Steven
Re: [patch, fortran] PR 54833 Don't wrap calls to free(a) in if (a != NULL)
Steven Bosscher stevenb@gmail.com writes: On Sat, Oct 27, 2012 at 7:41 PM, Andreas Schwab sch...@linux-m68k.org wrote: How does a (rougly) equivalent C case look like? Usually something can be constructed from the -fdump-tree-gimple dump. Doesn't look like. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different.
[patch, fortran] PR 54833 Don't wrap calls to free(a) in if (a != NULL)
Hello world, the attached patch removes wrapping calls to free(a) by if (a != NULL) for some cases. It is not complete, because automatic deallocation of allocatable structure components is not yet covered. OK for trunk? Thomas 2012-10-06 Thomas König tkoe...@gcc.gnu.org PR fortran/54833 * trans.c (gfc_call_free): Do not wrap the call to __builtin_free in check for NULL. (gfc_deallocate_with_status): For automatic deallocation without status, don't wrap call to __builtin_free in check for NULL. 2012-10-06 Thomas König tkoe...@gcc.gnu.org PR fortran/54833 * gfortran.dg/auto_dealloc_3.f90: New test. Index: trans.c === --- trans.c (Revision 191857) +++ trans.c (Arbeitskopie) @@ -814,26 +814,23 @@ gfc_allocate_allocatable (stmtblock_t * block, tre } -/* Free a given variable, if it's not NULL. */ +/* Free a given variable. If it is NULL, free takes care of this + automatically. */ tree gfc_call_free (tree var) { stmtblock_t block; - tree tmp, cond, call; + tree call; if (TREE_TYPE (var) != TREE_TYPE (pvoid_type_node)) var = fold_convert (pvoid_type_node, var); gfc_start_block (block); var = gfc_evaluate_now (var, block); - cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, var, - build_int_cst (pvoid_type_node, 0)); call = build_call_expr_loc (input_location, builtin_decl_explicit (BUILT_IN_FREE), 1, var); - tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, call, - build_empty_stmt (input_location)); - gfc_add_expr_to_block (block, tmp); + gfc_add_expr_to_block (block, call); return gfc_finish_block (block); } @@ -861,11 +858,10 @@ gfc_call_free (tree var) } } - In this front-end version, status doesn't have to be GFC_INTEGER_4. - Moreover, if CAN_FAIL is true, then we will not emit a runtime error, - even when no status variable is passed to us (this is used for - unconditional deallocation generated by the front-end at end of - each procedure). + In this front-end version, status doesn't have to be GFC_INTEGER_4. If + CAN_FAIL is true and no status variable is passed, we will simply call + free(). This is used for unconditional deallocation generated by the + front-end at end of each procedure. If a runtime-message is possible, `expr' must point to the original expression being deallocated for its locus and variable name. @@ -890,6 +886,14 @@ gfc_deallocate_with_status (tree pointer, tree sta STRIP_NOPS (pointer); } + if (can_fail status == NULL_TREE) +{ + tmp = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_FREE), 1, + fold_convert (pvoid_type_node, pointer)); + return tmp; +} + cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer, build_int_cst (TREE_TYPE (pointer), 0)); ! { dg-do compile } ! { dg-options -fdump-tree-original } ! PR fortran/54833 ! Make sure we don't wrap a free() in an if(a.data != NULL) by ! counting the ifs. subroutine foo real, allocatable :: a(:) allocate(a(10)) end subroutine foo ! { dg-final { scan-tree-dump-times if 3 original } } ! { dg-final { cleanup-tree-dump original } }
Re: [patch, fortran] PR 54833 Don't wrap calls to free(a) in if (a != NULL)
I wrote: the attached patch removes wrapping calls to free(a) by if (a != NULL) for some cases. It is not complete, because automatic deallocation of allocatable structure components is not yet covered. I accidentally posted an old version, which had a bug in coarrays (basically was just missing an else). Regression-tested. OK for trunk? Thomas 2012-10-06 Thomas König tkoe...@gcc.gnu.org PR fortran/54833 * trans.c (gfc_call_free): Do not wrap the call to __builtin_free in check for NULL. (gfc_deallocate_with_status): For automatic deallocation without status for non-coarrays, don't wrap call to __builtin_free in check for NULL. 2012-10-06 Thomas König tkoe...@gcc.gnu.org PR fortran/54833 * gfortran.dg/auto_dealloc_3.f90: New test. Index: trans.c === --- trans.c (Revision 191857) +++ trans.c (Arbeitskopie) @@ -814,26 +814,23 @@ gfc_allocate_allocatable (stmtblock_t * block, tre } -/* Free a given variable, if it's not NULL. */ +/* Free a given variable. If it is NULL, free takes care of this + automatically. */ tree gfc_call_free (tree var) { stmtblock_t block; - tree tmp, cond, call; + tree call; if (TREE_TYPE (var) != TREE_TYPE (pvoid_type_node)) var = fold_convert (pvoid_type_node, var); gfc_start_block (block); var = gfc_evaluate_now (var, block); - cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, var, - build_int_cst (pvoid_type_node, 0)); call = build_call_expr_loc (input_location, builtin_decl_explicit (BUILT_IN_FREE), 1, var); - tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, call, - build_empty_stmt (input_location)); - gfc_add_expr_to_block (block, tmp); + gfc_add_expr_to_block (block, call); return gfc_finish_block (block); } @@ -861,11 +858,10 @@ gfc_call_free (tree var) } } - In this front-end version, status doesn't have to be GFC_INTEGER_4. - Moreover, if CAN_FAIL is true, then we will not emit a runtime error, - even when no status variable is passed to us (this is used for - unconditional deallocation generated by the front-end at end of - each procedure). + In this front-end version, status doesn't have to be GFC_INTEGER_4. If + CAN_FAIL is true, no status variable is passed and we are not dealing with + a coarray, we will simply call free(). This is used for unconditional + deallocation generated by the front-end at end of each procedure. If a runtime-message is possible, `expr' must point to the original expression being deallocated for its locus and variable name. @@ -890,6 +886,14 @@ gfc_deallocate_with_status (tree pointer, tree sta STRIP_NOPS (pointer); } + else if (can_fail status == NULL_TREE) +{ + tmp = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_FREE), 1, + fold_convert (pvoid_type_node, pointer)); + return tmp; +} + cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer, build_int_cst (TREE_TYPE (pointer), 0)); ! { dg-do compile } ! { dg-options -fdump-tree-original } ! PR fortran/54833 ! Make sure we don't wrap a free() in an if(a.data != NULL) by ! counting the ifs. subroutine foo real, allocatable :: a(:) allocate(a(10)) end subroutine foo ! { dg-final { scan-tree-dump-times if 3 original } } ! { dg-final { cleanup-tree-dump original } }