diff options
Diffstat (limited to 'gcc')
50 files changed, 1014 insertions, 419 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6def41fee76..b05a7649429 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,111 @@ +2012-01-20 Andrey Belevantsev <abel@ispras.ru> + + PR target/51106 + * function.c (instantiate_virtual_regs_in_insn): Use + delete_insn_and_edges when removing a wrong asm insn. + +2012-01-19 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/40761 + * ira-int.h (struct ira_loop_tree_node): Add comment for member + loop. Add new member loop_num. + (IRA_LOOP_NODE_BY_INDEX): Modify the check. + (ira_build): Remove the parameter. + + * ira.c (ira_print_disposition): Use loop_num instead of + loop->num. + (ira.c): Do not build CFG loops for one region allocation. Remove + argument from ira_build call. + + * ira-build.c (init_loop_tree_node): New function. + (create_loop_tree_nodes): Use it. Separate the case when CFG + loops are not built. + (more_one_region_p): Check current_loops. + (finish_loop_tree_nodes): Separate the case when CFG loops are not + built. + (add_loop_to_tree): Process loop equal to NULL too. + (form_loop_tree): Separate the case when CFG loops are not built. + Use explicitly number for the root. + (rebuild_regno_allocno_maps, create_loop_tree_node_allocnos): Add + an assertion. + (ira_print_expanded_allocno, loop_compare_func): Use loop_num + instead of loop->num. + (mark_loops_for_removal): Ditto. Use loop_num instead of + loop->num. + (mark_all_loops_for_removal): Ditto. + (remove_unnecessary_regions): Separate the case when CFG loops + are not built. + (ira_build): Remove the parameter. Use explicit number of regions + when CFG loops are not built. + + * ira-color.c (print_loop_title): Separate the case for the root + node. Use loop_num instead of loop->num. + (move_spill_restore): Use loop_num instead of loop->num. + + * ira-emit.c (setup_entered_from_non_parent_p): Add an assertion. + (change_loop): Ditto. + (change_loop): Use loop_num instead of loop->num. + + * ira-lives.c (process_bb_node_lives): Ditto. + + * ira-costs.c (print_allocno_costs, find_costs_and_classes): + Ditto. + + * ira-conflicts.c (print_allocno_conflicts): Ditto. + +2012-01-19 Jakub Jelinek <jakub@redhat.com> + + PR libmudflap/40778 + * tree-mudflap.c (mf_artificial): New function. + (execute_mudflap_function_ops, execute_mudflap_function_decls, + mx_register_decls, mudflap_enqueue_decl): Use it. + + PR target/51876 + * config/arm/neon.md (*neon_vswp<mode>): Fix up operand + numbers in the insn pattern. + +2012-01-19 Michael Matz <matz@suse.de> + + PR tree-optimization/46590 + * cfgexpand.c (add_scope_conflicts_1): New old_conflicts argument, + use it in remembering which conflicts we already created. + (add_scope_conflicts): Adjust call to above, (de)allocate helper + bitmap. + +2012-01-19 Aldy Hernandez <aldyh@redhat.com> + + PR lto/51280 + * lto-wrapper.c (run_gcc): Pass -fgnu_tm on. + (merge_and_complain): Same. + +2012-01-19 Jakub Jelinek <jakub@redhat.com> + + PR bootstrap/50237 + * config/initfini-array.h: Guard content of the header + with #ifdef HAVE_INITFINI_ARRAY. + * configure.ac: Move gcc_AC_INITFINI_ARRAY much later into the file. + Add initfini-array.h to tm_file here. + * acinclude.m4 (gcc_AC_INITFINI_ARRAY): For non-ia64 do a linker + test. + * config.gcc: Don't add initfini-array.h to tm_file here. + * configure: Regenerated. + +2012-01-19 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/51505 + * df-problems.c (df_kill_notes): New parameter live. Update comment. + Remove REG_EQUAL/REG_EQUIV notes referring to dead registers. + (df_note_bb_compute): Update the call to df_kill_notes. + +2012-01-18 Aldy Hernandez <aldyh@redhat.com> + + * trans-mem.c (requires_barrier): Remove call to is_global_var. + +2012-01-18 Richard Guenther <rguenther@suse.de> + + * tree-ssa.c (useless_type_conversion_p): Remove special-casing + of conversions to void *. + 2012-01-17 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> Richard Sandiford <rdsandiford@googlemail.com> diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 1dff77b4fc2..2be57aa702b 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20120118 +20120120 diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4 index d8defea5a78..933f81167c6 100644 --- a/gcc/acinclude.m4 +++ b/gcc/acinclude.m4 @@ -376,119 +376,85 @@ AC_DEFUN([gcc_AC_INITFINI_ARRAY], AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support, gcc_cv_initfini_array, [dnl if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then - AC_RUN_IFELSE([AC_LANG_SOURCE([ + case "${target}" in + ia64-*) + AC_RUN_IFELSE([AC_LANG_SOURCE([ #ifndef __ELF__ #error Not an ELF OS #endif -#ifdef __ia64__ /* We turn on .preinit_array/.init_array/.fini_array support for ia64 if it can be used. */ static int x = -1; int main (void) { return x; } int foo (void) { x = 0; } int (*fp) (void) __attribute__ ((section (".init_array"))) = foo; -#else -extern void abort (); -static int count; - -static void -init1005 () -{ - if (count != 0) - abort (); - count = 1005; -} -void (*const init_array1005[]) () - __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *)))) - = { init1005 }; -static void -fini1005 () -{ - if (count != 1005) - abort (); -} -void (*const fini_array1005[]) () - __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *)))) - = { fini1005 }; - -static void -ctor1007 () -{ - if (count != 1005) - abort (); - count = 1007; -} -void (*const ctors1007[]) () - __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *)))) - = { ctor1007 }; -static void -dtor1007 () -{ - if (count != 1007) - abort (); - count = 1005; -} -void (*const dtors1007[]) () - __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *)))) - = { dtor1007 }; - -static void -init65530 () -{ - if (count != 1007) - abort (); - count = 65530; -} -void (*const init_array65530[]) () - __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *)))) - = { init65530 }; -static void -fini65530 () -{ - if (count != 65530) - abort (); - count = 1007; -} -void (*const fini_array65530[]) () - __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *)))) - = { fini65530 }; - -static void -ctor65535 () -{ - if (count != 65530) - abort (); - count = 65535; -} -void (*const ctors65535[]) () - __attribute__ ((section (".ctors"), aligned (sizeof (void *)))) - = { ctor65535 }; -static void -dtor65535 () -{ - if (count != 65535) - abort (); - count = 65530; -} -void (*const dtors65535[]) () - __attribute__ ((section (".dtors"), aligned (sizeof (void *)))) - = { dtor65535 }; - -int -main () -{ - if (count != 65535) - abort (); - return 0; -} -#endif ])], [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no], - [gcc_cv_initfini_array=no]) - else - AC_MSG_CHECKING(cross compile... guessing) - gcc_cv_initfini_array=no - fi]) + [gcc_cv_initfini_array=no]);; + *) + gcc_cv_initfini_array=no + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 \ + -a "$gcc_cv_gld_minor_version" -ge 22 \ + -o "$gcc_cv_gld_major_version" -gt 2 \ + && test $in_tree_ld_is_elf = yes; then + gcc_cv_initfini_array=yes + fi + elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then + cat > conftest.s <<\EOF +.section .dtors,"a",%progbits +.balign 4 +.byte 'A', 'A', 'A', 'A' +.section .ctors,"a",%progbits +.balign 4 +.byte 'B', 'B', 'B', 'B' +.section .fini_array.65530,"a",%progbits +.balign 4 +.byte 'C', 'C', 'C', 'C' +.section .init_array.65530,"a",%progbits +.balign 4 +.byte 'D', 'D', 'D', 'D' +.section .dtors.64528,"a",%progbits +.balign 4 +.byte 'E', 'E', 'E', 'E' +.section .ctors.64528,"a",%progbits +.balign 4 +.byte 'F', 'F', 'F', 'F' +.section .fini_array.01005,"a",%progbits +.balign 4 +.byte 'G', 'G', 'G', 'G' +.section .init_array.01005,"a",%progbits +.balign 4 +.byte 'H', 'H', 'H', 'H' +.text +EOF + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -e 0 -o conftest conftest.o > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .init_array conftest \ + | grep HHHHFFFFDDDDBBBB > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .fini_array conftest \ + | grep GGGGEEEECCCCAAAA > /dev/null 2>&1; then + gcc_cv_initfini_array=yes + fi +changequote(,)dnl + rm -f conftest conftest.* +changequote([,])dnl + fi + AC_PREPROC_IFELSE([AC_LANG_SOURCE([ +#ifndef __ELF__ +#error Not an ELF OS +#endif +#include <stdlib.h> +#if defined __GLIBC_PREREQ && __GLIBC_PREREQ (2, 4) +#else +#error The C library not known to support .init_array/.fini_array +#endif +])],, [gcc_cv_initfini_array=no]);; + esac + else + AC_MSG_CHECKING(cross compile... guessing) + gcc_cv_initfini_array=no + fi]) enable_initfini_array=$gcc_cv_initfini_array ]) if test $enable_initfini_array = yes; then diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 index 06028cc051f..e466ae17839 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -1,7 +1,8 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- +# generated automatically by aclocal 1.11.2 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -13,12 +14,14 @@ # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2746d04fe4a..c2045f940fe 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2012-01-18 Richard Guenther <rguenther@suse.de> + + * c-opts.c (c_common_post_options): Reset LTO flags if + we are about to generate a PCH. + 2012-01-17 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51777 diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 4f0d8861470..f2a7971781d 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -1058,6 +1058,13 @@ c_common_post_options (const char **pfilename) && flag_preprocess_only && !flag_no_line_commands) pp_dir_change (parse_in, get_src_pwd ()); + /* Disable LTO output when outputting a precompiled header. */ + if (pch_file && flag_lto) + { + flag_lto = 0; + flag_generate_lto = 0; + } + return flag_preprocess_only; } diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 579c3cde011..9f0797ce050 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -441,11 +441,12 @@ visit_conflict (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data) /* Helper routine for add_scope_conflicts, calculating the active partitions at the end of BB, leaving the result in WORK. We're called to generate - conflicts when FOR_CONFLICT is true, otherwise we're just tracking - liveness. */ + conflicts when OLD_CONFLICTS is non-null, otherwise we're just tracking + liveness. If we generate conflicts then OLD_CONFLICTS stores the bits + for which we generated conflicts already. */ static void -add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) +add_scope_conflicts_1 (basic_block bb, bitmap work, bitmap old_conflicts) { edge e; edge_iterator ei; @@ -482,7 +483,7 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) } else if (!is_gimple_debug (stmt)) { - if (for_conflict + if (old_conflicts && visit == visit_op) { /* If this is the first real instruction in this BB we need @@ -490,16 +491,27 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) Unlike classical liveness for named objects we can't rely on seeing a def/use of the names we're interested in. There might merely be indirect loads/stores. We'd not add any - conflicts for such partitions. */ + conflicts for such partitions. We know that we generated + conflicts between all partitions in old_conflicts already, + so we need to generate only the new ones, avoiding to + repeatedly pay the O(N^2) cost for each basic block. */ bitmap_iterator bi; unsigned i; - EXECUTE_IF_SET_IN_BITMAP (work, 0, i, bi) + + EXECUTE_IF_AND_COMPL_IN_BITMAP (work, old_conflicts, 0, i, bi) { unsigned j; bitmap_iterator bj; - EXECUTE_IF_SET_IN_BITMAP (work, i + 1, j, bj) + /* First the conflicts between new and old_conflicts. */ + EXECUTE_IF_SET_IN_BITMAP (old_conflicts, 0, j, bj) + add_stack_var_conflict (i, j); + /* Then the conflicts between only the new members. */ + EXECUTE_IF_AND_COMPL_IN_BITMAP (work, old_conflicts, i + 1, + j, bj) add_stack_var_conflict (i, j); } + /* And remember for the next basic block. */ + bitmap_ior_into (old_conflicts, work); visit = visit_conflict; } walk_stmt_load_store_addr_ops (stmt, work, visit, visit, visit); @@ -516,6 +528,7 @@ add_scope_conflicts (void) basic_block bb; bool changed; bitmap work = BITMAP_ALLOC (NULL); + bitmap old_conflicts; /* We approximate the live range of a stack variable by taking the first mention of its name as starting point(s), and by the end-of-scope @@ -537,15 +550,18 @@ add_scope_conflicts (void) FOR_EACH_BB (bb) { bitmap active = (bitmap)bb->aux; - add_scope_conflicts_1 (bb, work, false); + add_scope_conflicts_1 (bb, work, NULL); if (bitmap_ior_into (active, work)) changed = true; } } + old_conflicts = BITMAP_ALLOC (NULL); + FOR_EACH_BB (bb) - add_scope_conflicts_1 (bb, work, true); + add_scope_conflicts_1 (bb, work, old_conflicts); + BITMAP_FREE (old_conflicts); BITMAP_FREE (work); FOR_ALL_BB (bb) BITMAP_FREE (bb->aux); diff --git a/gcc/config.gcc b/gcc/config.gcc index bc2bf05ec4e..e8155cd9a4e 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -2941,11 +2941,6 @@ if test x$with_schedule = x; then esac fi -# Support --enable-initfini-array. -if test x$enable_initfini_array = xyes; then - tm_file="${tm_file} initfini-array.h" -fi - # Validate and mark as valid any --with options supported # by this target. In order to use a particular --with option # you must list it in supported_defaults; validating the value diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 24a15802bc3..a6c891dafd6 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -2869,7 +2869,7 @@ (match_operand:VDQX 1 "s_register_operand" "+w")) (set (match_dup 1) (match_dup 0))] "TARGET_NEON && reload_completed" - "vswp\t%<V_reg>1, %<V_reg>2" + "vswp\t%<V_reg>0, %<V_reg>1" [(set (attr "neon_type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") diff --git a/gcc/config/initfini-array.h b/gcc/config/initfini-array.h index 8aaadf686af..bb48c70a920 100644 --- a/gcc/config/initfini-array.h +++ b/gcc/config/initfini-array.h @@ -1,6 +1,6 @@ /* Definitions for ELF systems with .init_array/.fini_array section support. - Copyright (C) 2011 + Copyright (C) 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -19,6 +19,8 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +#ifdef HAVE_INITFINI_ARRAY + #define USE_INITFINI_ARRAY #undef INIT_SECTION_ASM_OP @@ -35,3 +37,5 @@ #define TARGET_ASM_CONSTRUCTOR default_elf_init_array_asm_out_constructor #undef TARGET_ASM_DESTRUCTOR #define TARGET_ASM_DESTRUCTOR default_elf_fini_array_asm_out_destructor + +#endif diff --git a/gcc/configure b/gcc/configure index 96998911229..7a2f03490da 100755 --- a/gcc/configure +++ b/gcc/configure @@ -893,7 +893,6 @@ enable_languages with_multilib_list enable_rpath with_libiconv_prefix -enable_initfini_array enable_sjlj_exceptions enable_secureplt enable_leading_mingw64_underscores @@ -906,6 +905,7 @@ enable_fast_install enable_libtool_lock with_plugin_ld enable_gnu_indirect_function +enable_initfini_array enable_comdat enable_gnu_unique_object enable_linker_build_id @@ -1591,7 +1591,6 @@ Optional Features: --disable-shared don't provide a shared libgcc --enable-languages=LIST specify which front-ends to build --disable-rpath do not hardcode runtime library paths - --enable-initfini-array use .init_array/.fini_array sections --enable-sjlj-exceptions arrange to use setjmp/longjmp exception handling --enable-secureplt enable -msecure-plt by default for PowerPC @@ -1615,6 +1614,7 @@ Optional Features: --enable-gnu-indirect-function enable the use of the @gnu_indirect_function to glibc systems + --enable-initfini-array use .init_array/.fini_array sections --enable-comdat enable COMDAT group support --enable-gnu-unique-object enable the use of the @gnu_unique_object ELF @@ -10986,157 +10986,6 @@ fi CFLAGS="$saved_CFLAGS" CXXFLAGS="$saved_CXXFLAGS" -# Check whether --enable-initfini-array was given. -if test "${enable_initfini_array+set}" = set; then : - enableval=$enable_initfini_array; -else - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .preinit_array/.init_array/.fini_array support" >&5 -$as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6; } -if test "${gcc_cv_initfini_array+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then - if test "$cross_compiling" = yes; then : - gcc_cv_initfini_array=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifndef __ELF__ -#error Not an ELF OS -#endif -#ifdef __ia64__ -/* We turn on .preinit_array/.init_array/.fini_array support for ia64 - if it can be used. */ -static int x = -1; -int main (void) { return x; } -int foo (void) { x = 0; } -int (*fp) (void) __attribute__ ((section (".init_array"))) = foo; -#else -extern void abort (); -static int count; - -static void -init1005 () -{ - if (count != 0) - abort (); - count = 1005; -} -void (*const init_array1005) () - __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *)))) - = { init1005 }; -static void -fini1005 () -{ - if (count != 1005) - abort (); -} -void (*const fini_array1005) () - __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *)))) - = { fini1005 }; - -static void -ctor1007 () -{ - if (count != 1005) - abort (); - count = 1007; -} -void (*const ctors1007) () - __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *)))) - = { ctor1007 }; -static void -dtor1007 () -{ - if (count != 1007) - abort (); - count = 1005; -} -void (*const dtors1007) () - __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *)))) - = { dtor1007 }; - -static void -init65530 () -{ - if (count != 1007) - abort (); - count = 65530; -} -void (*const init_array65530) () - __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *)))) - = { init65530 }; -static void -fini65530 () -{ - if (count != 65530) - abort (); - count = 1007; -} -void (*const fini_array65530) () - __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *)))) - = { fini65530 }; - -static void -ctor65535 () -{ - if (count != 65530) - abort (); - count = 65535; -} -void (*const ctors65535) () - __attribute__ ((section (".ctors"), aligned (sizeof (void *)))) - = { ctor65535 }; -static void -dtor65535 () -{ - if (count != 65535) - abort (); - count = 65530; -} -void (*const dtors65535) () - __attribute__ ((section (".dtors"), aligned (sizeof (void *)))) - = { dtor65535 }; - -int -main () -{ - if (count != 65535) - abort (); - return 0; -} -#endif - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - gcc_cv_initfini_array=yes -else - gcc_cv_initfini_array=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking cross compile... guessing" >&5 -$as_echo_n "checking cross compile... guessing... " >&6; } - gcc_cv_initfini_array=no - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5 -$as_echo "$gcc_cv_initfini_array" >&6; } - enable_initfini_array=$gcc_cv_initfini_array - -fi - -if test $enable_initfini_array = yes; then - -$as_echo "#define HAVE_INITFINI_ARRAY 1" >>confdefs.h - -fi - # mkdir takes a single argument on some systems. { $as_echo "$as_me:${as_lineno-$LINENO}: checking if mkdir takes one argument" >&5 $as_echo_n "checking if mkdir takes one argument... " >&6; } @@ -11255,6 +11104,11 @@ if test x"$tmake_file" = x then tmake_file=$cpu_type/t-$cpu_type fi +# Support --enable-initfini-array. +if test x$enable_initfini_array != xno; then + tm_file="${tm_file} initfini-array.h" +fi + if test x"$dwarf2" = xyes then tm_file="$tm_file tm-dwarf2.h" fi @@ -18116,7 +17970,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 18119 "configure" +#line 17973 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -18222,7 +18076,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 18225 "configure" +#line 18079 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -22496,6 +22350,130 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_ro_rw_mix" >&5 $as_echo "$gcc_cv_ld_ro_rw_mix" >&6; } +# Check whether --enable-initfini-array was given. +if test "${enable_initfini_array+set}" = set; then : + enableval=$enable_initfini_array; +else + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .preinit_array/.init_array/.fini_array support" >&5 +$as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6; } +if test "${gcc_cv_initfini_array+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then + case "${target}" in + ia64-*) + if test "$cross_compiling" = yes; then : + gcc_cv_initfini_array=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifndef __ELF__ +#error Not an ELF OS +#endif +/* We turn on .preinit_array/.init_array/.fini_array support for ia64 + if it can be used. */ +static int x = -1; +int main (void) { return x; } +int foo (void) { x = 0; } +int (*fp) (void) __attribute__ ((section (".init_array"))) = foo; + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gcc_cv_initfini_array=yes +else + gcc_cv_initfini_array=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +;; + *) + gcc_cv_initfini_array=no + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 \ + -a "$gcc_cv_gld_minor_version" -ge 22 \ + -o "$gcc_cv_gld_major_version" -gt 2 \ + && test $in_tree_ld_is_elf = yes; then + gcc_cv_initfini_array=yes + fi + elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then + cat > conftest.s <<\EOF +.section .dtors,"a",%progbits +.balign 4 +.byte 'A', 'A', 'A', 'A' +.section .ctors,"a",%progbits +.balign 4 +.byte 'B', 'B', 'B', 'B' +.section .fini_array.65530,"a",%progbits +.balign 4 +.byte 'C', 'C', 'C', 'C' +.section .init_array.65530,"a",%progbits +.balign 4 +.byte 'D', 'D', 'D', 'D' +.section .dtors.64528,"a",%progbits +.balign 4 +.byte 'E', 'E', 'E', 'E' +.section .ctors.64528,"a",%progbits +.balign 4 +.byte 'F', 'F', 'F', 'F' +.section .fini_array.01005,"a",%progbits +.balign 4 +.byte 'G', 'G', 'G', 'G' +.section .init_array.01005,"a",%progbits +.balign 4 +.byte 'H', 'H', 'H', 'H' +.text +EOF + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -e 0 -o conftest conftest.o > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .init_array conftest \ + | grep HHHHFFFFDDDDBBBB > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .fini_array conftest \ + | grep GGGGEEEECCCCAAAA > /dev/null 2>&1; then + gcc_cv_initfini_array=yes + fi + rm -f conftest conftest.* + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifndef __ELF__ +#error Not an ELF OS +#endif +#include <stdlib.h> +#if defined __GLIBC_PREREQ && __GLIBC_PREREQ (2, 4) +#else +#error The C library not known to support .init_array/.fini_array +#endif + +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + gcc_cv_initfini_array=no +fi +rm -f conftest.err conftest.$ac_ext;; + esac + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking cross compile... guessing" >&5 +$as_echo_n "checking cross compile... guessing... " >&6; } + gcc_cv_initfini_array=no + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5 +$as_echo "$gcc_cv_initfini_array" >&6; } + enable_initfini_array=$gcc_cv_initfini_array + +fi + +if test $enable_initfini_array = yes; then + +$as_echo "#define HAVE_INITFINI_ARRAY 1" >>confdefs.h + +fi + # Check if we have .[us]leb128, and support symbol arithmetic with it. { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .sleb128 and .uleb128" >&5 $as_echo_n "checking assembler for .sleb128 and .uleb128... " >&6; } diff --git a/gcc/configure.ac b/gcc/configure.ac index 01e37b38b6e..d72be3c5b58 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1197,8 +1197,6 @@ fi CFLAGS="$saved_CFLAGS" CXXFLAGS="$saved_CXXFLAGS" -gcc_AC_INITFINI_ARRAY - # mkdir takes a single argument on some systems. gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG @@ -1271,6 +1269,11 @@ if test x"$tmake_file" = x then tmake_file=$cpu_type/t-$cpu_type fi +# Support --enable-initfini-array. +if test x$enable_initfini_array != xno; then + tm_file="${tm_file} initfini-array.h" +fi + if test x"$dwarf2" = xyes then tm_file="$tm_file tm-dwarf2.h" fi @@ -2422,6 +2425,8 @@ if test x$gcc_cv_ld_ro_rw_mix = xread-write; then fi AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix) +gcc_AC_INITFINI_ARRAY + # Check if we have .[us]leb128, and support symbol arithmetic with it. gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128, [elf,2,11,0],, diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e90f8331204..610baa2ede2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +2012-01-19 Kai Tietz <ktietz@redhat.com> + + PR c++/51344 + * decl2.c (save_template_attributes): Use merge_attributes + instead of chaining up via TREE_CHAIN. + +2012-01-19 Jason Merrill <jason@redhat.com> + + PR c++/51889 + * class.c (finish_struct): Call add_method here for function usings. + * semantics.c (finish_member_declaration): Not here. + +2012-01-18 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/51225 + * typeck2.c (store_init_value): Within a template guard + cxx_constant_value with require_potential_constant_expression. + * pt.c (convert_nontype_argument): Likewise. + 2012-01-16 Jakub Jelinek <jakub@redhat.com> PR c++/51854 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9b957fec36f..e6f33fe47ac 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6195,6 +6195,18 @@ finish_struct (tree t, tree attributes) if (DECL_PURE_VIRTUAL_P (x)) VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x); complete_vars (t); + /* We need to add the target functions to the CLASSTYPE_METHOD_VEC if + an enclosing scope is a template class, so that this function be + found by lookup_fnfields_1 when the using declaration is not + instantiated yet. */ + for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) + if (TREE_CODE (x) == USING_DECL) + { + tree fn = strip_using_decl (x); + if (is_overloaded_fn (fn)) + for (; fn; fn = OVL_NEXT (fn)) + add_method (t, OVL_CURRENT (fn), x); + } /* Remember current #pragma pack value. */ TYPE_PRECISION (t) = maximum_field_alignment; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 270fe54bcef..f51790c551d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1199,9 +1199,9 @@ save_template_attributes (tree *attr_p, tree *decl_p) old_attrs = *q; - /* Place the late attributes at the beginning of the attribute + /* Merge the late attributes at the beginning with the attribute list. */ - TREE_CHAIN (tree_last (late_attrs)) = *q; + late_attrs = merge_attributes (late_attrs, *q); *q = late_attrs; if (!DECL_P (*decl_p) && *decl_p == TYPE_MAIN_VARIANT (*decl_p)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f2b4c8e0319..87ec5f5103e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5807,6 +5807,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) if (complain & tf_error) { int errs = errorcount, warns = warningcount; + if (processing_template_decl + && !require_potential_constant_expression (expr)) + return NULL_TREE; expr = cxx_constant_value (expr); if (errorcount > errs || warningcount > warns) inform (EXPR_LOC_OR_HERE (expr), diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 40676b6b809..a5a10d02c89 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2671,20 +2671,6 @@ finish_member_declaration (tree decl) { if (TREE_CODE (decl) == USING_DECL) { - /* We need to add the target functions to the - CLASSTYPE_METHOD_VEC if an enclosing scope is a template - class, so that this function be found by lookup_fnfields_1 - when the using declaration is not instantiated yet. */ - - tree target_decl = strip_using_decl (decl); - if (dependent_type_p (current_class_type) - && is_overloaded_fn (target_decl)) - { - tree t = target_decl; - for (; t; t = OVL_NEXT (t)) - add_method (current_class_type, OVL_CURRENT (t), decl); - } - /* For now, ignore class-scope USING_DECLS, so that debugging backends do not see them. */ DECL_IGNORED_P (decl) = 1; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index a1b4274bdb1..7793744ae4f 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -718,8 +718,14 @@ store_init_value (tree decl, tree init, VEC(tree,gc)** cleanups, int flags) value = fold_non_dependent_expr (value); value = maybe_constant_init (value); if (DECL_DECLARED_CONSTEXPR_P (decl)) - /* Diagnose a non-constant initializer for constexpr. */ - value = cxx_constant_value (value); + { + /* Diagnose a non-constant initializer for constexpr. */ + if (processing_template_decl + && !require_potential_constant_expression (value)) + value = error_mark_node; + else + value = cxx_constant_value (value); + } const_init = (reduced_constant_expression_p (value) || error_operand_p (value)); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init; diff --git a/gcc/df-problems.c b/gcc/df-problems.c index 89284541394..f9b0bc1d872 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -2748,10 +2748,12 @@ df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED) /* Remove all of the REG_DEAD or REG_UNUSED notes from INSN and add - them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES. */ + them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES. Remove also + REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE + as the bitmap of currently live registers. */ static void -df_kill_notes (rtx insn) +df_kill_notes (rtx insn, bitmap live) { rtx *pprev = ®_NOTES (insn); rtx link = *pprev; @@ -2798,6 +2800,45 @@ df_kill_notes (rtx insn) } break; + case REG_EQUAL: + case REG_EQUIV: + { + /* Remove the notes that refer to dead registers. As we have at most + one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note + so we need to purge the complete EQ_USES vector when removing + the note using df_notes_rescan. */ + df_ref *use_rec; + bool deleted = false; + + for (use_rec = DF_INSN_EQ_USES (insn); *use_rec; use_rec++) + { + df_ref use = *use_rec; + if (DF_REF_REGNO (use) > FIRST_PSEUDO_REGISTER + && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE) + && ! bitmap_bit_p (live, DF_REF_REGNO (use))) + { + deleted = true; + break; + } + } + if (deleted) + { + rtx next; +#ifdef REG_DEAD_DEBUGGING + df_print_note ("deleting: ", insn, link); +#endif + next = XEXP (link, 1); + free_EXPR_LIST_node (link); + *pprev = link = next; + df_notes_rescan (insn); + } + else + { + pprev = &XEXP (link, 1); + link = *pprev; + } + break; + } default: pprev = &XEXP (link, 1); link = *pprev; @@ -3299,7 +3340,7 @@ df_note_bb_compute (unsigned int bb_index, debug_insn = DEBUG_INSN_P (insn); bitmap_clear (do_not_gen); - df_kill_notes (insn); + df_kill_notes (insn, live); /* Process the defs. */ if (CALL_P (insn)) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index f53576085f9..22828efefdc 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,21 @@ +2012-01-20 Tobias Burnus <burnus@net-b.de> + Janus Weil <janus@gcc.gnu.org> + + PR fortran/51056 + * module.c (load_needed, read_module): Don't mark __vtab etc. + as use_only. + +2012-01-19 Tobias Burnus <burnus@net-b.de> + + PR fortran/51904 + * expr.c (gfc_build_intrinsic_call): Also set the symtree. + +2012-01-18 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/51634 + * trans-expr.c (gfc_conv_procedure_call): Deallocate allocatable + components of temporary class arguments. + 2012-01-17 Tobias Burnus <burnus@net-b.de> Janne Blomqvist <jb@gcc.gnu.org> @@ -24,6 +42,26 @@ * trans-decl.c (gfc_get_symbol_decl): Mark __vtab and __def_init as TREE_READONLY. +2012-01-16 Zydrunas Gimbutas <gimbutas@cims.nyu.edu> + Andreas Kloeckner <kloeckner@cims.nyu.edu> + Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/48426 + * gfortran.h (gfc_option_t): Add members flag_*_kind to store kind. + * lang.opt: Add options -freal-4-real-8, -freal-4-real-10, + -freal-4-real-16, -freal-8-real-4, -freal-8-real-10, -freal-8-real-16 + and -finteger-4-integer-8. User-desired type conversion information. + * decl.c (gfc_match_old_kind_spec,kind_expr): Type conversions + in declaration parsing. + * trans-types.c (gfc_init_kinds): User-specified type conversion + checked for current backend. + * primary.c (match_integer_constant,match_real_constant): Implement + type conversion in constant parsing. + * options.c (gfc_init_options,gfc_handle_option): Translate input + options to flags in internal options data structure. + * invoke.texi: Document new options. Re-order options in Options + summary section. + 2012-01-16 Paul Thomas <pault@gcc.gnu.org> * trans-array.c (gfc_trans_create_temp_array): In the case of a diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 8f04c731077..7cea780693d 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -4519,6 +4519,11 @@ gfc_build_intrinsic_call (const char* name, locus where, unsigned numarg, ...) result->value.function.name = name; result->value.function.isym = isym; + result->symtree = gfc_find_symtree (gfc_current_ns->sym_root, name); + gcc_assert (result->symtree + && (result->symtree->n.sym->attr.flavor == FL_PROCEDURE + || result->symtree->n.sym->attr.flavor == FL_UNKNOWN)); + va_start (ap, numarg); atail = NULL; for (i = 0; i < numarg; ++i) diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 0616a8591f1..b2808d4d9d9 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -4351,7 +4351,11 @@ load_needed (pointer_info *p) mio_symbol (sym); sym->attr.use_assoc = 1; - if (only_flag) + + /* Mark as only or rename for later diagnosis for explicitly imported + but not used warnings; don't mark internal symbols such as __vtab, + __def_init etc. */ + if (only_flag && sym->name[0] != '_' && sym->name[1] != '_') sym->attr.use_only = 1; if (p->u.rsym.renamed) sym->attr.use_rename = 1; @@ -4574,8 +4578,9 @@ read_module (void) p = name; /* Exception: Always import vtabs & vtypes. */ - if (p == NULL && (strncmp (name, "__vtab_", 5) == 0 - || strncmp (name, "__vtype_", 6) == 0)) + if (p == NULL && name[0] == '_' + && (strncmp (name, "__vtab_", 5) == 0 + || strncmp (name, "__vtype_", 6) == 0)) p = name; /* Skip symtree nodes not in an ONLY clause, unless there @@ -4641,7 +4646,10 @@ read_module (void) if (strcmp (name, p) != 0) sym->attr.use_rename = 1; - sym->attr.use_only = only_flag; + if (name[0] != '_' + || (strncmp (name, "__vtab_", 5) != 0 + && strncmp (name, "__vtype_", 6) != 0)) + sym->attr.use_only = only_flag; /* Store the symtree pointing to this symbol. */ info->u.rsym.symtree = st; diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index b41935add47..15b6797c12b 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -3736,7 +3736,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, /* Allocated allocatable components of derived types must be deallocated for non-variable scalars. Non-variable arrays are dealt with in trans-array.c(gfc_conv_array_parameter). */ - if (e && e->ts.type == BT_DERIVED + if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS) && e->ts.u.derived->attr.alloc_comp && !(e->symtree && e->symtree->n.sym->attr.pointer) && (e->expr_type != EXPR_VARIABLE && !e->rank)) @@ -3768,6 +3768,16 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, gfc_add_expr_to_block (&se->post, local_tmp); } + if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS) + { + /* The derived type is passed to gfc_deallocate_alloc_comp. + Therefore, class actuals can handled correctly but derived + types passed to class formals need the _data component. */ + tmp = gfc_class_data_get (tmp); + if (!CLASS_DATA (fsym)->attr.dimension) + tmp = build_fold_indirect_ref_loc (input_location, tmp); + } + tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank); gfc_add_expr_to_block (&se->post, tmp); diff --git a/gcc/function.c b/gcc/function.c index fcb79f5d1b8..94e51f401c3 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1737,7 +1737,7 @@ instantiate_virtual_regs_in_insn (rtx insn) if (!check_asm_operands (PATTERN (insn))) { error_for_asm (insn, "impossible constraint in %<asm%>"); - delete_insn (insn); + delete_insn_and_edges (insn); } } else diff --git a/gcc/ira-build.c b/gcc/ira-build.c index 2d8708a4e65..78d0b36acda 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -93,15 +93,35 @@ int ira_copies_num; basic block. */ static int last_basic_block_before_change; -/* The following function allocates the loop tree nodes. If LOOPS_P - is FALSE, the nodes corresponding to the loops (except the root - which corresponds the all function) will be not allocated but nodes - will still be allocated for basic blocks. */ +/* Initialize some members in loop tree node NODE. Use LOOP_NUM for + the member loop_num. */ static void -create_loop_tree_nodes (bool loops_p) +init_loop_tree_node (struct ira_loop_tree_node *node, int loop_num) +{ + int max_regno = max_reg_num (); + + node->regno_allocno_map + = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) * max_regno); + memset (node->regno_allocno_map, 0, sizeof (ira_allocno_t) * max_regno); + memset (node->reg_pressure, 0, sizeof (node->reg_pressure)); + node->all_allocnos = ira_allocate_bitmap (); + node->modified_regnos = ira_allocate_bitmap (); + node->border_allocnos = ira_allocate_bitmap (); + node->local_copies = ira_allocate_bitmap (); + node->loop_num = loop_num; + node->children = NULL; + node->subloops = NULL; +} + + +/* The following function allocates the loop tree nodes. If + CURRENT_LOOPS is NULL, the nodes corresponding to the loops (except + the root which corresponds the all function) will be not allocated + but nodes will still be allocated for basic blocks. */ +static void +create_loop_tree_nodes (void) { unsigned int i, j; - int max_regno; bool skip_p; edge_iterator ei; edge e; @@ -122,17 +142,21 @@ create_loop_tree_nodes (bool loops_p) ira_bb_nodes[i].border_allocnos = NULL; ira_bb_nodes[i].local_copies = NULL; } + if (current_loops == NULL) + { + ira_loop_nodes = ((struct ira_loop_tree_node *) + ira_allocate (sizeof (struct ira_loop_tree_node))); + init_loop_tree_node (ira_loop_nodes, 0); + return; + } ira_loop_nodes = ((struct ira_loop_tree_node *) ira_allocate (sizeof (struct ira_loop_tree_node) * VEC_length (loop_p, ira_loops.larray))); - max_regno = max_reg_num (); FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) { if (loop != ira_loops.tree_root) { ira_loop_nodes[i].regno_allocno_map = NULL; - if (! loops_p) - continue; skip_p = false; FOR_EACH_EDGE (e, ei, loop->header->preds) if (e->src != loop->latch @@ -154,16 +178,7 @@ create_loop_tree_nodes (bool loops_p) if (skip_p) continue; } - ira_loop_nodes[i].regno_allocno_map - = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) * max_regno); - memset (ira_loop_nodes[i].regno_allocno_map, 0, - sizeof (ira_allocno_t) * max_regno); - memset (ira_loop_nodes[i].reg_pressure, 0, - sizeof (ira_loop_nodes[i].reg_pressure)); - ira_loop_nodes[i].all_allocnos = ira_allocate_bitmap (); - ira_loop_nodes[i].modified_regnos = ira_allocate_bitmap (); - ira_loop_nodes[i].border_allocnos = ira_allocate_bitmap (); - ira_loop_nodes[i].local_copies = ira_allocate_bitmap (); + init_loop_tree_node (&ira_loop_nodes[i], loop->num); } } @@ -175,10 +190,11 @@ more_one_region_p (void) unsigned int i; loop_p loop; - FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) - if (ira_loop_nodes[i].regno_allocno_map != NULL - && ira_loop_tree_root != &ira_loop_nodes[i]) - return true; + if (current_loops != NULL) + FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) + if (ira_loop_nodes[i].regno_allocno_map != NULL + && ira_loop_tree_root != &ira_loop_nodes[i]) + return true; return false; } @@ -205,8 +221,11 @@ finish_loop_tree_nodes (void) unsigned int i; loop_p loop; - FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) - finish_loop_tree_node (&ira_loop_nodes[i]); + if (current_loops == NULL) + finish_loop_tree_node (&ira_loop_nodes[0]); + else + FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) + finish_loop_tree_node (&ira_loop_nodes[i]); ira_free (ira_loop_nodes); for (i = 0; i < (unsigned int) last_basic_block_before_change; i++) { @@ -227,30 +246,39 @@ finish_loop_tree_nodes (void) /* The following recursive function adds LOOP to the loop tree - hierarchy. LOOP is added only once. */ + hierarchy. LOOP is added only once. If LOOP is NULL we adding + loop designating the whole function when CFG loops are not + built. */ static void add_loop_to_tree (struct loop *loop) { + int loop_num; struct loop *parent; ira_loop_tree_node_t loop_node, parent_node; /* We can not use loop node access macros here because of potential checking and because the nodes are not initialized enough yet. */ - if (loop_outer (loop) != NULL) + if (loop != NULL && loop_outer (loop) != NULL) add_loop_to_tree (loop_outer (loop)); - if (ira_loop_nodes[loop->num].regno_allocno_map != NULL - && ira_loop_nodes[loop->num].children == NULL) + loop_num = loop != NULL ? loop->num : 0; + if (ira_loop_nodes[loop_num].regno_allocno_map != NULL + && ira_loop_nodes[loop_num].children == NULL) { /* We have not added loop node to the tree yet. */ - loop_node = &ira_loop_nodes[loop->num]; + loop_node = &ira_loop_nodes[loop_num]; loop_node->loop = loop; loop_node->bb = NULL; - for (parent = loop_outer (loop); - parent != NULL; - parent = loop_outer (parent)) - if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) - break; + if (loop == NULL) + parent = NULL; + else + { + for (parent = loop_outer (loop); + parent != NULL; + parent = loop_outer (parent)) + if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) + break; + } if (parent == NULL) { loop_node->next = NULL; @@ -299,21 +327,13 @@ setup_loop_tree_level (ira_loop_tree_node_t loop_node, int level) static void form_loop_tree (void) { - unsigned int i; basic_block bb; struct loop *parent; ira_loop_tree_node_t bb_node, loop_node; - loop_p loop; /* We can not use loop/bb node access macros because of potential checking and because the nodes are not initialized enough yet. */ - FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) - if (ira_loop_nodes[i].regno_allocno_map != NULL) - { - ira_loop_nodes[i].children = NULL; - ira_loop_nodes[i].subloops = NULL; - } FOR_EACH_BB (bb) { bb_node = &ira_bb_nodes[bb->index]; @@ -323,18 +343,23 @@ form_loop_tree (void) bb_node->children = NULL; bb_node->subloop_next = NULL; bb_node->next = NULL; - for (parent = bb->loop_father; - parent != NULL; - parent = loop_outer (parent)) - if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) - break; + if (current_loops == NULL) + parent = NULL; + else + { + for (parent = bb->loop_father; + parent != NULL; + parent = loop_outer (parent)) + if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) + break; + } add_loop_to_tree (parent); - loop_node = &ira_loop_nodes[parent->num]; + loop_node = &ira_loop_nodes[parent == NULL ? 0 : parent->num]; bb_node->next = loop_node->children; bb_node->parent = loop_node; loop_node->children = bb_node; } - ira_loop_tree_root = IRA_LOOP_NODE_BY_INDEX (ira_loops.tree_root->num); + ira_loop_tree_root = IRA_LOOP_NODE_BY_INDEX (0); ira_loop_tree_height = setup_loop_tree_level (ira_loop_tree_root, 0); ira_assert (ira_loop_tree_root->regno_allocno_map != NULL); } @@ -353,6 +378,7 @@ rebuild_regno_allocno_maps (void) loop_p loop; ira_allocno_iterator ai; + ira_assert (current_loops != NULL); max_regno = max_reg_num (); FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, l, loop) if (ira_loop_nodes[l].regno_allocno_map != NULL) @@ -837,7 +863,7 @@ ira_print_expanded_allocno (ira_allocno_t a) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) fprintf (ira_dump_file, ",b%d", bb->index); else - fprintf (ira_dump_file, ",l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); + fprintf (ira_dump_file, ",l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num); if (ALLOCNO_CAP_MEMBER (a) != NULL) { fprintf (ira_dump_file, ":"); @@ -1621,6 +1647,7 @@ create_loop_tree_node_allocnos (ira_loop_tree_node_t loop_node) edge e; VEC (edge, heap) *edges; + ira_assert (current_loops != NULL); FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds) if (e->src != loop_node->loop->latch) create_loop_allocnos (e); @@ -1848,7 +1875,7 @@ loop_compare_func (const void *v1p, const void *v2p) if ((diff = (int) loop_depth (l1->loop) - (int) loop_depth (l2->loop)) != 0) return diff; /* Make sorting stable. */ - return l1->loop->num - l2->loop->num; + return l1->loop_num - l2->loop_num; } /* Mark loops which should be removed from regional allocation. We @@ -1870,6 +1897,7 @@ mark_loops_for_removal (void) ira_loop_tree_node_t *sorted_loops; loop_p loop; + ira_assert (current_loops != NULL); sorted_loops = (ira_loop_tree_node_t *) ira_allocate (sizeof (ira_loop_tree_node_t) * VEC_length (loop_p, @@ -1900,7 +1928,7 @@ mark_loops_for_removal (void) fprintf (ira_dump_file, " Mark loop %d (header %d, freq %d, depth %d) for removal (%s)\n", - sorted_loops[i]->loop->num, sorted_loops[i]->loop->header->index, + sorted_loops[i]->loop_num, sorted_loops[i]->loop->header->index, sorted_loops[i]->loop->header->frequency, loop_depth (sorted_loops[i]->loop), low_pressure_loop_node_p (sorted_loops[i]->parent) @@ -1917,6 +1945,7 @@ mark_all_loops_for_removal (void) int i; loop_p loop; + ira_assert (current_loops != NULL); FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) if (ira_loop_nodes[i].regno_allocno_map != NULL) { @@ -1931,7 +1960,7 @@ mark_all_loops_for_removal (void) fprintf (ira_dump_file, " Mark loop %d (header %d, freq %d, depth %d) for removal\n", - ira_loop_nodes[i].loop->num, + ira_loop_nodes[i].loop_num, ira_loop_nodes[i].loop->header->index, ira_loop_nodes[i].loop->header->frequency, loop_depth (ira_loop_nodes[i].loop)); @@ -2221,6 +2250,8 @@ remove_low_level_allocnos (void) static void remove_unnecessary_regions (bool all_p) { + if (current_loops == NULL) + return; if (all_p) mark_all_loops_for_removal (); else @@ -3026,23 +3057,20 @@ update_conflict_hard_reg_costs (void) } /* Create a internal representation (IR) for IRA (allocnos, copies, - loop tree nodes). If LOOPS_P is FALSE the nodes corresponding to - the loops (except the root which corresponds the all function) and - correspondingly allocnos for the loops will be not created. Such - parameter value is used for Chaitin-Briggs coloring. The function - returns TRUE if we generate loop structure (besides nodes - representing all function and the basic blocks) for regional - allocation. A true return means that we really need to flatten IR - before the reload. */ + loop tree nodes). The function returns TRUE if we generate loop + structure (besides nodes representing all function and the basic + blocks) for regional allocation. A true return means that we + really need to flatten IR before the reload. */ bool -ira_build (bool loops_p) +ira_build (void) { - df_analyze (); + bool loops_p; + df_analyze (); initiate_cost_vectors (); initiate_allocnos (); initiate_copies (); - create_loop_tree_nodes (loops_p); + create_loop_tree_nodes (); form_loop_tree (); create_allocnos (); ira_costs (); @@ -3111,8 +3139,8 @@ ira_build (bool loops_p) } } fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n", - VEC_length (loop_p, ira_loops.larray), n_basic_blocks, - ira_max_point); + current_loops == NULL ? 1 : VEC_length (loop_p, ira_loops.larray), + n_basic_blocks, ira_max_point); fprintf (ira_dump_file, " allocnos=%d (big %d), copies=%d, conflicts=%d, ranges=%d\n", ira_allocnos_num, nr_big, ira_copies_num, n, nr); diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 92f68bf0f19..c638e58f333 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -1670,7 +1670,6 @@ assign_hard_reg (ira_allocno_t a, bool retry_p) update_conflict_hard_regno_costs (full_costs, aclass, false); } min_cost = min_full_cost = INT_MAX; - /* We don't care about giving callee saved registers to allocnos no living through calls because call clobbered registers are allocated first (it is usual practice to put them first in @@ -2011,7 +2010,7 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p) edge e; VEC (edge, heap) *edges; - ira_assert (loop_node->loop != NULL + ira_assert (current_loops != NULL && loop_node->loop != NULL && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)); freq = 0; if (! exit_p) @@ -2662,14 +2661,19 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node) edge e; edge_iterator ei; - ira_assert (loop_tree_node->loop != NULL); - fprintf (ira_dump_file, - "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:", - loop_tree_node->loop->num, - (loop_tree_node->parent == NULL - ? -1 : loop_tree_node->parent->loop->num), - loop_tree_node->loop->header->index, - loop_depth (loop_tree_node->loop)); + if (loop_tree_node->parent == NULL) + fprintf (ira_dump_file, + "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:", + NUM_FIXED_BLOCKS); + else + { + ira_assert (current_loops != NULL && loop_tree_node->loop != NULL); + fprintf (ira_dump_file, + "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:", + loop_tree_node->loop_num, loop_tree_node->parent->loop_num, + loop_tree_node->loop->header->index, + loop_depth (loop_tree_node->loop)); + } for (subloop_node = loop_tree_node->children; subloop_node != NULL; subloop_node = subloop_node->next) @@ -2681,7 +2685,7 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node) && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent) != loop_tree_node)) fprintf (ira_dump_file, "(->%d:l%d)", - e->dest->index, dest_loop_node->loop->num); + e->dest->index, dest_loop_node->loop_num); } fprintf (ira_dump_file, "\n all:"); EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi) @@ -3011,7 +3015,7 @@ move_spill_restore (void) fprintf (ira_dump_file, " Moving spill/restore for a%dr%d up from loop %d", - ALLOCNO_NUM (a), regno, loop_node->loop->num); + ALLOCNO_NUM (a), regno, loop_node->loop_num); fprintf (ira_dump_file, " - profit %d\n", -cost); } changed_p = true; diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index f2f13114f38..a0d36094ed5 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -419,6 +419,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, { ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)]; ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)]; + if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2) { cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn, @@ -765,7 +766,7 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) fprintf (file, "b%d", bb->index); else - fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); + fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num); putc (')', file); } @@ -796,7 +797,7 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a) fprintf (file, ",b%d", bb->index); else fprintf (file, ",l%d", - ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num); + ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num); putc (')', file); } } diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 4f2f8412f7c..8e1e8466437 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -1391,7 +1391,7 @@ print_allocno_costs (FILE *f) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) fprintf (f, "b%d", bb->index); else - fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); + fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num); fprintf (f, ") costs:"); for (k = 0; k < cost_classes_ptr->num; k++) { @@ -1789,7 +1789,7 @@ find_costs_and_classes (FILE *dump_file) fprintf (dump_file, "b%d", bb->index); else fprintf (dump_file, "l%d", - ALLOCNO_LOOP_TREE_NODE (a)->loop->num); + ALLOCNO_LOOP_TREE_NODE (a)->loop_num); fprintf (dump_file, ") best %s, allocno %s\n", reg_class_names[best], reg_class_names[regno_aclass[i]]); diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c index 01a94420aa8..3dcd3241cfc 100644 --- a/gcc/ira-emit.c +++ b/gcc/ira-emit.c @@ -438,6 +438,7 @@ setup_entered_from_non_parent_p (void) unsigned int i; loop_p loop; + ira_assert (current_loops != NULL); FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) if (ira_loop_nodes[i].regno_allocno_map != NULL) ira_loop_nodes[i].entered_from_non_parent_p @@ -565,7 +566,8 @@ change_loop (ira_loop_tree_node_t node) if (node != ira_loop_tree_root) { - + ira_assert (current_loops != NULL); + if (node->bb != NULL) { FOR_BB_INSNS (node->bb, insn) @@ -580,7 +582,7 @@ change_loop (ira_loop_tree_node_t node) if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL) fprintf (ira_dump_file, " Changing RTL for loop %d (header bb%d)\n", - node->loop->num, node->loop->header->index); + node->loop_num, node->loop->header->index); parent = ira_curr_loop_tree_node->parent; map = parent->regno_allocno_map; diff --git a/gcc/ira-int.h b/gcc/ira-int.h index 61998942d9e..9faabb5d703 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -87,7 +87,8 @@ struct ira_loop_tree_node { /* The node represents basic block if children == NULL. */ basic_block bb; /* NULL for loop. */ - struct loop *loop; /* NULL for BB. */ + /* NULL for BB or for loop tree root if we did not build CFG loop tree. */ + struct loop *loop; /* NEXT/SUBLOOP_NEXT is the next node/loop-node of the same parent. SUBLOOP_NEXT is always NULL for BBs. */ ira_loop_tree_node_t subloop_next, next; @@ -103,6 +104,9 @@ struct ira_loop_tree_node /* All the following members are defined only for nodes representing loops. */ + /* The loop number from CFG loop tree. The root number is 0. */ + int loop_num; + /* True if the loop was marked for removal from the register allocation. */ bool to_remove_p; @@ -154,7 +158,7 @@ extern ira_loop_tree_node_t ira_bb_nodes; /* Two access macros to the nodes representing basic blocks. */ #if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007) #define IRA_BB_NODE_BY_INDEX(index) __extension__ \ -(({ ira_loop_tree_node_t _node = (&ira_bb_nodes[index]); \ +(({ ira_loop_tree_node_t _node = (&ira_bb_nodes[index]); \ if (_node->children != NULL || _node->loop != NULL || _node->bb == NULL)\ { \ fprintf (stderr, \ @@ -176,8 +180,9 @@ extern ira_loop_tree_node_t ira_loop_nodes; /* Two access macros to the nodes representing loops. */ #if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007) #define IRA_LOOP_NODE_BY_INDEX(index) __extension__ \ -(({ ira_loop_tree_node_t const _node = (&ira_loop_nodes[index]);\ - if (_node->children == NULL || _node->bb != NULL || _node->loop == NULL)\ +(({ ira_loop_tree_node_t const _node = (&ira_loop_nodes[index]); \ + if (_node->children == NULL || _node->bb != NULL \ + || (_node->loop == NULL && current_loops != NULL)) \ { \ fprintf (stderr, \ "\n%s: %d: error in %s: it is not a loop node\n", \ @@ -989,7 +994,7 @@ extern int *ira_allocate_cost_vector (reg_class_t); extern void ira_free_cost_vector (int *, reg_class_t); extern void ira_flattening (int, int); -extern bool ira_build (bool); +extern bool ira_build (void); extern void ira_destroy (void); /* ira-costs.c */ diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index 9af2f93db95..f639e12449b 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -1123,7 +1123,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) fprintf (ira_dump_file, " Insn %u(l%d): point = %d\n", - INSN_UID (insn), loop_tree_node->parent->loop->num, + INSN_UID (insn), loop_tree_node->parent->loop_num, curr_point); /* Mark each defined value as live. We need to do this for diff --git a/gcc/ira.c b/gcc/ira.c index 6db79097c2e..a632284de88 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -718,7 +718,7 @@ ira_print_disposition (FILE *f) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) fprintf (f, "b%-3d", bb->index); else - fprintf (f, "l%-3d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); + fprintf (f, "l%-3d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num); if (ALLOCNO_HARD_REGNO (a) >= 0) fprintf (f, " %3d", ALLOCNO_HARD_REGNO (a)); else @@ -3614,14 +3614,16 @@ ira (FILE *f) ira_move_loops_num = ira_additional_jumps_num = 0; ira_assert (current_loops == NULL); - flow_loops_find (&ira_loops); - record_loop_exits (); - current_loops = &ira_loops; + if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED) + { + flow_loops_find (&ira_loops); + record_loop_exits (); + current_loops = &ira_loops; + } if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL) fprintf (ira_dump_file, "Building IRA IR\n"); - loops_p = ira_build (flag_ira_region == IRA_REGION_ALL - || flag_ira_region == IRA_REGION_MIXED); + loops_p = ira_build (); ira_assert (ira_conflicts_p || !loops_p); @@ -3745,8 +3747,11 @@ do_reload (void) flag_ira_share_spill_slots = saved_flag_ira_share_spill_slots; - flow_loops_free (&ira_loops); - free_dominance_info (CDI_DOMINATORS); + if (current_loops != NULL) + { + flow_loops_free (&ira_loops); + free_dominance_info (CDI_DOMINATORS); + } FOR_ALL_BB (bb) bb->loop_father = NULL; current_loops = NULL; diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 1cc7bfb843d..6d262e8040b 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -403,6 +403,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options, case OPT_fpie: case OPT_fcommon: case OPT_fexceptions: + case OPT_fgnu_tm: /* Do what the old LTO code did - collect exactly one option setting per OPT code, we pick the first we encounter. ??? This doesn't make too much sense, but when it doesn't @@ -555,6 +556,7 @@ run_gcc (unsigned argc, char *argv[]) case OPT_fpie: case OPT_fcommon: case OPT_fexceptions: + case OPT_fgnu_tm: break; default: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 352f15d99fd..2d42abfb446 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,50 @@ +2012-01-20 Tobias Burnus <burnus@net-b.de> + Janus Weil <janus@gcc.gnu.org> + + PR fortran/51056 + * gfortran.dg/use_21.f90: New. + +2012-01-20 Jakub Jelinek <jakub@redhat.com> + + PR target/51106 + * gcc.dg/torture/pr51106-1.c: New test. + * gcc.dg/torture/pr51106-2.c: New test. + +2012-01-19 Kai Tietz <ktietz@redhat.com> + + * g++.dg/torture/pr51344.C: New test. + +2012-01-19 Tobias Burnus <burnus@net-b.de> + + PR fortran/51904 + * gfortran.dg/intrinsic_size_2.f90: New. + +2012-01-19 Jason Merrill <jason@redhat.com> + + PR c++/51889 + * g++.dg/inherit/using7.C: New. + +2012-01-19 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/37997 + * gcc.dg/tree-ssa/ssa-pre-28.c: New testcase. + +2012-01-19 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/51505 + * gcc.dg/pr51505.c: New test. + +2012-01-18 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/51634 + * gfortran.dg/typebound_operator_12.f03: New. + * gfortran.dg/typebound_operator_13.f03: New. + +2012-01-18 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/51225 + * g++.dg/cpp0x/pr51225.C: New. + 2012-01-17 Ian Lance Taylor <iant@google.com> PR go/50656 diff --git a/gcc/testsuite/g++.dg/cpp0x/pr51225.C b/gcc/testsuite/g++.dg/cpp0x/pr51225.C new file mode 100644 index 00000000000..6fcf8611f9c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr51225.C @@ -0,0 +1,14 @@ +// PR c++/51225 +// { dg-options "-std=c++0x" } + +template<int> struct A {}; + +template<typename> void foo() +{ + A<int(x)> a; // { dg-error "not declared|invalid type" } +} + +template<typename> struct bar +{ + static constexpr A<1> b = A<1>(x); // { dg-error "not declared" } +}; diff --git a/gcc/testsuite/g++.dg/inherit/using7.C b/gcc/testsuite/g++.dg/inherit/using7.C new file mode 100644 index 00000000000..de177c91d21 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/using7.C @@ -0,0 +1,12 @@ +// PR c++/51889 + +struct A { + void f(); +}; + +template <class T> +struct B: A +{ + using A::f; + void f(); +}; diff --git a/gcc/testsuite/g++.dg/torture/pr51344.C b/gcc/testsuite/g++.dg/torture/pr51344.C new file mode 100644 index 00000000000..482c0fae065 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr51344.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +template <class T> +class B +{ + friend __attribute__((cdecl)) A& operator >>(A& a, B& b) + { + return a; + } +}; diff --git a/gcc/testsuite/gcc.dg/lto/trans-mem-3_0.c b/gcc/testsuite/gcc.dg/lto/trans-mem-3_0.c new file mode 100644 index 00000000000..dd578907da0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/trans-mem-3_0.c @@ -0,0 +1,8 @@ +/* { dg-lto-options {{-flto}} } */ +/* { dg-lto-do link } */ + +/* Test that we can build one object file with -fgnu-tm + (trans-mem-3_1.c), but do the final link of all objects without + -fgnu-tm. */ + +int i; diff --git a/gcc/testsuite/gcc.dg/lto/trans-mem-3_1.c b/gcc/testsuite/gcc.dg/lto/trans-mem-3_1.c new file mode 100644 index 00000000000..d907f68384f --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/trans-mem-3_1.c @@ -0,0 +1,18 @@ +/* { dg-options "-fgnu-tm" } */ + +extern int i; + +main() +{ + __transaction_atomic { i = 0; } +} + +#define dummy(func) \ + __attribute__((noinline,noclone,used)) void func() { asm (""); } + +dummy(_ITM_beginTransaction) +dummy(_ITM_commitTransaction) +dummy(_ITM_WU4) +dummy(_ITM_WU8) +dummy(_ITM_registerTMCloneTable) +dummy(_ITM_deregisterTMCloneTable) diff --git a/gcc/testsuite/gcc.dg/pr51505.c b/gcc/testsuite/gcc.dg/pr51505.c new file mode 100644 index 00000000000..dbcd3226d7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr51505.c @@ -0,0 +1,19 @@ +/* PR rtl-optimization/51505 */ +/* { dg-do compile } */ +/* { dg-options "-O --param max-cse-insns=1" } */ +struct S +{ +char a[256]; +}; + +int bar(struct S, char[16]); + +void foo () +{ + struct S u, s1, s2; + char e[256]; + char i; + e[i] = ~s1.a[i] & s2.a[i]; + if (bar(u, e)) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr51106-1.c b/gcc/testsuite/gcc.dg/torture/pr51106-1.c new file mode 100644 index 00000000000..10b3b682b98 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr51106-1.c @@ -0,0 +1,14 @@ +/* PR target/51106 */ +/* { dg-do "compile" } */ +/* { dg-skip-if "RTL error" { "*-*-*" } { "-fno-fat-lto-objects" } { "" } } */ + +int +foo (int x) +{ + asm goto ("" : : "i" (x) : : lab); /* { dg-error "impossible constraint" } */ + return 1; +lab: + return 0; +} + +/* { dg-warning "probably doesn.t match constraints" "" { target *-*-* } 8 } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr51106-2.c b/gcc/testsuite/gcc.dg/torture/pr51106-2.c new file mode 100644 index 00000000000..e69bf1b01ab --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr51106-2.c @@ -0,0 +1,14 @@ +/* PR target/51106 */ +/* { dg-do "compile" } */ +/* { dg-skip-if "RTL error" { "*-*-*" } { "-fno-fat-lto-objects" } { "" } } */ + +int +bar (int x) +{ + asm goto ("" : : "i" (x) : : lab); /* { dg-error "impossible constraint" } */ + __builtin_unreachable (); +lab: + return 0; +} + +/* { dg-warning "probably doesn.t match constraints" "" { target *-*-* } 8 } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-28.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-28.c new file mode 100644 index 00000000000..3c27a1a29f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-28.c @@ -0,0 +1,21 @@ +/* PR37997 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-pre-details" } */ + +int foo (int i, int b, int result) +{ + int mask; + if (b) + mask = -1; + else + mask = 0; + result = i + 1; + result = result & mask; + return result; +} + +/* We should insert i + 1 into the if (b) path as well as the simplified + i + 1 & -1 expression. And do replacement with two PHI temps. */ + +/* { dg-final { scan-tree-dump-times "with prephitmp" 2 "pre" } } */ +/* { dg-final { cleanup-tree-dump "pre" } } */ diff --git a/gcc/testsuite/gfortran.dg/intrinsic_size_2.f90 b/gcc/testsuite/gfortran.dg/intrinsic_size_2.f90 new file mode 100644 index 00000000000..6070bc21b7d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intrinsic_size_2.f90 @@ -0,0 +1,17 @@ +! { dg-do compile } +! +! PR fortran/51904 +! +! Contributed by David Sagan. +! + +call qp_draw_polyline_basic([1.0,2.0]) +contains +subroutine qp_draw_polyline_basic (x) + implicit none + real :: x(:), f + integer :: i + f = 0 + print *, size(f*x) +end subroutine +end diff --git a/gcc/testsuite/gfortran.dg/typebound_operator_12.f03 b/gcc/testsuite/gfortran.dg/typebound_operator_12.f03 new file mode 100644 index 00000000000..3496ed38639 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/typebound_operator_12.f03 @@ -0,0 +1,45 @@ +! { dg-do run } +! PR51634 - Handle allocatable components correctly in expressions +! involving typebound operators. See comment 2 of PR. +! +! Reported by Tobias Burnus <burnus@gcc.gnu.org> +! +module soop_stars_class + implicit none + type soop_stars + real, dimension(:), allocatable :: position,velocity + contains + procedure :: total + procedure :: product + generic :: operator(+) => total + generic :: operator(*) => product + end type +contains + type(soop_stars) function product(lhs,rhs) + class(soop_stars) ,intent(in) :: lhs + real ,intent(in) :: rhs + product%position = lhs%position*rhs + product%velocity = lhs%velocity*rhs + end function + + type(soop_stars) function total(lhs,rhs) + class(soop_stars) ,intent(in) :: lhs,rhs + total%position = lhs%position + rhs%position + total%velocity = lhs%velocity + rhs%velocity + end function +end module + +program main + use soop_stars_class ,only : soop_stars + implicit none + type(soop_stars) :: fireworks + real :: dt + fireworks%position = [1,2,3] + fireworks%velocity = [4,5,6] + dt = 5 + fireworks = fireworks + fireworks*dt + if (any (fireworks%position .ne. [6, 12, 18])) call abort + if (any (fireworks%velocity .ne. [24, 30, 36])) call abort +end program +! { dg-final { cleanup-modules "soop_stars_class" } } + diff --git a/gcc/testsuite/gfortran.dg/typebound_operator_13.f03 b/gcc/testsuite/gfortran.dg/typebound_operator_13.f03 new file mode 100644 index 00000000000..e1371c8a817 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/typebound_operator_13.f03 @@ -0,0 +1,59 @@ +! { dg-do run } +! PR51634 - Handle allocatable components correctly in expressions +! involving typebound operators. From comment 2 of PR but using +! classes throughout. +! +! Reported by Tobias Burnus <burnus@gcc.gnu.org> +! +module soop_stars_class + implicit none + type soop_stars + real, dimension(:), allocatable :: position,velocity + contains + procedure :: total + procedure :: mult + procedure :: assign + generic :: operator(+) => total + generic :: operator(*) => mult + generic :: assignment(=) => assign + end type +contains + function mult(lhs,rhs) + class(soop_stars) ,intent(in) :: lhs + real ,intent(in) :: rhs + class(soop_stars), allocatable :: mult + type(soop_stars) :: tmp + tmp = soop_stars (lhs%position*rhs, lhs%velocity*rhs) + allocate (mult, source = tmp) + end function + + function total(lhs,rhs) + class(soop_stars) ,intent(in) :: lhs,rhs + class(soop_stars), allocatable :: total + type(soop_stars) :: tmp + tmp = soop_stars (lhs%position + rhs%position, & + lhs%velocity + rhs%velocity) + allocate (total, source = tmp) + end function + + subroutine assign(lhs,rhs) + class(soop_stars), intent(in) :: rhs + class(soop_stars), intent(out) :: lhs + lhs%position = rhs%position + lhs%velocity = rhs%velocity + end subroutine +end module + +program main + use soop_stars_class ,only : soop_stars + implicit none + class(soop_stars), allocatable :: fireworks + real :: dt + allocate (fireworks, source = soop_stars ([1,2,3], [4,5,6])) + dt = 5 + fireworks = fireworks + fireworks*dt + if (any (fireworks%position .ne. [6, 12, 18])) call abort + if (any (fireworks%velocity .ne. [24, 30, 36])) call abort +end program +! { dg-final { cleanup-modules "soop_stars_class" } } + diff --git a/gcc/testsuite/gfortran.dg/use_21.f90 b/gcc/testsuite/gfortran.dg/use_21.f90 new file mode 100644 index 00000000000..eba412d9d78 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/use_21.f90 @@ -0,0 +1,35 @@ +! { dg-do compile } +! { dg-options "-Wall" } +! +! PR fortran/51056 +! +! Contributed by Kacper Kowalik +! +module domain + implicit none + private + public :: domain_container, dom + + type :: domain_container + integer :: D_x !< set to 1 when x-direction exists, 0 otherwise + contains + procedure :: init => init_domain_container + end type domain_container + + type(domain_container) :: dom + + contains + subroutine init_domain_container(this) + implicit none + class(domain_container), intent(inout) :: this + this%D_x = 0 + end subroutine init_domain_container +end module domain + +program ala + use domain, only: dom + implicit none + call dom%init +end program ala + +! { dg-final { cleanup-modules "domain" } } diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 8b7e51045a9..30dc4b3dee3 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -1496,9 +1496,7 @@ requires_barrier (basic_block entry_block, tree x, gimple stmt) during lower_sequence_tm/gimplification, leave the call to needs_to_live_in_memory until we eliminate lower_sequence_tm altogether. */ - needs_to_live_in_memory (x) - /* X escapes. */ - || is_global_var (x)) + needs_to_live_in_memory (x)) return true; else { diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index 67fea759459..e4f6ec0b331 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -1,5 +1,5 @@ /* Mudflap: narrow-pointer bounds-checking by tree rewriting. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Free Software Foundation, Inc. Contributed by Frank Ch. Eigler <fche@redhat.com> and Graydon Hoare <graydon@redhat.com> @@ -69,6 +69,13 @@ static tree mx_xfn_xform_decls (gimple_stmt_iterator *, bool *, static gimple_seq mx_register_decls (tree, gimple_seq, location_t); static unsigned int execute_mudflap_function_decls (void); +/* Return true if DECL is artificial stub that shouldn't be instrumented by + mf. We should instrument clones of non-artificial functions. */ +static inline bool +mf_artificial (const_tree decl) +{ + return DECL_ARTIFICIAL (DECL_ORIGIN (decl)); +} /* ------------------------------------------------------------------------ */ /* Some generally helpful functions for mudflap instrumentation. */ @@ -412,8 +419,8 @@ execute_mudflap_function_ops (void) /* Don't instrument functions such as the synthetic constructor built during mudflap_finish_file. */ - if (mf_marked_p (current_function_decl) || - DECL_ARTIFICIAL (current_function_decl)) + if (mf_marked_p (current_function_decl) + || mf_artificial (current_function_decl)) return 0; push_gimplify_context (&gctx); @@ -994,8 +1001,8 @@ execute_mudflap_function_decls (void) /* Don't instrument functions such as the synthetic constructor built during mudflap_finish_file. */ - if (mf_marked_p (current_function_decl) || - DECL_ARTIFICIAL (current_function_decl)) + if (mf_marked_p (current_function_decl) + || mf_artificial (current_function_decl)) return 0; push_gimplify_context (&gctx); @@ -1078,7 +1085,7 @@ mx_register_decls (tree decl, gimple_seq seq, location_t location) /* Add the __mf_register call at the current appending point. */ if (gsi_end_p (initially_stmts)) { - if (!DECL_ARTIFICIAL (decl)) + if (!mf_artificial (decl)) warning (OPT_Wmudflap, "mudflap cannot track %qE in stub function", DECL_NAME (decl)); @@ -1249,7 +1256,7 @@ mudflap_enqueue_decl (tree obj) during mudflap_finish_file (). That would confuse the user, since the text would refer to variables that don't show up in the user's source code. */ - if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj)) + if (DECL_P (obj) && DECL_EXTERNAL (obj) && mf_artificial (obj)) return; VEC_safe_push (tree, gc, deferred_static_decls, obj); diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index c28167e41aa..fb2c005e8b7 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1199,10 +1199,6 @@ useless_type_conversion_p (tree outer_type, tree inner_type) if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) return false; - - /* If the outer type is (void *), the conversion is not necessary. */ - if (VOID_TYPE_P (TREE_TYPE (outer_type))) - return true; } /* From now on qualifiers on value types do not matter. */ |