summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-10-24 16:43:32 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-10-24 16:43:32 +0000
commitd68b5255b5b313cf2f63584f1a46e23530592cf6 (patch)
treea9b82c0074f9520554b71249f6d2f1ad28f5a55f /gcc
parent30ab0a1063bf6d5b1125cf73add64ee69a41d00c (diff)
downloadgcc-d68b5255b5b313cf2f63584f1a46e23530592cf6.tar.gz
2009-10-24 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 153531 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@153533 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog293
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/ada/ChangeLog12
-rw-r--r--gcc/ada/gcc-interface/Makefile.in17
-rw-r--r--gcc/ada/gcc-interface/decl.c19
-rw-r--r--gcc/ada/init.c6
-rw-r--r--gcc/alias.c9
-rw-r--r--gcc/builtins.c7
-rw-r--r--gcc/c-common.c9
-rw-r--r--gcc/c-typeck.c8
-rw-r--r--gcc/cfgexpand.c4
-rw-r--r--gcc/cfgloop.h1
-rw-r--r--gcc/cfgloopmanip.c3
-rw-r--r--gcc/cgraphunit.c7
-rw-r--r--gcc/config/avr/avr.c8
-rw-r--r--gcc/config/avr/avr.md48
-rw-r--r--gcc/config/darwin.c11
-rw-r--r--gcc/config/darwin10.h5
-rw-r--r--gcc/config/ia64/ia64.c8
-rw-r--r--gcc/config/m32c/m32c-protos.h3
-rw-r--r--gcc/config/m32c/m32c.c35
-rw-r--r--gcc/config/m32c/m32c.h5
-rw-r--r--gcc/config/rs6000/rs6000.c84
-rw-r--r--gcc/config/rs6000/rs6000.h10
-rw-r--r--gcc/config/sh/sh.c1
-rw-r--r--gcc/cp/ChangeLog26
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/cp/mangle.c11
-rw-r--r--gcc/cp/semantics.c64
-rw-r--r--gcc/cselib.c29
-rw-r--r--gcc/doc/install.texi9
-rw-r--r--gcc/doc/invoke.texi20
-rw-r--r--gcc/fortran/ChangeLog29
-rw-r--r--gcc/fortran/match.c76
-rw-r--r--gcc/fortran/resolve.c89
-rw-r--r--gcc/fortran/symbol.c11
-rw-r--r--gcc/fortran/trans-expr.c2
-rw-r--r--gcc/fortran/trans-intrinsic.c2
-rw-r--r--gcc/gengtype.c2
-rw-r--r--gcc/ipa-cp.c38
-rw-r--r--gcc/ipa-inline.c66
-rw-r--r--gcc/ipa-prop.c314
-rw-r--r--gcc/ipa-prop.h49
-rw-r--r--gcc/ipa-pure-const.c64
-rw-r--r--gcc/ipa-reference.c271
-rw-r--r--gcc/ira-lives.c11
-rw-r--r--gcc/lto-cgraph.c12
-rw-r--r--gcc/lto-streamer-in.c15
-rw-r--r--gcc/lto-streamer-out.c3
-rw-r--r--gcc/lto-streamer.c3
-rw-r--r--gcc/lto-streamer.h4
-rw-r--r--gcc/lto-symtab.c105
-rw-r--r--gcc/lto/ChangeLog20
-rw-r--r--gcc/lto/lto.c38
-rw-r--r--gcc/opts.c1
-rw-r--r--gcc/passes.c6
-rw-r--r--gcc/rtl.c14
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/simplify-rtx.c45
-rw-r--r--gcc/testsuite/ChangeLog109
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle33.C19
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle34.C41
-rw-r--r--gcc/testsuite/g++.dg/abi/rtti3.C1
-rw-r--r--gcc/testsuite/g++.dg/abi/thunk4.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit4.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C31
-rw-r--r--gcc/testsuite/g++.dg/lto/20091022-1_0.C13
-rw-r--r--gcc/testsuite/g++.dg/lto/20091022-2_0.C12
-rw-r--r--gcc/testsuite/g++.dg/opt/vt1.C1
-rw-r--r--gcc/testsuite/g++.dg/template/spec35.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/copyprop.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40556.c11
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-vla-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/autopar/outer-1.c33
-rw-r--r--gcc/testsuite/gcc.dg/autopar/outer-2.c33
-rw-r--r--gcc/testsuite/gcc.dg/autopar/outer-3.c33
-rw-r--r--gcc/testsuite/gcc.dg/autopar/outer-4.c37
-rw-r--r--gcc/testsuite/gcc.dg/autopar/outer-5.c50
-rw-r--r--gcc/testsuite/gcc.dg/autopar/outer-6.c51
-rw-r--r--gcc/testsuite/gcc.dg/noncompile/pr40033-1.c7
-rw-r--r--gcc/testsuite/gcc.dg/tls/pie-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr41497.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-26.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/pic-1.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsx-vrsave.c20
-rw-r--r--gcc/testsuite/gfortran.dg/class_10.f0332
-rw-r--r--gcc/testsuite/gfortran.dg/goto_8.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/transfer_intrinsic_3.f9038
-rw-r--r--gcc/testsuite/gnat.dg/null_pointer_deref1.adb21
-rw-r--r--gcc/testsuite/gnat.dg/null_pointer_deref2.adb28
-rw-r--r--gcc/testsuite/gnat.dg/opt4.adb22
-rw-r--r--gcc/testsuite/gnat.dg/specs/pack4.ads12
-rw-r--r--gcc/tree-cfg.c137
-rw-r--r--gcc/tree-chrec.h1
-rw-r--r--gcc/tree-parloops.c66
-rw-r--r--gcc/tree-scalar-evolution.c15
-rw-r--r--gcc/tree-ssa-alias.c40
-rw-r--r--gcc/tree-ssa-pre.c15
100 files changed, 2575 insertions, 557 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4b96a2f00db..b46a2ef7288 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,296 @@
+ 2009-09-27 Andy Hutchinson <hutchinsonandy@gcc.gnu.org>
+
+ PR middle-end/19154
+ * avr.md (QIDI): Add new mode iterator.
+ (sbrx_branch<mode>): Create new zero extract bit, test and jump
+ patterns for all QI thru DI modes combinations.
+ (sbrx_and_branch<mode>): Create new and based bit test and jump
+ patterns for QI thru SI modes.
+ avr.c (avr_out_sbxx_branch): Use only bit number.
+
+2009-10-24 Jan Hubicka <jh@suse.cz>
+
+ * ipa-reference.c (check_call): Noreturn notrhow calls do not write
+ to memory.
+ (analyze_function): When analyzing noreturn nothrow call, do not compute
+ written stats; free bitmaps of vars early if possible.
+ (generate_summary): Only update bitmaps if computed.
+ (propagate): Only dump bitmaps if computed.
+ (ipa_reference_read_summary): Fix pasto.
+
+2009-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-ssa-alias.c (nonaliasing_component_refs_p): Rename into...
+ (aliasing_component_refs_p): ...this. Return true if there is no
+ common base and the base access types have the same alias set.
+ (indirect_ref_may_alias_decl_p): Adjust for above renaming.
+ (indirect_refs_may_alias_p): Likewise.
+
+2009-10-23 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/40033
+ * c-typeck.c (c_finish_stmt_expr): Do not wrap error_mark_node in
+ a C_MAYBE_CONST_EXPR.
+
+2009-10-23 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/41787
+ * config/rs6000/rs6000.c (struct machine_function): Add
+ vsx_or_altivec_used_p to record if vector types are used.
+ (rs6000_expand_to_rtl_hook): Rename from
+ rs6000_alloc_sdmode_stack_slot. If VSX, check to see if there are
+ any vector operations, so if there are, we can set VRSAVE to
+ non-zero when only floating point vector registers are used.
+ (TARGET_EXPAND_TO_RTL_HOOK): Use rs6000_expand_to_rtl_hook.
+ (rs6000_check_vector_mode): Inner function to check if vector
+ types are used in the code.
+ (compute_vrsave_mask): If VSX, make sure VRSAVE is non-zero if
+ vector instructions are used.
+
+ * config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED):
+ Indicate that VSX registers which overlap floating point
+ registers, can't be used across a call, since the ABI only states
+ the scalar part of the register will be saved and restored.
+
+2009-10-23 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/41673
+ * alias.c (get_alias_set): Call langhook before returning 0 for
+ types with structural equality.
+ * c-common.c (c_common_get_alias_set): Use alias set of element
+ type for arrays with structural comparison.
+
+2009-10-23 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41805
+ * cfgexpand.c (expand_call_stmt): Use gimple_has_side_effects and
+ gimple_call_nothrow_p.
+
+2009-10-23 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/41778
+ * tree-ssa-pre.c (do_regular_insertion): Only insert if a
+ redundancy along a path in the CFG we want to optimize for speed
+ is going to be removed.
+ (execute_pre): Do partial-PRE only if the function is to be
+ optimized for speed.
+ (gate_pre): Do not turn off all of PRE when not optimizing a
+ function for speed.
+
+2009-10-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_cabs): Use validate_arg().
+ (fold_builtin_cexp): Fix if-logic.
+ (fold_builtin_1): Check subtype for BUILT_IN_CIMAG.
+
+2009-10-22 Jeff Law <law@redhat.com>
+
+ * ira-lives.c (process_single_reg_class_operands): Update the
+ hard reg costs for all the hard registers desired by the
+ single reg class operand.
+
+2009-10-22 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * simplify-rtx.c (simplify_replace_fn_rtx): Add a fallback case
+ for rtxes that aren't handled specially.
+
+2009-10-22 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * rtl.h (shallow_copy_rtvec): Declare.
+ * rtl.c (shallow_copy_rtvec): New function.
+ * cselib.c (cselib_subst_to_values): Use it. Only modify an
+ rtx field if the subrtx has changed.
+
+2009-10-22 Anatoly Sokolov <aesok@post.ru>
+
+ * config/m32c/m32c.c (m32c_function_value_regno_p): New function.
+ (m32c_function_value): Make static, add new 'outgoing' argument.
+ (m32c_libcall_value): Make static, add new 'fun' argument.
+ (TARGET_FUNCTION_VALUE, TARGET_LIBCALL_VALUE): Declare.
+ * config/m32c/m32c.h: (FUNCTION_VALUE, LIBCALL_VALUE): Remove.
+ (FUNCTION_VALUE_REGNO_P): Redefine, use m32c_function_value_regno_p.
+ * config/m32c/m32c-protos.h (m32c_function_value_regno_p): Declare.
+ (m32c_function_value, m32c_libcall_value): Delete declaration.
+
+2009-10-22 Diego Novillo <dnovillo@google.com>
+
+ * Makefile.in (PLUGIN_HEADERS): Add output.h and IPA_UTILS_H.
+
+2009-10-22 Razya Ladelsky <razya@il.ibm.com>
+
+ * testsuite/gcc.dg/autopar/outer-4.c: Adjust scan.
+ * testsuite/gcc.dg/autopar/outer-5.c: Adjust scan.
+ * testsuite/gcc.dg/autopar/outer-5.c: Add scan optimized.
+ * tree-cfg.c (gimple_duplicate_sese_tail): Fix typos/indentation/white
+ space.
+
+2009-10-22 Richard Guenther <rguenther@suse.de>
+
+ * lto-streamer.h (lto_symtab_merge_cgraph_nodes): Declare.
+ * lto-symtab.c (struct lto_symtab_entry_def): Add node member.
+ (lto_symtab_merge): Do not merge cgraph nodes here.
+ (lto_symtab_resolve_can_prevail_p): Simplify.
+ (lto_symtab_resolve_symbols): Store cgraph node.
+ (lto_symtab_merge_decls_1): Simplify. Do not drop non-prevailing
+ functions from the symtab.
+ (lto_symtab_merge_cgraph_nodes_1): New function.
+ (lto_symtab_merge_cgraph_nodes): Likewise.
+
+2009-10-22 Richard Guenther <rguenther@suse.de>
+
+ PR lto/41791
+ * lto-streamer-out.c (lto_output_location): Stream the
+ system header flag.
+ * lto-streamer-in.c (lto_input_location): Likewise.
+
+2009-10-22 Razya Ladelsky <razya@il.ibm.com>
+
+ * cfgloopmanip.c (duplicate_subloops): Export.
+ * tree-parloops.c (loop_parallel_p): Dump if loop is innermost.
+ (transform_to_exit_first_loop): Duplicate bbs starting from
+ header up to loop->latch instead of exit->src.
+ Initialize control variable to the correct number of iterations.
+ (gather_scalar_reductions): Do not register double reductions.
+ (parallelize_loops): Dump which loop is tested.
+ Indicate whether the parallelized loop is inner or not.
+ Remove the innermost-loop requirement.
+ * cfgloop.h (duplicate_subloops): Export.
+ * tree-cfg.c (add_phi_args_after_redirect): New function.
+ (gimple_duplicate_sese_tail): Remove the no-subloops constraint.
+ Call duplicate_subloops.
+ Update number of iterations at the exit condition.
+ Don't redirect nexits always to the loop exit.
+ Redirect copied edges from latch to the loop exit.
+ * testsuite/libgomp.graphite/force-parallel-2.c: Adjust scan.
+ * testsuite/gcc.dg/autopar/outer-1.c: New testcase.
+ * testsuite/gcc.dg/autopar/outer-2.c: New testcase.
+ * testsuite/gcc.dg/autopar/outer-3.c: New testcase.
+ * testsuite/gcc.dg/autopar/outer-4.c: New testcase.
+ * testsuite/gcc.dg/autopar/outer-5.c: New testcase.
+ * testsuite/gcc.dg/autopar/outer-6.c: New testcase.
+
+2009-10-22 Jan Hubicka <jh@suse.cz>
+
+ * ipa-cp.c (ipcp_read_summary): Remove now invalid FIXME and
+ flag_ltrans check.
+ * ipa-inline.c (cgraph_mark_inline_edge,
+ cgraph_decide_inlining_of_small_function,
+ cgraph_decide_inlining, inline_read_summary): Disable indirect inlining
+ for WPA for time being.
+
+ PR tree-optimize/40556
+ * ipa-inline.c (cgraph_early_inlining): Fix iterations condition.
+
+2009-10-22 Richard Guenther <rguenther@suse.de>
+
+ * lto-streamer.h (lto_symtab_clear_resolution): Remove.
+ * lto-symtab.c (lto_symtab_clear_resolution): Likewise.
+
+2009-10-22 Jan Hubicka <jh@suse.cz>
+
+ PR lto/41730
+ * ipa-reference.c (has_proper_scope_for_analysis): Add fixme about
+ global vars.
+ (check_call): Handle only indirect calls.
+ (propagate_bits): Update comment.
+ (write_node_summary_p): Turn bogus check to assert.
+ (ipa_reference_write_summary): Stream calls_read_all properly.
+ (ipa_reference_read_summary): Stream in calls_read_all properly.
+ (read_write_all_from_decl): New function.
+ (propagate): Handle OVERWRITABLE nodes and external calls here.
+ * ipa-pre-const.c (check_call): In IPA mode handle indirect calls
+ only.
+ (analyze_function): Do not check visibility here.
+ (add_new_function): We summary OVERWRITABLE too.
+ (generate_summary): Stream OVERWRITABLE nodes too.
+ (propagate): Handle external calls and OVERWRITABLE nodes here.
+ (local_pure_const): Check visibility here.
+
+2009-10-22 Jan Hubicka <jh@suse.cz>
+
+ * ipa-cp.c (ipcp_write_summary, ipcp_read_summary): New functions.
+ (pass_ipa_cp): Register them.
+ (ipcp_init_stage): Analyze all functions for whopr/lto.
+ (ipcp_propagate_stage): Skip external calls.
+ (ipcp_iterate_stage): Call ipa_update_after_lto_read if needed.
+ * ipa-reference.c (write_node_summary_p): Fix thinko about availability.
+ * cgraphunit.c (ipa_passes): When in lto, ne er produce new summaries;
+ when in ltrans, skip executing of ipa passes since everything should've
+ been done.
+ * ipa-inline.c (cgraph_decide_inlining): Remove FIXMEs.
+ (inline_generate_summary): Likewise.
+ (inline_read_summary): New function.
+ (inline_write_summary): New function.
+ (pass_ipa_inline): Register new hooks.
+ * ipa-prop.c: Inlcude lto-streamer.h
+ (ipa_edge_args_vector): Update declaration.
+ (ipa_count_arguments, ipa_compute_jump_functions,
+ ipa_free_edge_args_substructures): Move ipa_edge_args_vector into ggc.
+ (ipa_write_jump_function, ipa_read_jump_function, ipa_write_node_info,
+ ipa_read_node_info): New static functions.
+ (ipa_prop_write_jump_functions, ipa_prop_read_jump_functions): Update.
+ (duplicate_array): Use xmalloc.
+ (duplicate_ggc_array): New.
+ (ipa_edge_duplication_hook): Use it.
+ (ipa_update_after_lto_read): New function.
+ * ipa-prop.h (ipa_prop_write_jump_functions,
+ ipa_prop_read_jump_functions): Declare.
+ (ipa_pass_through_data, ipa_ancestor_jf_data, ipa_member_ptr_cst,
+ jump_func_value, ipa_member_ptr_cst, ipa_edge_args): Add GTY markers.
+ (ipa_edge_args_vector): Move into GGC.
+ (ipa_check_create_edge_args): Update.
+ (ipa_update_after_lto_read): New.
+ * passes.c (ipa_write_summaries_1): When in wpa, do not write summaries.
+ (ipa_read_summaries): When in ltrans, so not read summaries.
+ * lto-streamer.c (lto_get_section_name): Add LTO_section_jump_functions.
+ * lto-streamer.h (LTO_section_jump_functions): New section.
+ (produce_asm): Declare.
+ * lto-cgraph.c (output_cgraph): Output edges in reverse order.
+ * lto-streamer-out.c (produce_asm): Export.
+ * lto-streamer-in.c: Include tree-pass.h
+ (input_function): Free dominance info when done.
+ (lto_read_body): Push ipa_inline in ltrans stage.
+ * gengtype.c (open_base_files): Add ipa-prop.h into includes.
+ * Makefile.in (GTFILES): Add ipa-prop.h
+
+2009-10-22 Matthias Klose <doko@ubuntu.com>
+
+ * doc/install.texi: Document --enable-browser-plugin.
+
+2009-10-21 Vladimir Makarov <vmakarov@redhat.com>
+
+ * doc/invoke.texi (fira-loop-pressure): Update default value.
+ * opts.c (decode_options): Remove default value setting for
+ flag_ira_loop_pressure.
+ * config/ia64/ia64.c (ia64_override_options): Set
+ flag_ira_loop_pressure up for -O3.
+ * config/rs6000/rs6000.c (rs6000_override_options): Ditto.
+
+2009-10-21 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR tree-optimization/41497
+ * tree-scalar-evolution.c (analyze_evolution_in_loop): Return
+ chrec_dont_know if the evolution function returned by follow_ssa_edge
+ is constant in the analyzed loop and is not compatible with the
+ initial value before the loop.
+ * tree-chrec.h (no_evolution_in_loop_p): Call STRIP_NOPS.
+
+2009-10-21 Joseph Myers <joseph@codesourcery.com>
+
+ * config/sh/sh.c (nonpic_symbol_mentioned_p): Allow UNSPEC_TPOFF.
+
+2009-10-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/25507
+ * doc/invoke.texi: Document -print-multi-os-directory.
+
+2009-10-21 Jack Howarth <howarth@bromo.med.uc.edu>
+
+ PR c++/41313
+ * gcc/config/darwin10.h: Use default_emit_unwind_label.
+ * gcc/config/darwin.c: Disable -freorder-blocks-and-partition
+ when darwin_emit_unwind_label is used.
+
2009-10-21 Eric Botcazou <ebotcazou@adacore.com>
* tree-vect-stmts.c (exist_non_indexing_operands_for_use_p): Tweak
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 8474a36c7cc..68b8c8cae81 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20091021
+20091024
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a6e62c2bf26..d1d2dfcad3e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3629,6 +3629,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/tree-ssa-structalias.c \
$(srcdir)/lto-symtab.c \
$(srcdir)/tree-ssa-alias.h \
+ $(srcdir)/ipa-prop.h \
$(MELT_C) \
@all_gtfiles@
@@ -4329,7 +4330,7 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \
intl.h $(PLUGIN_VERSION_H) $(DIAGNOSTIC_H) $(C_COMMON_H) $(C_PRETTY_PRINT_H) \
tree-iterator.h $(PLUGIN_H) $(TREE_FLOW_H) langhooks.h incpath.h \
- tree-ssa-sccvn.h real.h
+ tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H)
# Install the headers needed to build a plugin.
install-plugin: installdirs lang.install-plugin
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index e4761d82e1f..dae8d315f49 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,15 @@
+2009-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: When
+ processing the parent type, build the COMPONENT_REF for a discriminant
+ with the proper type.
+
+2009-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * init.c (__gnat_adjust_context_for_raise): Mention _Unwind_GetIPInfo.
+ * gcc-interface/Makefile.in (GNATLIBCFLAGS_FOR_C): Add HAVE_GETIPINFO.
+ Pass GNATLIBCFLAGS_FOR_C to recursive invocations.
+
2009-10-21 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interfaces/decl.c (build_subst_list): Convert the expression of
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index cf717ac39cd..c9221fb5022 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -109,8 +109,11 @@ SOME_ADAFLAGS =-gnata
FORCE_DEBUG_ADAFLAGS = -g
GNATLIBFLAGS = -gnatpg -nostdinc
GNATLIBCFLAGS = -g -O2
+# Pretend that _Unwind_GetIPInfo is available for the target by default. This
+# should be autodetected during the configuration of libada and passed down to
+# here, but we need something for --disable-libada and hope for the best.
GNATLIBCFLAGS_FOR_C = $(GNATLIBCFLAGS) $(TARGET_LIBGCC2_CFLAGS) -fexceptions \
- -DIN_RTS
+ -DIN_RTS -DHAVE_GETIPINFO
ALL_ADAFLAGS = $(CFLAGS) $(ADA_CFLAGS) $(ADAFLAGS)
MOST_ADAFLAGS = $(CFLAGS) $(ADA_CFLAGS) $(SOME_ADAFLAGS)
THREAD_KIND = native
@@ -2422,6 +2425,7 @@ gnatlib-shared-default:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS) $(TARGET_LIBGCC2_CFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
@@ -2447,6 +2451,7 @@ gnatlib-shared-dual:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib-shared-default
@@ -2455,6 +2460,7 @@ gnatlib-shared-dual:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
@@ -2464,6 +2470,7 @@ gnatlib-shared-dual-win32:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS) $(TARGET_LIBGCC2_CFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib-shared-win32
@@ -2472,6 +2479,7 @@ gnatlib-shared-dual-win32:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
@@ -2485,6 +2493,7 @@ gnatlib-shared-win32:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS) $(TARGET_LIBGCC2_CFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
@@ -2503,7 +2512,7 @@ gnatlib-shared-darwin:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS) $(TARGET_LIBGCC2_CFLAGS) \
- -fno-common" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C) -fno-common" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
@@ -2531,6 +2540,7 @@ gnatlib-shared-vms:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
@@ -2559,6 +2569,7 @@ gnatlib-shared:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
@@ -2572,6 +2583,7 @@ gnatlib-sjlj:
EH_MECHANISM="" \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" gnatlib
@@ -2584,6 +2596,7 @@ gnatlib-zcx:
EH_MECHANISM="-gcc" \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" gnatlib
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index d0b52f2e745..6abb366bd07 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -2729,15 +2729,16 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
Present (gnat_field);
gnat_field = Next_Stored_Discriminant (gnat_field))
if (Present (Corresponding_Discriminant (gnat_field)))
- save_gnu_tree
- (gnat_field,
- build3 (COMPONENT_REF,
- get_unpadded_type (Etype (gnat_field)),
- gnu_get_parent,
- gnat_to_gnu_field_decl (Corresponding_Discriminant
- (gnat_field)),
- NULL_TREE),
- true);
+ {
+ tree gnu_field
+ = gnat_to_gnu_field_decl (Corresponding_Discriminant
+ (gnat_field));
+ save_gnu_tree
+ (gnat_field,
+ build3 (COMPONENT_REF, TREE_TYPE (gnu_field),
+ gnu_get_parent, gnu_field, NULL_TREE),
+ true);
+ }
/* Then we build the parent subtype. If it has discriminants but
the type itself has unknown discriminants, this means that it
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 5fe46cd0ff2..0483d82724b 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -2301,8 +2301,10 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
{
/* We used to compensate here for the raised from call vs raised from signal
exception discrepancy with the GCC ZCX scheme, but this now can be dealt
- with generically in the unwinder (see GCC PR other/26208). Only the VMS
- ports still do the compensation described in the few lines below.
+ with generically in the unwinder (see GCC PR other/26208). This however
+ requires the use of the _Unwind_GetIPInfo routine in raise-gcc.c, which
+ is predicated on the definition of HAVE_GETIPINFO at compile time. Only
+ the VMS ports still do the compensation described in the few lines below.
*** Call vs signal exception discrepancy with GCC ZCX scheme ***
diff --git a/gcc/alias.c b/gcc/alias.c
index 694498ab55a..09ec775c5d0 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -691,7 +691,14 @@ get_alias_set (tree t)
requires structural comparisons to identify compatible types
use alias set zero. */
if (TYPE_STRUCTURAL_EQUALITY_P (t))
- return 0;
+ {
+ /* Allow the language to specify another alias set for this
+ type. */
+ set = lang_hooks.get_alias_set (t);
+ if (set != -1)
+ return set;
+ return 0;
+ }
t = TYPE_CANONICAL (t);
/* Canonical types shouldn't form a tree nor should the canonical
type require structural equality checks. */
diff --git a/gcc/builtins.c b/gcc/builtins.c
index d991408fa28..1243d72048b 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7194,7 +7194,7 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
{
tree res;
- if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
+ if (!validate_arg (arg, COMPLEX_TYPE)
|| TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
return NULL_TREE;
@@ -7583,7 +7583,7 @@ fold_builtin_cexp (location_t loc, tree arg0, tree type)
#endif
if (!validate_arg (arg0, COMPLEX_TYPE)
- && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
return NULL_TREE;
#ifdef HAVE_mpc
@@ -10017,7 +10017,8 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
break;
CASE_FLT_FN (BUILT_IN_CIMAG):
- if (validate_arg (arg0, COMPLEX_TYPE))
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
break;
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 16e17b39d1d..8a6d15b9d9b 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4183,6 +4183,15 @@ c_common_get_alias_set (tree t)
tree u;
PTR *slot;
+ /* For VLAs, use the alias set of the element type rather than the
+ default of alias set 0 for types compared structurally. */
+ if (TYPE_P (t) && TYPE_STRUCTURAL_EQUALITY_P (t))
+ {
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ return get_alias_set (TREE_TYPE (t));
+ return -1;
+ }
+
/* Permit type-punning when accessing a union, provided the access
is directly through the union. For example, this code does not
permit taking the address of a union member and then storing
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index e7425a77d65..3274e0730ec 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -8653,11 +8653,13 @@ c_finish_stmt_expr (location_t loc, tree body)
goto continue_searching;
}
+ if (last == error_mark_node)
+ return last;
+
/* In the case that the BIND_EXPR is not necessary, return the
expression out from inside it. */
- if (last == error_mark_node
- || (last == BIND_EXPR_BODY (body)
- && BIND_EXPR_VARS (body) == NULL))
+ if (last == BIND_EXPR_BODY (body)
+ && BIND_EXPR_VARS (body) == NULL)
{
/* Even if this looks constant, do not allow it in a constant
expression. */
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 2678d7e7ffe..be46028fa58 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1768,10 +1768,10 @@ expand_call_stmt (gimple stmt)
for (i = 0; i < gimple_call_num_args (stmt); i++)
CALL_EXPR_ARG (exp, i) = gimple_call_arg (stmt, i);
- if (!(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
+ if (gimple_has_side_effects (stmt))
TREE_SIDE_EFFECTS (exp) = 1;
- if (gimple_call_flags (stmt) & ECF_NOTHROW)
+ if (gimple_call_nothrow_p (stmt))
TREE_NOTHROW (exp) = 1;
CALL_EXPR_TAILCALL (exp) = gimple_call_tail_p (stmt);
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index d6c26bf0ba0..4abdf8bfe15 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -288,6 +288,7 @@ extern edge create_empty_if_region_on_edge (edge, tree);
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
tree *, tree *, struct loop *);
extern struct loop * duplicate_loop (struct loop *, struct loop *);
+extern void duplicate_subloops (struct loop *, struct loop *);
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
unsigned, sbitmap, edge,
VEC (edge, heap) **, int);
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index a357a2fd77a..6f24415a72d 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "tree-flow.h"
-static void duplicate_subloops (struct loop *, struct loop *);
static void copy_loops_to (struct loop **, int,
struct loop *);
static void loop_redirect_edge (edge, basic_block);
@@ -886,7 +885,7 @@ duplicate_loop (struct loop *loop, struct loop *target)
/* Copies structure of subloops of LOOP into TARGET loop, placing
newly created loops into loop tree. */
-static void
+void
duplicate_subloops (struct loop *loop, struct loop *target)
{
struct loop *aloop, *cloop;
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 47ee7d9ebcd..7b8b738ed1f 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1375,15 +1375,16 @@ ipa_passes (void)
set_cfun (NULL);
current_function_decl = NULL;
cgraph_process_new_functions ();
- }
- execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
+ execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
+ }
execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
if (!in_lto_p)
ipa_write_summaries ();
- execute_ipa_pass_list (all_regular_ipa_passes);
+ if (!flag_ltrans)
+ execute_ipa_pass_list (all_regular_ipa_passes);
bitmap_obstack_release (NULL);
}
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 7c3234f8f64..cb2d709c89a 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -5877,12 +5877,12 @@ avr_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
return 1;
}
-/* Output a branch that tests a single bit of a register (QI, HI or SImode)
+/* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
or memory location in the I/O space (QImode only).
Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
Operand 1: register operand to test, or CONST_INT memory address.
- Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
+ Operand 2: bit number.
Operand 3: label to jump to if the test is true. */
const char *
@@ -5930,9 +5930,7 @@ avr_out_sbxx_branch (rtx insn, rtx operands[])
else /* HImode or SImode */
{
static char buf[] = "sbrc %A1,0";
- int bit_nr = exact_log2 (INTVAL (operands[2])
- & GET_MODE_MASK (GET_MODE (operands[1])));
-
+ int bit_nr = INTVAL (operands[2]);
buf[3] = (comp == EQ) ? 's' : 'c';
buf[6] = 'A' + (bit_nr >> 3);
buf[9] = '0' + (bit_nr & 7);
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index b2d6b44a57d..51fc1f99b8b 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -118,6 +118,7 @@
;; Define mode iterator
(define_mode_iterator QISI [(QI "") (HI "") (SI "")])
+(define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
;;========================================================================
;; The following is used by nonlocal_goto and setjmp.
@@ -2448,12 +2449,15 @@
;; Test a single bit in a QI/HI/SImode register.
-(define_insn "*sbrx_branch"
+;; Combine will create zero extract patterns for single bit tests.
+;; permit any mode in source pattern by using VOIDmode.
+
+(define_insn "*sbrx_branch<mode>"
[(set (pc)
(if_then_else
(match_operator 0 "eqne_operator"
- [(zero_extract:HI
- (match_operand:QI 1 "register_operand" "r")
+ [(zero_extract:QIDI
+ (match_operand:VOID 1 "register_operand" "r")
(const_int 1)
(match_operand 2 "const_int_operand" "n"))
(const_int 0)])
@@ -2470,39 +2474,27 @@
(const_int 4))))
(set_attr "cc" "clobber")])
-(define_insn "*sbrx_and_branchhi"
- [(set (pc)
- (if_then_else
- (match_operator 0 "eqne_operator"
- [(and:HI
- (match_operand:HI 1 "register_operand" "r")
- (match_operand:HI 2 "single_one_operand" "n"))
- (const_int 0)])
- (label_ref (match_operand 3 "" ""))
- (pc)))]
- ""
- "* return avr_out_sbxx_branch (insn, operands);"
- [(set (attr "length")
- (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
- (le (minus (pc) (match_dup 3)) (const_int 2046)))
- (const_int 2)
- (if_then_else (eq_attr "mcu_mega" "no")
- (const_int 2)
- (const_int 4))))
- (set_attr "cc" "clobber")])
+;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
+;; or for old peepholes.
+;; Fixme - bitwise Mask will not work for DImode
-(define_insn "*sbrx_and_branchsi"
+(define_insn "*sbrx_and_branch<mode>"
[(set (pc)
(if_then_else
(match_operator 0 "eqne_operator"
- [(and:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "single_one_operand" "n"))
+ [(and:QISI
+ (match_operand:QISI 1 "register_operand" "r")
+ (match_operand:QISI 2 "single_one_operand" "n"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
""
- "* return avr_out_sbxx_branch (insn, operands);"
+{
+ HOST_WIDE_INT bitnumber;
+ bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
+ operands[2] = GEN_INT (bitnumber);
+ return avr_out_sbxx_branch (insn, operands);
+}
[(set (attr "length")
(if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
(le (minus (pc) (match_dup 3)) (const_int 2046)))
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index a8933e66348..b5c4fb8e0d9 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -1697,6 +1697,17 @@ darwin_override_options (void)
if (dwarf_strict < 0)
dwarf_strict = 1;
+ /* Disable -freorder-blocks-and-partition for darwin_emit_unwind_label. */
+ if (flag_reorder_blocks_and_partition
+ && (targetm.asm_out.unwind_label == darwin_emit_unwind_label))
+ {
+ inform (input_location,
+ "-freorder-blocks-and-partition does not work with exceptions "
+ "on this architecture");
+ flag_reorder_blocks_and_partition = 0;
+ flag_reorder_blocks = 1;
+ }
+
if (flag_mkernel || flag_apple_kext)
{
/* -mkernel implies -fapple-kext for C++ */
diff --git a/gcc/config/darwin10.h b/gcc/config/darwin10.h
index 65ba2632a8f..b1edf36ce3d 100644
--- a/gcc/config/darwin10.h
+++ b/gcc/config/darwin10.h
@@ -23,3 +23,8 @@ unwinder in libSystem is fixed to digest new epilog unwinding notes. */
#undef LIB_SPEC
#define LIB_SPEC "%{!static:-no_compact_unwind -lSystem}"
+
+/* Unwind labels are no longer required in darwin10. */
+
+#undef TARGET_ASM_EMIT_UNWIND_LABEL
+#define TARGET_ASM_EMIT_UNWIND_LABEL default_emit_unwind_label
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 75c8f0ee6c4..23fc7540ec0 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -5496,6 +5496,14 @@ ia64_override_options (void)
if (TARGET_AUTO_PIC)
target_flags |= MASK_CONST_GP;
+ /* Numerous experiment shows that IRA based loop pressure
+ calculation works better for RTL loop invariant motion on targets
+ with enough (>= 32) registers. It is an expensive optimization.
+ So it is on only for peak performance. */
+ if (optimize >= 3)
+ flag_ira_loop_pressure = 1;
+
+
ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
flag_schedule_insns_after_reload = 0;
diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h
index e571fe9d25e..42b92feb506 100644
--- a/gcc/config/m32c/m32c-protos.h
+++ b/gcc/config/m32c/m32c-protos.h
@@ -49,7 +49,6 @@ int m32c_trampoline_size (void);
#if defined(RTX_CODE) && defined(TREE_CODE)
rtx m32c_function_arg (CUMULATIVE_ARGS *, MM, tree, int);
-rtx m32c_function_value (const_tree, const_tree);
#endif
@@ -75,7 +74,7 @@ bool m32c_immd_dbl_mov (rtx *, MM);
rtx m32c_incoming_return_addr_rtx (void);
int m32c_legitimate_constant_p (rtx);
int m32c_legitimize_reload_address (rtx *, MM, int, int, int);
-rtx m32c_libcall_value (MM);
+bool m32c_function_value_regno_p (const unsigned int);
int m32c_limit_reload_class (MM, int);
int m32c_memory_move_cost (MM, int, int);
int m32c_modes_tieable_p (MM, MM);
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index 4eeedb183e7..1085aa7c25a 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -81,6 +81,9 @@ static bool m32c_strict_argument_naming (CUMULATIVE_ARGS *);
static rtx m32c_struct_value_rtx (tree, int);
static rtx m32c_subreg (enum machine_mode, rtx, enum machine_mode, int);
static int need_to_save (int);
+static rtx m32c_function_value (const_tree, const_tree, bool);
+static rtx m32c_libcall_value (enum machine_mode, const_rtx);
+
int current_function_special_page_vector (rtx);
#define SYMBOL_FLAG_FUNCVEC_FUNCTION (SYMBOL_FLAG_MACH_DEP << 0)
@@ -1591,15 +1594,19 @@ m32c_valid_pointer_mode (enum machine_mode mode)
/* How Scalar Function Values Are Returned */
-/* Implements LIBCALL_VALUE. Most values are returned in $r0, or some
+/* Implements TARGET_LIBCALL_VALUE. Most values are returned in $r0, or some
combination of registers starting there (r2r0 for longs, r3r1r2r0
for long long, r3r2r1r0 for doubles), except that that ABI
currently doesn't work because it ends up using all available
general registers and gcc often can't compile it. So, instead, we
return anything bigger than 16 bits in "mem0" (effectively, a
memory location). */
-rtx
-m32c_libcall_value (enum machine_mode mode)
+
+#undef TARGET_LIBCALL_VALUE
+#define TARGET_LIBCALL_VALUE m32c_libcall_value
+
+static rtx
+m32c_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
{
/* return reg or parallel */
#if 0
@@ -1649,14 +1656,28 @@ m32c_libcall_value (enum machine_mode mode)
return gen_rtx_REG (mode, R0_REGNO);
}
-/* Implements FUNCTION_VALUE. Functions and libcalls have the same
+/* Implements TARGET_FUNCTION_VALUE. Functions and libcalls have the same
conventions. */
-rtx
-m32c_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
+
+#undef TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE m32c_function_value
+
+static rtx
+m32c_function_value (const_tree valtype,
+ const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
+ bool outgoing ATTRIBUTE_UNUSED)
{
/* return reg or parallel */
const enum machine_mode mode = TYPE_MODE (valtype);
- return m32c_libcall_value (mode);
+ return m32c_libcall_value (mode, NULL_RTX);
+}
+
+/* Implements FUNCTION_VALUE_REGNO_P. */
+
+bool
+m32c_function_value_regno_p (const unsigned int regno)
+{
+ return (regno == R0_REGNO || regno == MEM0_REGNO);
}
/* How Large Values Are Returned */
diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h
index 0f12158c0e4..c0914d3be02 100644
--- a/gcc/config/m32c/m32c.h
+++ b/gcc/config/m32c/m32c.h
@@ -533,10 +533,7 @@ typedef struct m32c_cumulative_args
/* How Scalar Function Values Are Returned */
-#define FUNCTION_VALUE(VT,F) m32c_function_value (VT, F)
-#define LIBCALL_VALUE(MODE) m32c_libcall_value (MODE)
-
-#define FUNCTION_VALUE_REGNO_P(r) ((r) == R0_REGNO || (r) == MEM0_REGNO)
+#define FUNCTION_VALUE_REGNO_P(r) m32c_function_value_regno_p (r)
/* How Large Values Are Returned */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8bb92129ecf..88649ea0735 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -130,6 +130,8 @@ typedef struct GTY(()) machine_function
64-bits wide and is allocated early enough so that the offset
does not overflow the 16-bit load/store offset field. */
rtx sdmode_stack_slot;
+ /* True if any VSX or ALTIVEC vector type was used. */
+ bool vsx_or_altivec_used_p;
} machine_function;
/* Target cpu type */
@@ -913,7 +915,7 @@ static void rs6000_elf_encode_section_info (tree, rtx, int)
ATTRIBUTE_UNUSED;
#endif
static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
-static void rs6000_alloc_sdmode_stack_slot (void);
+static void rs6000_expand_to_rtl_hook (void);
static void rs6000_instantiate_decls (void);
#if TARGET_XCOFF
static void rs6000_xcoff_asm_output_anchor (rtx);
@@ -1505,7 +1507,7 @@ static const struct attribute_spec rs6000_attribute_table[] =
#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
#undef TARGET_EXPAND_TO_RTL_HOOK
-#define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
+#define TARGET_EXPAND_TO_RTL_HOOK rs6000_expand_to_rtl_hook
#undef TARGET_INSTANTIATE_DECLS
#define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
@@ -2281,6 +2283,13 @@ rs6000_override_options (const char *default_cpu)
| MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
};
+ /* Numerous experiment shows that IRA based loop pressure
+ calculation works better for RTL loop invariant motion on targets
+ with enough (>= 32) registers. It is an expensive optimization.
+ So it is on only for peak performance. */
+ if (optimize >= 3)
+ flag_ira_loop_pressure = 1;
+
/* Set the pointer size. */
if (TARGET_64BIT)
{
@@ -13183,6 +13192,38 @@ rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
return NULL_TREE;
}
+static tree
+rs6000_check_vector_mode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+{
+ /* Don't walk into types. */
+ if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ switch (TREE_CODE (*tp))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case RESULT_DECL:
+ case SSA_NAME:
+ case REAL_CST:
+ case INDIRECT_REF:
+ case ALIGN_INDIRECT_REF:
+ case MISALIGNED_INDIRECT_REF:
+ case VIEW_CONVERT_EXPR:
+ if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (*tp))))
+ return *tp;
+ break;
+ default:
+ break;
+ }
+
+ return NULL_TREE;
+}
+
enum reload_reg_type {
GPR_REGISTER_TYPE,
VECTOR_REGISTER_TYPE,
@@ -13623,11 +13664,17 @@ rs6000_ira_cover_classes (void)
return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
}
-/* Allocate a 64-bit stack slot to be used for copying SDmode
- values through if this function has any SDmode references. */
+/* Scan the trees looking for certain types.
+
+ Allocate a 64-bit stack slot to be used for copying SDmode values through if
+ this function has any SDmode references.
+
+ If VSX, note whether any vector operation was done so we can set VRSAVE to
+ non-zero, even if we just use the floating point registers to tell the
+ kernel to save the vector registers. */
static void
-rs6000_alloc_sdmode_stack_slot (void)
+rs6000_expand_to_rtl_hook (void)
{
tree t;
basic_block bb;
@@ -13635,6 +13682,24 @@ rs6000_alloc_sdmode_stack_slot (void)
gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
+ /* Check for vectors. */
+ if (TARGET_VSX)
+ {
+ FOR_EACH_BB (bb)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ if (walk_gimple_op (gsi_stmt (gsi), rs6000_check_vector_mode,
+ NULL))
+ {
+ cfun->machine->vsx_or_altivec_used_p = true;
+ goto found_vector;
+ }
+ }
+ found_vector:
+ ;
+ }
+
+ /* Check for SDmode being used. */
FOR_EACH_BB (bb)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
@@ -16776,6 +16841,15 @@ compute_vrsave_mask (void)
if (df_regs_ever_live_p (i))
mask |= ALTIVEC_REG_BIT (i);
+ /* If VSX is used, we might have used a traditional floating point register
+ in a vector mode without using any altivec registers. However the VRSAVE
+ register does not have room to indicate the floating point registers.
+ Modern kernels only look to see if the value is non-zero to determine if
+ they need to save the vector registers, so we just set an arbitrary
+ value if any vector type was used. */
+ if (mask == 0 && TARGET_VSX && cfun->machine->vsx_or_altivec_used_p)
+ mask = 0xFFF;
+
if (mask == 0)
return mask;
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 25d760a5be6..4b1ca3d635a 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1033,10 +1033,12 @@ extern unsigned rs6000_pointer_size;
#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)]
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
- ((TARGET_32BIT && TARGET_POWERPC64 \
- && (GET_MODE_SIZE (MODE) > 4) \
- && INT_REGNO_P (REGNO)) ? 1 : 0)
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ (((TARGET_32BIT && TARGET_POWERPC64 \
+ && (GET_MODE_SIZE (MODE) > 4) \
+ && INT_REGNO_P (REGNO)) ? 1 : 0) \
+ || (TARGET_VSX && FP_REGNO_P (REGNO) \
+ && GET_MODE_SIZE (MODE) > 8))
#define VSX_VECTOR_MODE(MODE) \
((MODE) == V4SFmode \
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 7758bfa0f3b..26bceea670d 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -9431,6 +9431,7 @@ nonpic_symbol_mentioned_p (rtx x)
|| XINT (x, 1) == UNSPEC_GOTPLT
|| XINT (x, 1) == UNSPEC_GOTTPOFF
|| XINT (x, 1) == UNSPEC_DTPOFF
+ || XINT (x, 1) == UNSPEC_TPOFF
|| XINT (x, 1) == UNSPEC_PLT
|| XINT (x, 1) == UNSPEC_SYMOFF
|| XINT (x, 1) == UNSPEC_PCREL_SYMOFF))
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a068a432b1f..3ce735b3fe9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,29 @@
+2009-10-23 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40808
+ * mangle.c (write_template_args): Allow mangling of empty template
+ argument list. Updated function comments.
+
+2009-10-23 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (lambda_expr_this_capture): Use thisify_lambda_field.
+
+ * semantics.c (outer_lambda_capture_p): New fn.
+ (thisify_lambda_field): Factor out...
+ (add_default_capture): ...from here.
+ (finish_id_expression): Use them.
+
+ Core issue 899
+ * call.c (add_function_candidate): Only permit explicit conversion
+ ops if copy ctor was called with a single argument.
+
+ * call.c (initialize_reference): Tweak error message.
+
+2009-10-21 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (finish_mangling_get_identifier): Use
+ obstack_base (mangle_obstack) instead of name_base.
+
2009-10-19 Jakub Jelinek <jakub@redhat.com>
* parser.c (cp_lexer_print_token, cp_parser_is_string_literal,
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ff22d9e8674..45428045b84 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1631,7 +1631,8 @@ add_function_candidate (struct z_candidate **candidates,
parmtype = build_pointer_type (parmtype);
}
- if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn))
+ if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn)
+ && (len-skip == 1))
{
/* Hack: Direct-initialize copy parm (i.e. suppress
LOOKUP_ONLYCONVERTING) to make explicit conversion ops
@@ -7619,7 +7620,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
&& !TYPE_REF_IS_RVALUE (type)
&& !real_lvalue_p (expr))
error ("invalid initialization of non-const reference of "
- "type %qT from a temporary of type %qT",
+ "type %qT from an rvalue of type %qT",
type, TREE_TYPE (expr));
else
error ("invalid initialization of reference of type "
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index d96a929ec5c..d4bcbace727 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2284,21 +2284,22 @@ write_class_enum_type (const tree type)
/* Non-terminal <template-args>. ARGS is a TREE_VEC of template
arguments.
- <template-args> ::= I <template-arg>+ E */
+ <template-args> ::= I <template-arg>* E */
static void
write_template_args (tree args)
{
int i;
- int length = TREE_VEC_LENGTH (args);
+ int length = 0;
MANGLE_TRACE_TREE ("template-args", args);
write_char ('I');
- gcc_assert (length > 0);
+ if (args)
+ length = TREE_VEC_LENGTH (args);
- if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
+ if (args && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
{
/* We have nested template args. We want the innermost template
argument list. */
@@ -2958,7 +2959,7 @@ finish_mangling_get_identifier (const bool warn)
finish_mangling_internal (warn);
/* Don't obstack_finish here, and the next start_mangling will
remove the identifier. */
- return get_identifier ((const char *) name_base);
+ return get_identifier ((const char *) obstack_base (mangle_obstack));
}
/* Initialize data structures for mangling. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 6cf22204a5e..417c15f428e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
static tree maybe_convert_cond (tree);
static tree finalize_nrv_r (tree *, int *, void *);
static tree capture_decltype (tree);
+static tree thisify_lambda_field (tree);
/* Deferred Access Checking Overview
@@ -1447,14 +1448,13 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
return error_mark_node;
}
- /* If decl is a field, object has a lambda type, and decl is not a member
- of that type, then we have a reference to a member of 'this' from a
+ /* If decl is a non-capture field and object has a lambda type,
+ then we have a reference to a member of 'this' from a
lambda inside a non-static member function, and we must get to decl
through the 'this' capture. If decl is not a member of that object,
either, then its access will still fail later. */
if (LAMBDA_TYPE_P (TREE_TYPE (object))
- && !same_type_ignoring_top_level_qualifiers_p (DECL_CONTEXT (decl),
- TREE_TYPE (object)))
+ && !LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
object = cp_build_indirect_ref (lambda_expr_this_capture
(CLASSTYPE_LAMBDA_EXPR
(TREE_TYPE (object))),
@@ -2648,6 +2648,18 @@ outer_automatic_var_p (tree decl)
&& DECL_CONTEXT (decl) != current_function_decl);
}
+/* Returns true iff DECL is a capture field from a lambda that is not our
+ immediate context. */
+
+static bool
+outer_lambda_capture_p (tree decl)
+{
+ return (TREE_CODE (decl) == FIELD_DECL
+ && LAMBDA_TYPE_P (DECL_CONTEXT (decl))
+ && (!current_class_type
+ || !DERIVED_FROM_P (DECL_CONTEXT (decl), current_class_type)));
+}
+
/* ID_EXPRESSION is a representation of parsed, but unprocessed,
id-expression. (See cp_parser_id_expression for details.) SCOPE,
if non-NULL, is the type or namespace used to explicitly qualify
@@ -2751,7 +2763,8 @@ finish_id_expression (tree id_expression,
/* Disallow uses of local variables from containing functions, except
within lambda-expressions. */
- if (outer_automatic_var_p (decl)
+ if ((outer_automatic_var_p (decl)
+ || outer_lambda_capture_p (decl))
/* It's not a use (3.2) if we're in an unevaluated context. */
&& !cp_unevaluated_operand)
{
@@ -2759,6 +2772,7 @@ finish_id_expression (tree id_expression,
tree containing_function = current_function_decl;
tree lambda_stack = NULL_TREE;
tree lambda_expr = NULL_TREE;
+ tree initializer = decl;
/* Core issue 696: "[At the July 2009 meeting] the CWG expressed
support for an approach in which a reference to a local
@@ -2770,6 +2784,13 @@ finish_id_expression (tree id_expression,
if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
return integral_constant_value (decl);
+ if (TYPE_P (context))
+ {
+ /* Implicit capture of an explicit capture. */
+ context = lambda_function (context);
+ initializer = thisify_lambda_field (decl);
+ }
+
/* If we are in a lambda function, we can move out until we hit
1. the context,
2. a non-lambda function, or
@@ -2796,7 +2817,7 @@ finish_id_expression (tree id_expression,
{
decl = add_default_capture (lambda_stack,
/*id=*/DECL_NAME (decl),
- /*initializer=*/decl);
+ initializer);
}
else if (lambda_expr)
{
@@ -5604,6 +5625,21 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
return member;
}
+/* Given a FIELD_DECL decl belonging to a closure type, return a
+ COMPONENT_REF of it relative to the 'this' parameter of the op() for
+ that type. */
+
+static tree
+thisify_lambda_field (tree decl)
+{
+ tree context = lambda_function (DECL_CONTEXT (decl));
+ tree object = cp_build_indirect_ref (DECL_ARGUMENTS (context),
+ /*errorstring*/"",
+ tf_warning_or_error);
+ return finish_non_static_data_member (decl, object,
+ /*qualifying_scope*/NULL_TREE);
+}
+
/* Similar to add_capture, except this works on a stack of nested lambdas.
BY_REFERENCE_P in this case is derived from the default capture mode.
Returns the capture for the lambda at the bottom of the stack. */
@@ -5634,16 +5670,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
&& (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda)
== CPLD_REFERENCE)),
/*explicit_init_p=*/false);
-
- {
- /* Have to get the old value of current_class_ref. */
- tree object = cp_build_indirect_ref (DECL_ARGUMENTS
- (lambda_function (lambda)),
- /*errorstring=*/"",
- /*complain=*/tf_warning_or_error);
- initializer = finish_non_static_data_member
- (member, object, /*qualifying_scope=*/NULL_TREE);
- }
+ initializer = thisify_lambda_field (member);
}
current_class_type = saved_class_type;
@@ -5682,10 +5709,7 @@ lambda_expr_this_capture (tree lambda)
{
/* An outer lambda has already captured 'this'. */
tree cap = LAMBDA_EXPR_THIS_CAPTURE (lambda);
- tree lthis
- = cp_build_indirect_ref (DECL_ARGUMENTS (containing_function),
- "", tf_warning_or_error);
- init = finish_non_static_data_member (cap, lthis, NULL_TREE);
+ init = thisify_lambda_field (cap);
break;
}
diff --git a/gcc/cselib.c b/gcc/cselib.c
index aa5f7b022bc..7065429be8b 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -1422,30 +1422,31 @@ cselib_subst_to_values (rtx x)
{
rtx t = cselib_subst_to_values (XEXP (x, i));
- if (t != XEXP (x, i) && x == copy)
- copy = shallow_copy_rtx (x);
-
- XEXP (copy, i) = t;
+ if (t != XEXP (x, i))
+ {
+ if (x == copy)
+ copy = shallow_copy_rtx (x);
+ XEXP (copy, i) = t;
+ }
}
else if (fmt[i] == 'E')
{
- int j, k;
+ int j;
for (j = 0; j < XVECLEN (x, i); j++)
{
rtx t = cselib_subst_to_values (XVECEXP (x, i, j));
- if (t != XVECEXP (x, i, j) && XVEC (x, i) == XVEC (copy, i))
+ if (t != XVECEXP (x, i, j))
{
- if (x == copy)
- copy = shallow_copy_rtx (x);
-
- XVEC (copy, i) = rtvec_alloc (XVECLEN (x, i));
- for (k = 0; k < j; k++)
- XVECEXP (copy, i, k) = XVECEXP (x, i, k);
+ if (XVEC (x, i) == XVEC (copy, i))
+ {
+ if (x == copy)
+ copy = shallow_copy_rtx (x);
+ XVEC (copy, i) = shallow_copy_rtvec (XVEC (x, i));
+ }
+ XVECEXP (copy, i, j) = t;
}
-
- XVECEXP (copy, i, j) = t;
}
}
}
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 73d8dedaacf..c04f9cb65d5 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1346,8 +1346,10 @@ powerpc-linux for powerpc64-linux, only generates 32-bit code. This
option enables the 32-bit target to be a bi-arch compiler, which is
useful when you want a bi-arch compiler that defaults to 32-bit, and
you are building a bi-arch or multi-arch binutils in a combined tree.
-Currently, this option only affects sparc-linux, powerpc-linux and
-x86-linux.
+On mips-linux, this will build a tri-arch compiler (ABI o32/n32/64),
+defaulted to o32.
+Currently, this option only affects sparc-linux, powerpc-linux, x86-linux
+and mips-linux.
@item --enable-secureplt
This option enables @option{-msecure-plt} by default for powerpc-linux.
@@ -1882,6 +1884,9 @@ not specified, then the Python modules are installed in $(prefix)/share/python.
@item --enable-aot-compile-rpm
Adds aot-compile-rpm to the list of installed scripts.
+@item --enable-browser-plugin
+Build the gcjwebplugin web browser plugin.
+
@table @code
@item ansi
Use the single-byte @code{char} and the Win32 A functions natively,
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ecc28c85cc7..81569194d9d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -321,7 +321,7 @@ Objective-C and Objective-C++ Dialects}.
-femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
-femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]} @gol
-p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol
--print-multi-directory -print-multi-lib @gol
+-print-multi-directory -print-multi-lib -print-multi-os-directory @gol
-print-prog-name=@var{program} -print-search-dirs -Q @gol
-print-sysroot -print-sysroot-headers-suffix @gol
-save-temps -save-temps=cwd -save-temps=obj -time@r{[}=@var{file}@r{]}}
@@ -5536,6 +5536,16 @@ that enable them. The directory name is separated from the switches by
@samp{-}, without spaces between multiple switches. This is supposed to
ease shell-processing.
+@item -print-multi-os-directory
+@opindex print-multi-os-directory
+Print the path to OS libraries for the selected
+multilib, relative to some @file{lib} subdirectory. If OS libraries are
+present in the @file{lib} subdirectory and no multilibs are used, this is
+usually just @file{.}, if OS libraries are present in @file{lib@var{suffix}}
+sibling directories this prints e.g.@: @file{../lib64}, @file{../lib} or
+@file{../lib32}, or if OS libraries are present in @file{lib/@var{subdir}}
+subdirectories it prints e.g.@: @file{amd64}, @file{sparcv9} or @file{ev6}.
+
@item -print-prog-name=@var{program}
@opindex print-prog-name
Like @option{-print-file-name}, but searches for a program such as @samp{cpp}.
@@ -5728,8 +5738,7 @@ invoking @option{-O2} on programs that use computed gotos.
Optimize yet more. @option{-O3} turns on all optimizations specified
by @option{-O2} and also turns on the @option{-finline-functions},
@option{-funswitch-loops}, @option{-fpredictive-commoning},
-@option{-fgcse-after-reload}, @option{-ftree-vectorize} and
-@option{-fira-loop-pressure} options.
+@option{-fgcse-after-reload} and @option{-ftree-vectorize} options.
@item -O0
@opindex O0
@@ -6230,9 +6239,10 @@ architectures with big regular register files.
@opindex fira-loop-pressure
Use IRA to evaluate register pressure in loops for decision to move
loop invariants. Usage of this option usually results in generation
-of faster and smaller code but can slow compiler down.
+of faster and smaller code on machines with big register files (>= 32
+registers) but it can slow compiler down.
-This option is enabled at level @option{-O3}.
+This option is enabled at level @option{-O3} for some targets.
@item -fno-ira-share-save-slots
@opindex fno-ira-share-save-slots
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index b3567e4cff7..cf6c8cd2dcb 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,32 @@
+2009-10-24 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/41772
+ * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Stop'extent'
+ from going negative.
+
+2009-10-23 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41800
+ * trans-expr.c (gfc_trans_scalar_assign): Handle CLASS variables.
+
+2009-10-23 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41758
+ * match.c (conformable_arrays): Move to resolve.c.
+ (gfc_match_allocate): Don't resolve SOURCE expr yet, and move some
+ checks to resolve_allocate_expr.
+ * resolve.c (conformable_arrays): Moved here from match.c.
+ (resolve_allocate_expr): Moved some checks here from gfc_match_allocate.
+ (resolve_code): Resolve SOURCE tag for ALLOCATE expressions.
+
+2009-10-22 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41781
+ * resolve.c (resolve_codes): Don't clear 'cs_base' for BLOCK constructs,
+ to make sure labels are treated correctly.
+ * symbol.c (gfc_get_st_label): Create labels in the right namespace.
+ For BLOCK constructs go into the parent namespace.
+
2009-10-21 Janus Weil <janus@gcc.gnu.org>
PR fortran/41706
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 0a418c8a449..24e292bd4d6 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -2388,58 +2388,6 @@ char_selector:
}
-/* Used in gfc_match_allocate to check that a allocation-object and
- a source-expr are conformable. This does not catch all possible
- cases; in particular a runtime checking is needed. */
-
-static gfc_try
-conformable_arrays (gfc_expr *e1, gfc_expr *e2)
-{
- /* First compare rank. */
- if (e2->ref && e1->rank != e2->ref->u.ar.as->rank)
- {
- gfc_error ("Source-expr at %L must be scalar or have the "
- "same rank as the allocate-object at %L",
- &e1->where, &e2->where);
- return FAILURE;
- }
-
- if (e1->shape)
- {
- int i;
- mpz_t s;
-
- mpz_init (s);
-
- for (i = 0; i < e1->rank; i++)
- {
- if (e2->ref->u.ar.end[i])
- {
- mpz_set (s, e2->ref->u.ar.end[i]->value.integer);
- mpz_sub (s, s, e2->ref->u.ar.start[i]->value.integer);
- mpz_add_ui (s, s, 1);
- }
- else
- {
- mpz_set (s, e2->ref->u.ar.start[i]->value.integer);
- }
-
- if (mpz_cmp (e1->shape[i], s) != 0)
- {
- gfc_error ("Source-expr at %L and allocate-object at %L must "
- "have the same shape", &e1->where, &e2->where);
- mpz_clear (s);
- return FAILURE;
- }
- }
-
- mpz_clear (s);
- }
-
- return SUCCESS;
-}
-
-
/* Match an ALLOCATE statement. */
match
@@ -2620,7 +2568,7 @@ alloc_opt_list:
goto cleanup;
}
- /* The next 3 conditionals check C631. */
+ /* The next 2 conditionals check C631. */
if (ts.type != BT_UNKNOWN)
{
gfc_error ("SOURCE tag at %L conflicts with the typespec at %L",
@@ -2635,28 +2583,6 @@ alloc_opt_list:
goto cleanup;
}
- gfc_resolve_expr (tmp);
-
- if (!gfc_type_compatible (&head->expr->ts, &tmp->ts))
- {
- gfc_error ("Type of entity at %L is type incompatible with "
- "source-expr at %L", &head->expr->where, &tmp->where);
- goto cleanup;
- }
-
- /* Check C633. */
- if (tmp->ts.kind != head->expr->ts.kind)
- {
- gfc_error ("The allocate-object at %L and the source-expr at %L "
- "shall have the same kind type parameter",
- &head->expr->where, &tmp->where);
- goto cleanup;
- }
-
- /* Check C632 and restriction following Note 6.18. */
- if (tmp->rank > 0 && conformable_arrays (tmp, head->expr) == FAILURE)
- goto cleanup;
-
source = tmp;
saw_source = true;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 8e23308d5b2..b17e8fef182 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5958,6 +5958,58 @@ gfc_expr_to_initialize (gfc_expr *e)
}
+/* Used in resolve_allocate_expr to check that a allocation-object and
+ a source-expr are conformable. This does not catch all possible
+ cases; in particular a runtime checking is needed. */
+
+static gfc_try
+conformable_arrays (gfc_expr *e1, gfc_expr *e2)
+{
+ /* First compare rank. */
+ if (e2->ref && e1->rank != e2->ref->u.ar.as->rank)
+ {
+ gfc_error ("Source-expr at %L must be scalar or have the "
+ "same rank as the allocate-object at %L",
+ &e1->where, &e2->where);
+ return FAILURE;
+ }
+
+ if (e1->shape)
+ {
+ int i;
+ mpz_t s;
+
+ mpz_init (s);
+
+ for (i = 0; i < e1->rank; i++)
+ {
+ if (e2->ref->u.ar.end[i])
+ {
+ mpz_set (s, e2->ref->u.ar.end[i]->value.integer);
+ mpz_sub (s, s, e2->ref->u.ar.start[i]->value.integer);
+ mpz_add_ui (s, s, 1);
+ }
+ else
+ {
+ mpz_set (s, e2->ref->u.ar.start[i]->value.integer);
+ }
+
+ if (mpz_cmp (e1->shape[i], s) != 0)
+ {
+ gfc_error ("Source-expr at %L and allocate-object at %L must "
+ "have the same shape", &e1->where, &e2->where);
+ mpz_clear (s);
+ return FAILURE;
+ }
+ }
+
+ mpz_clear (s);
+ }
+
+ return SUCCESS;
+}
+
+
/* Resolve the expression in an ALLOCATE statement, doing the additional
checks to see whether the expression is OK or not. The expression must
have a trailing array reference that gives the size of the array. */
@@ -6057,7 +6109,32 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
return FAILURE;
}
- if (is_abstract && !code->expr3 && code->ext.alloc.ts.type == BT_UNKNOWN)
+ /* Some checks for the SOURCE tag. */
+ if (code->expr3)
+ {
+ /* Check F03:C631. */
+ if (!gfc_type_compatible (&e->ts, &code->expr3->ts))
+ {
+ gfc_error ("Type of entity at %L is type incompatible with "
+ "source-expr at %L", &e->where, &code->expr3->where);
+ return FAILURE;
+ }
+
+ /* Check F03:C632 and restriction following Note 6.18. */
+ if (code->expr3->rank > 0
+ && conformable_arrays (code->expr3, e) == FAILURE)
+ return FAILURE;
+
+ /* Check F03:C633. */
+ if (code->expr3->ts.kind != e->ts.kind)
+ {
+ gfc_error ("The allocate-object at %L and the source-expr at %L "
+ "shall have the same kind type parameter",
+ &e->where, &code->expr3->where);
+ return FAILURE;
+ }
+ }
+ else if (is_abstract&& code->ext.alloc.ts.type == BT_UNKNOWN)
{
gcc_assert (e->ts.type == BT_CLASS);
gfc_error ("Allocating %s of ABSTRACT base type at %L requires a "
@@ -7734,6 +7811,10 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
if (gfc_resolve_expr (code->expr2) == FAILURE)
t = FAILURE;
+ if (code->op == EXEC_ALLOCATE
+ && gfc_resolve_expr (code->expr3) == FAILURE)
+ t = FAILURE;
+
switch (code->op)
{
case EXEC_NOP:
@@ -12053,7 +12134,11 @@ resolve_codes (gfc_namespace *ns)
resolve_codes (n);
gfc_current_ns = ns;
- cs_base = NULL;
+
+ /* Don't clear 'cs_base' if this is the namespace of a BLOCK construct. */
+ if (!(ns->proc_name && ns->proc_name->attr.flavor == FL_LABEL))
+ cs_base = NULL;
+
/* Set to an out of range value. */
current_entry_id = -1;
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 837a357d9fb..c1b39b0d9f1 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -2030,9 +2030,16 @@ gfc_st_label *
gfc_get_st_label (int labelno)
{
gfc_st_label *lp;
+ gfc_namespace *ns;
+
+ /* Find the namespace of the scoping unit:
+ If we're in a BLOCK construct, jump to the parent namespace. */
+ ns = gfc_current_ns;
+ while (ns->proc_name && ns->proc_name->attr.flavor == FL_LABEL)
+ ns = ns->parent;
/* First see if the label is already in this namespace. */
- lp = gfc_current_ns->st_labels;
+ lp = ns->st_labels;
while (lp)
{
if (lp->value == labelno)
@@ -2050,7 +2057,7 @@ gfc_get_st_label (int labelno)
lp->defined = ST_LABEL_UNKNOWN;
lp->referenced = ST_LABEL_UNKNOWN;
- gfc_insert_bbt (&gfc_current_ns->st_labels, lp, compare_st_labels);
+ gfc_insert_bbt (&ns->st_labels, lp, compare_st_labels);
return lp;
}
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index dc58dbf943d..da442edba4b 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -4660,7 +4660,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
gfc_add_expr_to_block (&block, tmp);
}
}
- else if (ts.type == BT_DERIVED)
+ else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
{
gfc_add_block_to_block (&block, &lse->pre);
gfc_add_block_to_block (&block, &rse->pre);
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 1e7b35f5c17..c3d7dfbab3c 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -4490,6 +4490,8 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
scalar_transfer:
extent = fold_build2 (MIN_EXPR, gfc_array_index_type,
dest_word_len, source_bytes);
+ extent = fold_build2 (MAX_EXPR, gfc_array_index_type,
+ extent, gfc_index_zero_node);
if (expr->ts.type == BT_CHARACTER)
{
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 6d5bbab16fa..b0f249f4bbb 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1571,7 +1571,7 @@ open_base_files (void)
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
"tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
"cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
- "target.h",
+ "target.h", "ipa-prop.h",
/* Addition of melt-runtime.h should be the only change here
w.r.t. ordinary (=trunk or gcc-4.5 ...) gengtype.c! */
"melt-runtime.h",
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 7e499ca27fa..79ff16e0e7f 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -614,7 +614,9 @@ ipcp_init_stage (void)
/* building jump functions */
for (cs = node->callees; cs; cs = cs->next_callee)
{
- if (!cs->callee->analyzed)
+ /* We do not need to bother analyzing calls to unknown
+ functions unless they may become known during lto/whopr. */
+ if (!cs->callee->analyzed && !flag_lto && !flag_whopr)
continue;
ipa_count_arguments (cs);
if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
@@ -696,7 +698,9 @@ ipcp_propagate_stage (void)
struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee);
struct ipa_edge_args *args = IPA_EDGE_REF (cs);
- if (ipa_is_called_with_var_arguments (callee_info))
+ if (ipa_is_called_with_var_arguments (callee_info)
+ || !cs->callee->analyzed
+ || ipa_is_called_with_var_arguments (callee_info))
continue;
count = ipa_get_cs_argument_count (args);
@@ -727,6 +731,10 @@ ipcp_iterate_stage (void)
if (dump_file)
fprintf (dump_file, "\nIPA iterate stage:\n\n");
+
+ if (in_lto_p)
+ ipa_update_after_lto_read ();
+
for (node = cgraph_nodes; node; node = node->next)
{
ipcp_initialize_node_lattices (node);
@@ -1276,17 +1284,25 @@ ipcp_generate_summary (void)
ipcp_init_stage ();
}
+/* Write ipcp summary for nodes in SET. */
+static void
+ipcp_write_summary (cgraph_node_set set)
+{
+ ipa_prop_write_jump_functions (set);
+}
+
+/* Read ipcp summary. */
+static void
+ipcp_read_summary (void)
+{
+ ipa_prop_read_jump_functions ();
+}
+
/* Gate for IPCP optimization. */
static bool
cgraph_gate_cp (void)
{
- /* FIXME lto. IPA-CP does not tolerate running when the inlining decisions
- have not been applied. This happens when WPA modifies the callgraph.
- Since those decisions are not applied until after all the IPA passes
- have been run in LTRANS, this means that IPA passes may see partially
- modified callgraphs. The solution to this is to apply WPA decisions
- early during LTRANS. */
- return flag_ipa_cp && !flag_ltrans;
+ return flag_ipa_cp;
}
struct ipa_opt_pass_d pass_ipa_cp =
@@ -1308,8 +1324,8 @@ struct ipa_opt_pass_d pass_ipa_cp =
TODO_remove_functions /* todo_flags_finish */
},
ipcp_generate_summary, /* generate_summary */
- NULL, /* write_summary */
- NULL, /* read_summary */
+ ipcp_write_summary, /* write_summary */
+ ipcp_read_summary, /* read_summary */
NULL, /* function_read_summary */
0, /* TODOs */
NULL, /* function_transform */
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 18e440a60fe..81c3379ca2e 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -310,7 +310,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
overall_size -= orig_size;
ncalls_inlined++;
- if (flag_indirect_inlining)
+ if (flag_indirect_inlining && !flag_wpa)
return ipa_propagate_indirect_call_infos (curr, new_edges);
else
return false;
@@ -876,7 +876,7 @@ cgraph_decide_inlining_of_small_functions (void)
int min_size, max_size;
VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL;
- if (flag_indirect_inlining)
+ if (flag_indirect_inlining && !flag_wpa)
new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8);
if (dump_file)
@@ -1023,10 +1023,10 @@ cgraph_decide_inlining_of_small_functions (void)
if (where->global.inlined_to)
where = where->global.inlined_to;
if (!cgraph_decide_recursive_inlining (where,
- flag_indirect_inlining
+ flag_indirect_inlining && !flag_wpa
? &new_indirect_edges : NULL))
continue;
- if (flag_indirect_inlining)
+ if (flag_indirect_inlining && !flag_wpa)
add_new_edges_to_heap (heap, new_indirect_edges);
update_callee_keys (heap, where, updated_nodes);
}
@@ -1045,7 +1045,7 @@ cgraph_decide_inlining_of_small_functions (void)
}
callee = edge->callee;
cgraph_mark_inline_edge (edge, true, &new_indirect_edges);
- if (flag_indirect_inlining)
+ if (flag_indirect_inlining && !flag_wpa)
add_new_edges_to_heap (heap, new_indirect_edges);
update_callee_keys (heap, callee, updated_nodes);
@@ -1113,13 +1113,9 @@ cgraph_decide_inlining (void)
bool redo_always_inline = true;
int initial_size = 0;
- /* FIXME lto. We need to rethink how to coordinate different passes. */
- if (flag_ltrans)
- return 0;
-
- /* FIXME lto. We need to re-think about how the passes get invoked. */
- if (!flag_wpa)
- cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
+ cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
+ if (in_lto_p && flag_indirect_inlining && !flag_wpa)
+ ipa_update_after_lto_read ();
max_count = 0;
max_benefit = 0;
@@ -1272,7 +1268,7 @@ cgraph_decide_inlining (void)
}
/* Free ipa-prop structures if they are no longer needed. */
- if (flag_indirect_inlining)
+ if (flag_indirect_inlining && !flag_wpa)
free_all_ipa_structures_after_iinln ();
if (dump_file)
@@ -1593,10 +1589,10 @@ cgraph_early_inlining (void)
if (sorrycount || errorcount)
return 0;
- while (cgraph_decide_inlining_incrementally (node,
- iterations
- ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0)
- && iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS))
+ while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS)
+ && cgraph_decide_inlining_incrementally (node,
+ iterations
+ ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0))
{
timevar_push (TV_INTEGRATION);
todo |= optimize_inline_calls (current_function_decl);
@@ -1928,10 +1924,6 @@ inline_generate_summary (void)
{
struct cgraph_node *node;
- /* FIXME lto. We should not run any IPA-summary pass in LTRANS mode. */
- if (flag_ltrans)
- return;
-
function_insertion_hook_holder =
cgraph_add_function_insertion_hook (&add_new_function, NULL);
@@ -1976,6 +1968,34 @@ inline_transform (struct cgraph_node *node)
return todo | execute_fixup_cfg ();
}
+/* Read inline summary. Jump functions are shared among ipa-cp
+ and inliner, so when ipa-cp is active, we don't need to write them
+ twice. */
+
+static void
+inline_read_summary (void)
+{
+ if (flag_indirect_inlining && !flag_wpa)
+ {
+ ipa_register_cgraph_hooks ();
+ if (!flag_ipa_cp)
+ ipa_prop_read_jump_functions ();
+ }
+ function_insertion_hook_holder =
+ cgraph_add_function_insertion_hook (&add_new_function, NULL);
+}
+
+/* Write inline summary for node in SET.
+ Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
+ active, we don't need to write them twice. */
+
+static void
+inline_write_summary (cgraph_node_set set)
+{
+ if (flag_indirect_inlining && !flag_ipa_cp)
+ ipa_prop_write_jump_functions (set);
+}
+
struct ipa_opt_pass_d pass_ipa_inline =
{
{
@@ -1995,8 +2015,8 @@ struct ipa_opt_pass_d pass_ipa_inline =
| TODO_remove_functions /* todo_flags_finish */
},
inline_generate_summary, /* generate_summary */
- NULL, /* write_summary */
- NULL, /* read_summary */
+ inline_write_summary, /* write_summary */
+ inline_read_summary, /* read_summary */
NULL, /* function_read_summary */
0, /* TODOs */
inline_transform, /* function_transform */
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 93c407b0826..9956fbc53b7 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -33,11 +33,12 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "flags.h"
#include "diagnostic.h"
+#include "lto-streamer.h"
/* Vector where the parameter infos are actually stored. */
VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
/* Vector where the parameter infos are actually stored. */
-VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
+VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
/* Holders of ipa cgraph hooks: */
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
@@ -248,7 +249,7 @@ ipa_count_arguments (struct cgraph_edge *cs)
arg_num = gimple_call_num_args (stmt);
if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
<= (unsigned) cgraph_edge_max_uid)
- VEC_safe_grow_cleared (ipa_edge_args_t, heap,
+ VEC_safe_grow_cleared (ipa_edge_args_t, gc,
ipa_edge_args_vector, cgraph_edge_max_uid + 1);
ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
}
@@ -661,8 +662,8 @@ ipa_compute_jump_functions (struct cgraph_edge *cs)
if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions)
return;
- arguments->jump_functions = XCNEWVEC (struct ipa_jump_func,
- ipa_get_cs_argument_count (arguments));
+ arguments->jump_functions = GGC_CNEWVEC (struct ipa_jump_func,
+ ipa_get_cs_argument_count (arguments));
call = cs->call_stmt;
gcc_assert (is_gimple_call (call));
@@ -1173,7 +1174,7 @@ void
ipa_free_edge_args_substructures (struct ipa_edge_args *args)
{
if (args->jump_functions)
- free (args->jump_functions);
+ ggc_free (args->jump_functions);
memset (args, 0, sizeof (*args));
}
@@ -1191,7 +1192,7 @@ ipa_free_all_edge_args (void)
i++)
ipa_free_edge_args_substructures (args);
- VEC_free (ipa_edge_args_t, heap, ipa_edge_args_vector);
+ VEC_free (ipa_edge_args_t, gc, ipa_edge_args_vector);
ipa_edge_args_vector = NULL;
}
@@ -1262,7 +1263,22 @@ duplicate_array (void *src, size_t n)
if (!src)
return NULL;
- p = xcalloc (1, n);
+ p = xmalloc (n);
+ memcpy (p, src, n);
+ return p;
+}
+
+/* Like duplicate_array byt in GGC memory. */
+
+static void *
+duplicate_ggc_array (void *src, size_t n)
+{
+ void *p;
+
+ if (!src)
+ return NULL;
+
+ p = ggc_alloc (n);
memcpy (p, src, n);
return p;
}
@@ -1284,8 +1300,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
arg_count = ipa_get_cs_argument_count (old_args);
ipa_set_cs_argument_count (new_args, arg_count);
new_args->jump_functions = (struct ipa_jump_func *)
- duplicate_array (old_args->jump_functions,
- sizeof (struct ipa_jump_func) * arg_count);
+ duplicate_ggc_array (old_args->jump_functions,
+ sizeof (struct ipa_jump_func) * arg_count);
}
/* Hook that is called by cgraph.c when a node is duplicated. */
@@ -1875,3 +1891,283 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
VEC_free (tree, heap, parms);
}
+/* Stream out jump function JUMP_FUNC to OB. */
+
+static void
+ipa_write_jump_function (struct output_block *ob,
+ struct ipa_jump_func *jump_func)
+{
+ lto_output_uleb128_stream (ob->main_stream,
+ jump_func->type);
+
+ switch (jump_func->type)
+ {
+ case IPA_JF_UNKNOWN:
+ break;
+ case IPA_JF_CONST:
+ lto_output_tree (ob, jump_func->value.constant, true);
+ break;
+ case IPA_JF_PASS_THROUGH:
+ lto_output_tree (ob, jump_func->value.pass_through.operand, true);
+ lto_output_uleb128_stream (ob->main_stream,
+ jump_func->value.pass_through.formal_id);
+ lto_output_uleb128_stream (ob->main_stream,
+ jump_func->value.pass_through.operation);
+ break;
+ case IPA_JF_ANCESTOR:
+ lto_output_uleb128_stream (ob->main_stream,
+ jump_func->value.ancestor.offset);
+ lto_output_tree (ob, jump_func->value.ancestor.type, true);
+ lto_output_uleb128_stream (ob->main_stream,
+ jump_func->value.ancestor.formal_id);
+ break;
+ case IPA_JF_CONST_MEMBER_PTR:
+ lto_output_tree (ob, jump_func->value.member_cst.pfn, true);
+ lto_output_tree (ob, jump_func->value.member_cst.delta, false);
+ break;
+ }
+}
+
+/* Read in jump function JUMP_FUNC from IB. */
+
+static void
+ipa_read_jump_function (struct lto_input_block *ib,
+ struct ipa_jump_func *jump_func,
+ struct data_in *data_in)
+{
+ jump_func->type = (enum jump_func_type) lto_input_uleb128 (ib);
+
+ switch (jump_func->type)
+ {
+ case IPA_JF_UNKNOWN:
+ break;
+ case IPA_JF_CONST:
+ jump_func->value.constant = lto_input_tree (ib, data_in);
+ break;
+ case IPA_JF_PASS_THROUGH:
+ jump_func->value.pass_through.operand = lto_input_tree (ib, data_in);
+ jump_func->value.pass_through.formal_id = lto_input_uleb128 (ib);
+ jump_func->value.pass_through.operation = (enum tree_code) lto_input_uleb128 (ib);
+ break;
+ case IPA_JF_ANCESTOR:
+ jump_func->value.ancestor.offset = lto_input_uleb128 (ib);
+ jump_func->value.ancestor.type = lto_input_tree (ib, data_in);
+ jump_func->value.ancestor.formal_id = lto_input_uleb128 (ib);
+ break;
+ case IPA_JF_CONST_MEMBER_PTR:
+ jump_func->value.member_cst.pfn = lto_input_tree (ib, data_in);
+ jump_func->value.member_cst.delta = lto_input_tree (ib, data_in);
+ break;
+ }
+}
+
+/* Stream out NODE info to OB. */
+
+static void
+ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
+{
+ int node_ref;
+ lto_cgraph_encoder_t encoder;
+ struct ipa_node_params *info = IPA_NODE_REF (node);
+ int j;
+ struct cgraph_edge *e;
+ struct bitpack_d *bp;
+
+ encoder = ob->decl_state->cgraph_node_encoder;
+ node_ref = lto_cgraph_encoder_encode (encoder, node);
+ lto_output_uleb128_stream (ob->main_stream, node_ref);
+
+ /* Note that flags will need to be read in the opposite
+ order as we are pushing the bitflags into FLAGS. */
+ bp = bitpack_create ();
+ bp_pack_value (bp, info->called_with_var_arguments, 1);
+ gcc_assert (info->modification_analysis_done || ipa_get_param_count (info) == 0);
+ gcc_assert (info->uses_analysis_done || ipa_get_param_count (info) == 0);
+ gcc_assert (!info->node_enqueued);
+ gcc_assert (!info->ipcp_orig_node);
+ for (j = 0; j < ipa_get_param_count (info); j++)
+ {
+ bp_pack_value (bp, info->params[j].modified, 1);
+ bp_pack_value (bp, info->params[j].called, 1);
+ }
+ lto_output_bitpack (ob->main_stream, bp);
+ bitpack_delete (bp);
+ for (e = node->callees; e; e = e->next_callee)
+ {
+ struct ipa_edge_args *args = IPA_EDGE_REF (e);
+
+ lto_output_uleb128_stream (ob->main_stream, ipa_get_cs_argument_count (args));
+ for (j = 0; j < ipa_get_cs_argument_count (args); j++)
+ ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
+ }
+}
+
+/* Srtream in NODE info from IB. */
+
+static void
+ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
+ struct data_in *data_in)
+{
+ struct ipa_node_params *info = IPA_NODE_REF (node);
+ int k;
+ struct cgraph_edge *e;
+ struct bitpack_d *bp;
+
+ ipa_initialize_node_params (node);
+
+ /* Note that the flags must be read in the opposite
+ order in which they were written (the bitflags were
+ pushed into FLAGS). */
+ bp = lto_input_bitpack (ib);
+ info->called_with_var_arguments = bp_unpack_value (bp, 1);
+ if (ipa_get_param_count (info) != 0)
+ {
+ info->modification_analysis_done = true;
+ info->uses_analysis_done = true;
+ }
+ info->node_enqueued = false;
+ for (k = 0; k < ipa_get_param_count (info); k++)
+ {
+ info->params[k].modified = bp_unpack_value (bp, 1);
+ info->params[k].called = bp_unpack_value (bp, 1);
+ }
+ bitpack_delete (bp);
+ for (e = node->callees; e; e = e->next_callee)
+ {
+ struct ipa_edge_args *args = IPA_EDGE_REF (e);
+ int count = lto_input_uleb128 (ib);
+
+ if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
+ <= (unsigned) cgraph_edge_max_uid)
+ VEC_safe_grow_cleared (ipa_edge_args_t, gc,
+ ipa_edge_args_vector, cgraph_edge_max_uid + 1);
+ ipa_set_cs_argument_count (args, count);
+ if (!count)
+ continue;
+
+ args->jump_functions = GGC_CNEWVEC (struct ipa_jump_func,
+ ipa_get_cs_argument_count (args));
+ for (k = 0; k < ipa_get_cs_argument_count (args); k++)
+ ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), data_in);
+ }
+}
+
+/* Write jump functions for nodes in SET. */
+
+void
+ipa_prop_write_jump_functions (cgraph_node_set set)
+{
+ struct cgraph_node *node;
+ struct output_block *ob = create_output_block (LTO_section_jump_functions);
+ unsigned int count = 0;
+ cgraph_node_set_iterator csi;
+
+ ob->cgraph_node = NULL;
+
+ for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
+ {
+ node = csi_node (csi);
+ if (node->analyzed && IPA_NODE_REF (node) != NULL)
+ count++;
+ }
+
+ lto_output_uleb128_stream (ob->main_stream, count);
+
+ /* Process all of the functions. */
+ for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
+ {
+ node = csi_node (csi);
+ if (node->analyzed && IPA_NODE_REF (node) != NULL)
+ ipa_write_node_info (ob, node);
+ }
+ lto_output_1_stream (ob->main_stream, 0);
+ produce_asm (ob, NULL);
+ destroy_output_block (ob);
+}
+
+/* Read section in file FILE_DATA of length LEN with data DATA. */
+
+static void
+ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
+ size_t len)
+{
+ const struct lto_function_header *header =
+ (const struct lto_function_header *) data;
+ const int32_t cfg_offset = sizeof (struct lto_function_header);
+ const int32_t main_offset = cfg_offset + header->cfg_size;
+ const int32_t string_offset = main_offset + header->main_size;
+ struct data_in *data_in;
+ struct lto_input_block ib_main;
+ unsigned int i;
+ unsigned int count;
+
+ LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
+ header->main_size);
+
+ data_in =
+ lto_data_in_create (file_data, (const char *) data + string_offset,
+ header->string_size, NULL);
+ count = lto_input_uleb128 (&ib_main);
+
+ for (i = 0; i < count; i++)
+ {
+ unsigned int index;
+ struct cgraph_node *node;
+ lto_cgraph_encoder_t encoder;
+
+ index = lto_input_uleb128 (&ib_main);
+ encoder = file_data->cgraph_node_encoder;
+ node = lto_cgraph_encoder_deref (encoder, index);
+ ipa_read_node_info (&ib_main, node, data_in);
+ }
+ lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
+ len);
+ lto_data_in_delete (data_in);
+}
+
+/* Read ipcp jump functions. */
+
+void
+ipa_prop_read_jump_functions (void)
+{
+ struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+ struct lto_file_decl_data *file_data;
+ unsigned int j = 0;
+
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
+ ipa_register_cgraph_hooks ();
+
+ while ((file_data = file_data_vec[j++]))
+ {
+ size_t len;
+ const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len);
+
+ if (data)
+ ipa_prop_read_section (file_data, data, len);
+ }
+}
+
+/* After merging units, we can get mismatch in argument counts.
+ Also decl merging might've rendered parameter lists obsolette.
+ Also compute called_with_variable_arg info. */
+
+void
+ipa_update_after_lto_read (void)
+{
+ struct cgraph_node *node;
+ struct cgraph_edge *cs;
+
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ if (!node->analyzed)
+ continue;
+ ipa_populate_param_decls (node, IPA_NODE_REF (node));
+ for (cs = node->callees; cs; cs = cs->next_callee)
+ {
+ if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
+ != ipa_get_param_count (IPA_NODE_REF (cs->callee)))
+ ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
+ }
+ }
+}
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 9b5f74f87ad..35005954deb 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -72,7 +72,7 @@ enum ipa_lattice_type
/* Structure holding data required to describe a pass-through jump function. */
-struct ipa_pass_through_data
+struct GTY(()) ipa_pass_through_data
{
/* If an operation is to be performed on the original parameter, this is the
second (constant) operand. */
@@ -89,7 +89,7 @@ struct ipa_pass_through_data
/* Structure holding data required to describe and ancestor pass throu
funkci. */
-struct ipa_ancestor_jf_data
+struct GTY(()) ipa_ancestor_jf_data
{
/* Offset of the field representing the ancestor. */
HOST_WIDE_INT offset;
@@ -101,30 +101,28 @@ struct ipa_ancestor_jf_data
/* Structure holding a C++ member pointer constant. Holds a pointer to the
method and delta offset. */
-struct ipa_member_ptr_cst
+struct GTY(()) ipa_member_ptr_cst
{
tree pfn;
tree delta;
};
-/* Represents a value of a jump function. pass_through is used only in jump
- function context. constant represents the actual constant in constant jump
- functions and member_cst holds constant c++ member functions. */
-union jump_func_value
-{
- tree constant;
- struct ipa_pass_through_data pass_through;
- struct ipa_ancestor_jf_data ancestor;
- struct ipa_member_ptr_cst member_cst;
-};
-
/* A jump function for a callsite represents the values passed as actual
arguments of the callsite. See enum jump_func_type for the various
types of jump functions supported. */
-struct ipa_jump_func
+struct GTY (()) ipa_jump_func
{
enum jump_func_type type;
- union jump_func_value value;
+ /* Represents a value of a jump function. pass_through is used only in jump
+ function context. constant represents the actual constant in constant jump
+ functions and member_cst holds constant c++ member functions. */
+ union jump_func_value
+ {
+ tree GTY ((tag ("IPA_JF_CONST"))) constant;
+ struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
+ struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
+ struct ipa_member_ptr_cst GTY ((tag ("IPA_JF_CONST_MEMBER_PTR"))) member_cst;
+ } GTY ((desc ("%1.type"))) value;
};
/* All formal parameters in the program have a cval computed by
@@ -280,15 +278,15 @@ ipa_is_called_with_var_arguments (struct ipa_node_params *info)
/* ipa_edge_args stores information related to a callsite and particularly
its arguments. It is pointed to by a field in the
callsite's corresponding cgraph_edge. */
-struct ipa_edge_args
+typedef struct GTY(()) ipa_edge_args
{
/* Number of actual arguments in this callsite. When set to 0,
this callsite's parameters would not be analyzed by the different
stages of IPA CP. */
int argument_count;
/* Array of the callsite's jump function of each parameter. */
- struct ipa_jump_func *jump_functions;
-};
+ struct ipa_jump_func GTY ((length ("%h.argument_count"))) *jump_functions;
+} ipa_edge_args_t;
/* ipa_edge_args access functions. Please use these to access fields that
are or will be shared among various passes. */
@@ -321,18 +319,17 @@ ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
/* Vectors need to have typedefs of structures. */
typedef struct ipa_node_params ipa_node_params_t;
-typedef struct ipa_edge_args ipa_edge_args_t;
/* Types of vectors holding the infos. */
DEF_VEC_O (ipa_node_params_t);
DEF_VEC_ALLOC_O (ipa_node_params_t, heap);
DEF_VEC_O (ipa_edge_args_t);
-DEF_VEC_ALLOC_O (ipa_edge_args_t, heap);
+DEF_VEC_ALLOC_O (ipa_edge_args_t, gc);
/* Vector where the parameter infos are actually stored. */
extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
/* Vector where the parameter infos are actually stored. */
-extern VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
+extern GTY(()) VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
/* Return the associated parameter/argument info corresponding to the given
node/edge. */
@@ -378,12 +375,12 @@ static inline void
ipa_check_create_edge_args (void)
{
if (!ipa_edge_args_vector)
- ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, heap,
+ ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, gc,
cgraph_edge_max_uid);
if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
<= (unsigned) cgraph_edge_max_uid)
- VEC_safe_grow_cleared (ipa_edge_args_t, heap, ipa_edge_args_vector,
+ VEC_safe_grow_cleared (ipa_edge_args_t, gc, ipa_edge_args_vector,
cgraph_edge_max_uid + 1);
}
@@ -508,6 +505,10 @@ ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
ipa_parm_adjustment_vec);
void ipa_dump_param_adjustments (FILE *, ipa_parm_adjustment_vec, tree);
+void ipa_prop_write_jump_functions (cgraph_node_set set);
+void ipa_prop_read_jump_functions (void);
+void ipa_update_after_lto_read (void);
+
/* From tree-sra.c: */
bool build_ref_for_offset (tree *, tree, HOST_WIDE_INT, tree, bool);
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index ea1d81ea5e2..e37af05d08e 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -330,12 +330,11 @@ check_call (funct_state local, gimple call, bool ipa)
/* When not in IPA mode, we can still handle self recursion. */
if (!ipa && callee_t == current_function_decl)
local->looping = true;
- /* The callee is either unknown (indirect call) or there is just no
- scannable code for it (external call) . We look to see if there
- are any bits available for the callee (such as by declaration or
- because it is builtin) and process solely on the basis of those
- bits. */
- else if (avail <= AVAIL_OVERWRITABLE || !ipa)
+ /* Either calle is unknown or we are doing local analysis.
+ Look to see if there are any bits available for the callee (such as by
+ declaration or because it is builtin) and process solely on the basis of
+ those bits. */
+ else if (!ipa || !callee_t)
{
if (possibly_throws && flag_non_call_exceptions)
{
@@ -492,13 +491,6 @@ analyze_function (struct cgraph_node *fn, bool ipa)
funct_state l;
basic_block this_block;
- if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
- {
- if (dump_file)
- fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
- return NULL;
- }
-
l = XCNEW (struct funct_state_d);
l->pure_const_state = IPA_CONST;
l->state_previously_known = IPA_NEITHER;
@@ -609,7 +601,7 @@ end:
static void
add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
{
- if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
+ if (cgraph_function_body_availability (node) < AVAIL_OVERWRITABLE)
return;
/* There are some shared nodes, in particular the initializers on
static declarations. We do not need to scan them more than once
@@ -686,12 +678,12 @@ generate_summary (void)
/* Process all of the functions.
- We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
- guarantee that what we learn about the one we see will be true
- for the one that overrides it.
- */
+ We process AVAIL_OVERWRITABLE functions. We can not use the results
+ by default, but the info can be used at LTO with -fwhole-program or
+ when function got clonned and the clone is AVAILABLE. */
+
for (node = cgraph_nodes; node; node = node->next)
- if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
+ if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
set_function_state (node, analyze_function (node, true));
pointer_set_destroy (visited_nodes);
@@ -878,6 +870,12 @@ propagate (void)
if (w_l->looping)
looping = true;
+ if (cgraph_function_body_availability (w) == AVAIL_OVERWRITABLE)
+ {
+ looping |= w_l->looping_previously_known;
+ if (pure_const_state < w_l->state_previously_known)
+ pure_const_state = w_l->state_previously_known;
+ }
if (pure_const_state == IPA_NEITHER)
break;
@@ -901,6 +899,20 @@ propagate (void)
if (y_l->looping)
looping = true;
}
+ else
+ {
+ int flags = flags_from_decl_or_type (y->decl);
+
+ if (flags & ECF_LOOPING_CONST_OR_PURE)
+ looping = true;
+ if (flags & ECF_CONST)
+ ;
+ else if ((flags & ECF_PURE) && pure_const_state == IPA_CONST)
+ pure_const_state = IPA_PURE;
+ else
+ pure_const_state = IPA_NEITHER, looping = true;
+
+ }
}
w_info = (struct ipa_dfs_info *) w->aux;
w = w_info->next_cycle;
@@ -988,7 +1000,8 @@ propagate (void)
struct cgraph_edge *e;
funct_state w_l = get_function_state (w);
- if (w_l->can_throw)
+ if (w_l->can_throw
+ || cgraph_function_body_availability (w) == AVAIL_OVERWRITABLE)
can_throw = true;
if (can_throw)
@@ -1008,6 +1021,8 @@ propagate (void)
&& e->can_throw_external)
can_throw = true;
}
+ else if (e->can_throw_external && !TREE_NOTHROW (y->decl))
+ can_throw = true;
}
w_info = (struct ipa_dfs_info *) w->aux;
w = w_info->next_cycle;
@@ -1046,7 +1061,7 @@ propagate (void)
free (node->aux);
node->aux = NULL;
}
- if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
+ if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
free (get_function_state (node));
}
@@ -1109,15 +1124,16 @@ local_pure_const (void)
fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
return 0;
}
-
- l = analyze_function (cgraph_node (current_function_decl), false);
- if (!l)
+ if (cgraph_function_body_availability (cgraph_node (current_function_decl))
+ <= AVAIL_OVERWRITABLE)
{
if (dump_file)
fprintf (dump_file, "Function has wrong visibility; ignoring\n");
return 0;
}
+ l = analyze_function (cgraph_node (current_function_decl), false);
+
switch (l->pure_const_state)
{
case IPA_CONST:
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 795684692bf..8610f13311f 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -318,6 +318,8 @@ has_proper_scope_for_analysis (tree t)
if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
return false;
+ /* FIXME: for LTO we should include PUBLIC vars too. This is bit difficult
+ as summarie would need unsharing. */
if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
return false;
@@ -413,31 +415,25 @@ check_call (ipa_reference_local_vars_info_t local, gimple stmt)
{
int flags = gimple_call_flags (stmt);
tree callee_t = gimple_call_fndecl (stmt);
- enum availability avail = AVAIL_NOT_AVAILABLE;
- if (callee_t)
+ /* Process indirect calls. All direct calles are handled at propagation
+ time. */
+ if (!callee_t)
{
- struct cgraph_node* callee = cgraph_node(callee_t);
- avail = cgraph_function_body_availability (callee);
- }
-
- if (avail <= AVAIL_OVERWRITABLE)
- if (local)
- {
- if (flags & ECF_CONST)
- ;
- else if (flags & ECF_PURE)
+ if (flags & ECF_CONST)
+ ;
+ else if (flags & ECF_PURE)
+ local->calls_read_all = true;
+ else
+ {
local->calls_read_all = true;
- else
- {
- local->calls_read_all = true;
+ /* When function does not reutrn, it is safe to ignore anythign it writes
+ to, because the effect will never happen. */
+ if ((flags & (ECF_NOTHROW | ECF_NORETURN))
+ != (ECF_NOTHROW | ECF_NORETURN))
local->calls_write_all = true;
- }
- }
- /* TODO: To be able to produce sane results, we should also handle
- common builtins, in particular throw.
- Indirect calls hsould be only counted and as inliner is replacing them
- by direct calls, we can conclude if any indirect calls are left in body */
+ }
+ }
}
/* TP is the part of the tree currently under the microscope.
@@ -527,7 +523,7 @@ propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x
{
struct cgraph_node *y = e->callee;
- /* Only look at the master nodes and skip external nodes. */
+ /* Only look into nodes we can propagate something. */
if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
{
if (get_reference_vars_info (y))
@@ -671,6 +667,7 @@ analyze_function (struct cgraph_node *fn)
#ifdef ENABLE_CHECKING
tree step;
#endif
+ ipa_reference_local_vars_info_t local;
if (dump_file)
fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
@@ -705,6 +702,21 @@ analyze_function (struct cgraph_node *fn)
scan_stmt_for_static_refs (&gsi, fn);
}
+ local = get_reference_vars_info (fn)->local;
+ if ((flags_from_decl_or_type (decl) & (ECF_NOTHROW | ECF_NORETURN))
+ == (ECF_NOTHROW | ECF_NORETURN))
+ {
+ local->calls_write_all = false;
+ bitmap_clear (local->statics_written);
+ }
+
+ /* Free bitmaps of direct references if we can not use them anyway. */
+ if (local->calls_write_all)
+ BITMAP_FREE (local->statics_written);
+ if (local->calls_read_all)
+ BITMAP_FREE (local->statics_read);
+
+
#ifdef ENABLE_CHECKING
/* Verify that all local initializers was expanded by gimplifier. */
for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
@@ -964,10 +976,12 @@ generate_summary (void)
removed from the local maps. This will include all of the
variables that were found to escape in the function
scanning. */
- bitmap_and_into (l->statics_read,
- all_module_statics);
- bitmap_and_into (l->statics_written,
- all_module_statics);
+ if (l->statics_read)
+ bitmap_and_into (l->statics_read,
+ all_module_statics);
+ if (l->statics_written)
+ bitmap_and_into (l->statics_written,
+ all_module_statics);
}
BITMAP_FREE(module_statics_readonly);
@@ -986,19 +1000,21 @@ generate_summary (void)
"\nFunction name:%s/%i:",
cgraph_node_name (node), node->uid);
fprintf (dump_file, "\n locals read: ");
- EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
- 0, index, bi)
- {
- fprintf (dump_file, "%s ",
- get_static_name (index));
- }
+ if (l->statics_read)
+ EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
+ 0, index, bi)
+ {
+ fprintf (dump_file, "%s ",
+ get_static_name (index));
+ }
fprintf (dump_file, "\n locals written: ");
- EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
- 0, index, bi)
- {
- fprintf(dump_file, "%s ",
- get_static_name (index));
- }
+ if (l->statics_written)
+ EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
+ 0, index, bi)
+ {
+ fprintf(dump_file, "%s ",
+ get_static_name (index));
+ }
if (l->calls_read_all)
fprintf (dump_file, "\n calls read all: ");
if (l->calls_write_all)
@@ -1012,9 +1028,9 @@ generate_summary (void)
static bool
write_node_summary_p (struct cgraph_node *node)
{
+ gcc_assert (node->global.inlined_to == NULL);
return (node->analyzed
- && node->global.inlined_to == NULL
- && cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE
+ && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE
&& get_reference_vars_info (node) != NULL);
}
@@ -1053,18 +1069,28 @@ ipa_reference_write_summary (cgraph_node_set set)
lto_output_uleb128_stream (ob->main_stream, node_ref);
/* Stream out the statics read. */
- lto_output_uleb128_stream (ob->main_stream,
- bitmap_count_bits (l->statics_read));
- EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
- lto_output_var_decl_index(ob->decl_state, ob->main_stream,
- get_static_decl (index));
+ if (l->calls_read_all)
+ lto_output_sleb128_stream (ob->main_stream, -1);
+ else
+ {
+ lto_output_sleb128_stream (ob->main_stream,
+ bitmap_count_bits (l->statics_read));
+ EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
+ lto_output_var_decl_index(ob->decl_state, ob->main_stream,
+ get_static_decl (index));
+ }
/* Stream out the statics written. */
- lto_output_uleb128_stream (ob->main_stream,
- bitmap_count_bits (l->statics_written));
- EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
- lto_output_var_decl_index(ob->decl_state, ob->main_stream,
- get_static_decl (index));
+ if (l->calls_write_all)
+ lto_output_sleb128_stream (ob->main_stream, -1);
+ else
+ {
+ lto_output_sleb128_stream (ob->main_stream,
+ bitmap_count_bits (l->statics_written));
+ EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
+ lto_output_var_decl_index(ob->decl_state, ob->main_stream,
+ get_static_decl (index));
+ }
}
}
lto_destroy_simple_output_block (ob);
@@ -1101,7 +1127,7 @@ ipa_reference_read_summary (void)
unsigned int j, index;
struct cgraph_node *node;
ipa_reference_local_vars_info_t l;
- unsigned int v_count;
+ int v_count;
lto_cgraph_encoder_t encoder;
index = lto_input_uleb128 (ib);
@@ -1110,26 +1136,32 @@ ipa_reference_read_summary (void)
l = init_function_info (node);
/* Set the statics read. */
- v_count = lto_input_uleb128 (ib);
- for (j = 0; j < v_count; j++)
- {
- unsigned int var_index = lto_input_uleb128 (ib);
- tree v_decl = lto_file_decl_data_get_var_decl (file_data,
- var_index);
- add_static_var (v_decl);
- bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
- }
+ v_count = lto_input_sleb128 (ib);
+ if (v_count == -1)
+ l->calls_read_all = true;
+ else
+ for (j = 0; j < (unsigned int)v_count; j++)
+ {
+ unsigned int var_index = lto_input_uleb128 (ib);
+ tree v_decl = lto_file_decl_data_get_var_decl (file_data,
+ var_index);
+ add_static_var (v_decl);
+ bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
+ }
/* Set the statics written. */
- v_count = lto_input_uleb128 (ib);
- for (j = 0; j < v_count; j++)
- {
- unsigned int var_index = lto_input_uleb128 (ib);
- tree v_decl = lto_file_decl_data_get_var_decl (file_data,
- var_index);
- add_static_var (v_decl);
- bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
- }
+ v_count = lto_input_sleb128 (ib);
+ if (v_count == -1)
+ l->calls_write_all = true;
+ else
+ for (j = 0; j < (unsigned int)v_count; j++)
+ {
+ unsigned int var_index = lto_input_uleb128 (ib);
+ tree v_decl = lto_file_decl_data_get_var_decl (file_data,
+ var_index);
+ add_static_var (v_decl);
+ bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
+ }
}
lto_destroy_simple_input_block (file_data,
@@ -1141,6 +1173,30 @@ ipa_reference_read_summary (void)
+/* Set READ_ALL/WRITE_ALL based on DECL flags. */
+static void
+read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
+{
+ int flags = flags_from_decl_or_type (decl);
+ if (flags & ECF_CONST)
+ ;
+ else if (flags & ECF_PURE)
+ *read_all = true;
+ else
+ {
+ /* TODO: To be able to produce sane results, we should also handle
+ common builtins, in particular throw.
+ Indirect calls hsould be only counted and as inliner is replacing them
+ by direct calls, we can conclude if any indirect calls are left in body */
+ *read_all = true;
+ /* When function does not reutrn, it is safe to ignore anythign it writes
+ to, because the effect will never happen. */
+ if ((flags & (ECF_NOTHROW | ECF_NORETURN))
+ != (ECF_NOTHROW | ECF_NORETURN))
+ *write_all = true;
+ }
+}
+
/* Produce the global information by preforming a transitive closure
on the local information that was produced by ipa_analyze_function
and ipa_analyze_variable. */
@@ -1173,6 +1229,7 @@ propagate (void)
ipa_reference_global_vars_info_t node_g =
XCNEW (struct ipa_reference_global_vars_info_d);
ipa_reference_local_vars_info_t node_l;
+ struct cgraph_edge *e;
bool read_all;
bool write_all;
@@ -1193,6 +1250,15 @@ propagate (void)
read_all = node_l->calls_read_all;
write_all = node_l->calls_write_all;
+ /* When function is overwrittable, we can not assume anything. */
+ if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
+ read_write_all_from_decl (node->decl, &read_all, &write_all);
+
+ for (e = node->callees; e; e = e->next_callee)
+ if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
+ read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
+
+
/* If any node in a cycle is calls_read_all or calls_write_all
they all are. */
w_info = (struct ipa_dfs_info *) node->aux;
@@ -1201,6 +1267,15 @@ propagate (void)
{
ipa_reference_local_vars_info_t w_l =
get_reference_vars_info (w)->local;
+
+ /* When function is overwrittable, we can not assume anything. */
+ if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
+ read_write_all_from_decl (w->decl, &read_all, &write_all);
+
+ for (e = w->callees; e; e = e->next_callee)
+ if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
+ read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
+
read_all |= w_l->calls_read_all;
write_all |= w_l->calls_write_all;
@@ -1208,6 +1283,7 @@ propagate (void)
w = w_info->next_cycle;
}
+
/* Initialized the bitmaps for the reduced nodes */
if (read_all)
node_g->statics_read = all_module_statics;
@@ -1217,7 +1293,6 @@ propagate (void)
bitmap_copy (node_g->statics_read,
node_l->statics_read);
}
-
if (write_all)
node_g->statics_written = all_module_statics;
else
@@ -1289,19 +1364,21 @@ propagate (void)
"\nFunction name:%s/%i:",
cgraph_node_name (node), node->uid);
fprintf (dump_file, "\n locals read: ");
- EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
- 0, index, bi)
- {
- fprintf (dump_file, "%s ",
- get_static_name (index));
- }
+ if (node_l->statics_read)
+ EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
+ 0, index, bi)
+ {
+ fprintf (dump_file, "%s ",
+ get_static_name (index));
+ }
fprintf (dump_file, "\n locals written: ");
- EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
- 0, index, bi)
- {
- fprintf(dump_file, "%s ",
- get_static_name (index));
- }
+ if (node_l->statics_written)
+ EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
+ 0, index, bi)
+ {
+ fprintf(dump_file, "%s ",
+ get_static_name (index));
+ }
w_info = (struct ipa_dfs_info *) node->aux;
w = w_info->next_cycle;
@@ -1333,19 +1410,25 @@ propagate (void)
w = w_info->next_cycle;
}
fprintf (dump_file, "\n globals read: ");
- EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
- 0, index, bi)
- {
- fprintf (dump_file, "%s ",
- get_static_name (index));
- }
+ if (node_g->statics_read == all_module_statics)
+ fprintf (dump_file, "ALL");
+ else
+ EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
+ 0, index, bi)
+ {
+ fprintf (dump_file, "%s ",
+ get_static_name (index));
+ }
fprintf (dump_file, "\n globals written: ");
- EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
- 0, index, bi)
- {
- fprintf (dump_file, "%s ",
- get_static_name (index));
- }
+ if (node_g->statics_written == all_module_statics)
+ fprintf (dump_file, "ALL");
+ else
+ EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
+ 0, index, bi)
+ {
+ fprintf (dump_file, "%s ",
+ get_static_name (index));
+ }
}
}
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 822dccb18d5..c67e89cbd79 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -841,6 +841,7 @@ process_single_reg_class_operands (bool in_p, int freq)
[ira_class_hard_regs[cl][0]]) >= 0
&& reg_class_size[cl] <= (unsigned) CLASS_MAX_NREGS (cl, mode))
{
+ int i, size;
cost
= (freq
* (in_p
@@ -848,10 +849,12 @@ process_single_reg_class_operands (bool in_p, int freq)
: ira_get_register_move_cost (mode, cl, cover_class)));
ira_allocate_and_set_costs
(&ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a), cover_class, 0);
- ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a)
- [ira_class_hard_reg_index
- [cover_class][ira_class_hard_regs[cl][0]]]
- -= cost;
+ size = ira_reg_class_nregs[cover_class][mode];
+ for (i = 0; i < size; i++)
+ ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a)
+ [ira_class_hard_reg_index
+ [cover_class][ira_class_hard_regs[cl][i]]]
+ -= cost;
}
}
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index fbf0df21c24..6b340a37d58 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -372,8 +372,16 @@ output_cgraph (cgraph_node_set set)
for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
{
node = csi_node (csi);
- for (edge = node->callees; edge; edge = edge->next_callee)
- lto_output_edge (ob, edge, encoder);
+ if (node->callees)
+ {
+ /* Output edges in backward direction, so the reconstructed callgraph
+ match and it is easy to associate call sites in the IPA pass summaries. */
+ edge = node->callees;
+ while (edge->next_callee)
+ edge = edge->next_callee;
+ for (; edge; edge = edge->prev_callee)
+ lto_output_edge (ob, edge, encoder);
+ }
}
lto_output_uleb128_stream (ob->main_stream, 0);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 4f7551d0d17..000be331a94 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "ipa-utils.h"
#include "lto-streamer.h"
+#include "tree-pass.h"
/* Data structure used to hash file names in the source_location field. */
struct string_slot
@@ -282,13 +283,14 @@ lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
xloc.file = canon_file_name (xloc.file);
xloc.line = lto_input_sleb128 (ib);
xloc.column = lto_input_sleb128 (ib);
+ xloc.sysp = lto_input_sleb128 (ib);
if (data_in->current_file != xloc.file)
{
if (data_in->current_file)
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
- linemap_add (line_table, LC_ENTER, false, xloc.file, xloc.line);
+ linemap_add (line_table, LC_ENTER, xloc.sysp, xloc.file, xloc.line);
}
else if (data_in->current_line != xloc.line)
linemap_line_start (line_table, xloc.line, xloc.column);
@@ -1341,6 +1343,8 @@ input_function (tree fn_decl, struct data_in *data_in,
fixup_call_stmt_edges (cgraph_node (fn_decl), stmts);
update_ssa (TODO_update_ssa_only_virtuals);
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
free (stmts);
}
@@ -1455,6 +1459,15 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
/* Restore decl state */
file_data->current_decl_state = file_data->global_decl_state;
+ /* FIXME: ipa_transforms_to_apply holds list of passes that have optimization
+ summaries computed and needs to apply changes. At the moment WHOPR only
+ supports inlining, so we can push it here by hand. In future we need to stream
+ this field into ltrans compilation. This will also need to move the field
+ from struct function into cgraph node where it belongs. */
+ if (flag_ltrans && !cgraph_node (fn_decl)->global.inlined_to)
+ VEC_safe_push (ipa_opt_pass, heap,
+ cfun->ipa_transforms_to_apply,
+ (ipa_opt_pass)&pass_ipa_inline);
pop_cfun ();
}
else
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 737206cb8f6..d593aacc4fc 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -618,6 +618,7 @@ lto_output_location (struct output_block *ob, location_t loc)
output_string (ob, ob->main_stream, xloc.file);
output_sleb128 (ob, xloc.line);
output_sleb128 (ob, xloc.column);
+ output_sleb128 (ob, xloc.sysp);
ob->current_file = xloc.file;
ob->current_line = xloc.line;
@@ -1762,7 +1763,7 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn)
/* Create the header in the file using OB. If the section type is for
a function, set FN to the decl for that function. */
-static void
+void
produce_asm (struct output_block *ob, tree fn)
{
enum lto_section_type section_type = ob->section_type;
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index 36172c03131..5b925db504e 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -157,6 +157,9 @@ lto_get_section_name (int section_type, const char *name)
case LTO_section_cgraph:
return concat (LTO_SECTION_NAME_PREFIX, ".cgraph", NULL);
+ case LTO_section_jump_functions:
+ return concat (LTO_SECTION_NAME_PREFIX, ".jmpfuncs", NULL);
+
case LTO_section_ipa_pure_const:
return concat (LTO_SECTION_NAME_PREFIX, ".pureconst", NULL);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 4d90ecb0d0c..de1ee080b84 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -256,6 +256,7 @@ enum lto_section_type
LTO_section_function_body,
LTO_section_static_initializer,
LTO_section_cgraph,
+ LTO_section_jump_functions,
LTO_section_ipa_pure_const,
LTO_section_ipa_reference,
LTO_section_symtab,
@@ -827,6 +828,7 @@ extern struct output_block *create_output_block (enum lto_section_type);
extern void destroy_output_block (struct output_block *);
extern void lto_output_tree (struct output_block *, tree, bool);
extern void lto_output_bitpack (struct lto_output_stream *, struct bitpack_d *);
+extern void produce_asm (struct output_block *ob, tree fn);
/* In lto-cgraph.c */
@@ -843,9 +845,9 @@ void input_cgraph (void);
extern void lto_symtab_register_decl (tree, ld_plugin_symbol_resolution_t,
struct lto_file_decl_data *);
extern void lto_symtab_merge_decls (void);
+extern void lto_symtab_merge_cgraph_nodes (void);
extern tree lto_symtab_prevailing_decl (tree decl);
extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree decl);
-extern void lto_symtab_clear_resolution (tree decl);
/* In lto-opts.c. */
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index 275875180c6..642b6235d90 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -41,6 +41,9 @@ struct GTY(()) lto_symtab_entry_def
tree id;
/* The symbol table entry, a DECL. */
tree decl;
+ /* The cgraph node if decl is a function decl. Filled in during the
+ merging process. */
+ struct cgraph_node *node;
/* LTO file-data and symbol resolution for this decl. */
struct lto_file_decl_data * GTY((skip (""))) file_data;
enum ld_plugin_symbol_resolution resolution;
@@ -232,18 +235,12 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
tree prevailing_decl = prevailing->decl;
tree decl = entry->decl;
tree prevailing_type, type;
- struct cgraph_node *node;
/* Merge decl state in both directions, we may still end up using
the new decl. */
TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
TREE_ADDRESSABLE (decl) |= TREE_ADDRESSABLE (prevailing_decl);
- /* Replace a cgraph node of entry with the prevailing one. */
- if (TREE_CODE (decl) == FUNCTION_DECL
- && (node = cgraph_get_node (decl)) != NULL)
- lto_cgraph_replace_node (node, cgraph_get_node (prevailing_decl));
-
/* The linker may ask us to combine two incompatible symbols.
Detect this case and notify the caller of required diagnostics. */
@@ -355,15 +352,12 @@ lto_symtab_resolve_replaceable_p (lto_symtab_entry_t e)
static bool
lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
{
- struct cgraph_node *node;
-
if (!TREE_STATIC (e->decl))
return false;
/* For functions we need a non-discarded body. */
if (TREE_CODE (e->decl) == FUNCTION_DECL)
- return ((node = cgraph_get_node (e->decl))
- && node->analyzed);
+ return (e->node && e->node->analyzed);
/* A variable should have a size. */
else if (TREE_CODE (e->decl) == VAR_DECL)
@@ -393,6 +387,9 @@ lto_symtab_resolve_symbols (void **slot)
diagnose ODR violations. */
for (; e; e = e->next)
{
+ if (TREE_CODE (e->decl) == FUNCTION_DECL)
+ e->node = cgraph_get_node (e->decl);
+
if (!lto_symtab_resolve_can_prevail_p (e))
{
e->resolution = LDPR_RESOLVED_IR;
@@ -531,7 +528,7 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
prevailing = (lto_symtab_entry_t) *slot;
/* For functions choose one with a cgraph node. */
if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
- while (!cgraph_get_node (prevailing->decl)
+ while (!prevailing->node
&& prevailing->next)
prevailing = prevailing->next;
/* We do not stream varpool nodes, so the first decl has to
@@ -600,7 +597,8 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
lto_symtab_merge_decls_2 (slot);
/* Drop all but the prevailing decl from the symtab. */
- prevailing->next = NULL;
+ if (TREE_CODE (prevailing->decl) != FUNCTION_DECL)
+ prevailing->next = NULL;
return 1;
}
@@ -614,6 +612,40 @@ lto_symtab_merge_decls (void)
htab_traverse (lto_symtab_identifiers, lto_symtab_merge_decls_1, NULL);
}
+/* Helper to process the decl chain for the symbol table entry *SLOT. */
+
+static int
+lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+{
+ lto_symtab_entry_t e, prevailing = (lto_symtab_entry_t) *slot;
+
+ if (!prevailing->next)
+ return 1;
+
+ gcc_assert (TREE_CODE (prevailing->decl) == FUNCTION_DECL);
+
+ /* Replace the cgraph node of each entry with the prevailing one. */
+ for (e = prevailing->next; e; e = e->next)
+ {
+ if (e->node != NULL)
+ lto_cgraph_replace_node (e->node, prevailing->node);
+ }
+
+ /* Drop all but the prevailing decl from the symtab. */
+ prevailing->next = NULL;
+
+ return 1;
+}
+
+/* Merge cgraph nodes according to the symbol merging done by
+ lto_symtab_merge_decls. */
+
+void
+lto_symtab_merge_cgraph_nodes (void)
+{
+ lto_symtab_maybe_init_hash_table ();
+ htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL);
+}
/* Given the decl DECL, return the prevailing decl with the same name. */
@@ -641,53 +673,4 @@ lto_symtab_prevailing_decl (tree decl)
return ret->decl;
}
-/* Remove any storage used to store resolution of DECL. */
-
-void
-lto_symtab_clear_resolution (tree decl)
-{
- struct lto_symtab_entry_def temp;
- lto_symtab_entry_t head;
- void **slot;
-
- if (!TREE_PUBLIC (decl))
- return;
-
- /* LTO FIXME: There should be no DECL_ABSTRACT in the middle end. */
- if (TREE_CODE (decl) == FUNCTION_DECL && DECL_ABSTRACT (decl))
- return;
-
- gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
-
- lto_symtab_maybe_init_hash_table ();
- temp.id = DECL_ASSEMBLER_NAME (decl);
- slot = htab_find_slot (lto_symtab_identifiers, &temp, NO_INSERT);
- if (!*slot)
- return;
-
- head = (lto_symtab_entry_t) *slot;
- if (head->decl == decl)
- {
- if (head->next)
- {
- *slot = head->next;
- head->next = NULL;
- }
- else
- htab_remove_elt (lto_symtab_identifiers, &temp);
- }
- else
- {
- lto_symtab_entry_t e;
- while (head->next && head->next->decl != decl)
- head = head->next;
- if (head->next)
- {
- e = head->next;
- head->next = e->next;
- e->next = NULL;
- }
- }
-}
-
#include "gt-lto-symtab.h"
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 938d32cb2ef..d6c3325846d 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,23 @@
+2009-10-22 Richard Guenther <rguenther@suse.de>
+
+ * lto.c (lto_fixup_jump_functions): Remove.
+ (lto_fixup_decls): Do not fixup jump functions.
+ (read_cgraph_and_symbols): Schedule cgraph merging after
+ summary reading. Schedule type and decl fixup before
+ summary reading.
+
+2009-10-22 Richard Guenther <rguenther@suse.de>
+
+ * lto.c (lto_fixup_data_t): Remove free_list member.
+ (lto_fixup_tree): Do not insert into free_list.
+ (free_decl): Remove.
+ (lto_fixup_decls): Remove free-list handling.
+
+2009-10-22 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (lto_fixup_jump_functions): New function.
+ (lto_fixup_decls): Use it.
+
2009-10-16 Richard Guenther <rguenther@suse.de>
PR lto/41715
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 2b674c176ac..54fde65c69a 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1193,7 +1193,6 @@ lto_execute_ltrans (char *const *files)
typedef struct {
- struct pointer_set_t *free_list;
struct pointer_set_t *seen;
} lto_fixup_data_t;
@@ -1528,8 +1527,6 @@ lto_fixup_tree (tree *tp, int *walk_subtrees, void *data)
lto_mark_nothrow_fndecl (prevailing);
}
- pointer_set_insert (fixup_data->free_list, t);
-
/* Also replace t with prevailing defintion. We don't want to
insert the other defintion in the seen set as we want to
replace all instances of it. */
@@ -1638,20 +1635,6 @@ lto_fixup_state_aux (void **slot, void *aux)
return 1;
}
-/* A callback to pointer_set_traverse. Frees the tree pointed by p. Removes
- from it from the UID -> DECL mapping. */
-
-static bool
-free_decl (const void *p, void *data ATTRIBUTE_UNUSED)
-{
- const_tree ct = (const_tree) p;
- tree t = CONST_CAST_TREE (ct);
-
- lto_symtab_clear_resolution (t);
-
- return true;
-}
-
/* Fix the decls from all FILES. Replaces each decl with the corresponding
prevailing one. */
@@ -1660,11 +1643,9 @@ lto_fixup_decls (struct lto_file_decl_data **files)
{
unsigned int i;
tree decl;
- struct pointer_set_t *free_list = pointer_set_create ();
struct pointer_set_t *seen = pointer_set_create ();
lto_fixup_data_t data;
- data.free_list = free_list;
data.seen = seen;
for (i = 0; files[i]; i++)
{
@@ -1683,8 +1664,6 @@ lto_fixup_decls (struct lto_file_decl_data **files)
VEC_replace (tree, lto_global_var_decls, i, decl);
}
- pointer_set_traverse (free_list, free_decl, NULL);
- pointer_set_destroy (free_list);
pointer_set_destroy (seen);
}
@@ -1823,11 +1802,18 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
/* Read the callgraph. */
input_cgraph ();
+ /* Merge global decls. */
+ lto_symtab_merge_decls ();
+
+ /* Fixup all decls and types and free the type hash tables. */
+ lto_fixup_decls (all_file_decl_data);
+ free_gimple_type_tables ();
+
/* Read the IPA summary data. */
ipa_read_summaries ();
- /* Merge global decls. */
- lto_symtab_merge_decls ();
+ /* Finally merge the cgraph according to the decl merging decisions. */
+ lto_symtab_merge_cgraph_nodes ();
/* Mark cgraph nodes needed in the merged cgraph
This normally happens in whole-program pass, but for
@@ -1844,12 +1830,6 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
timevar_push (TV_IPA_LTO_DECL_IO);
- /* Fixup all decls and types. */
- lto_fixup_decls (all_file_decl_data);
-
- /* Free the type hash tables. */
- free_gimple_type_tables ();
-
/* FIXME lto. This loop needs to be changed to use the pass manager to
call the ipa passes directly. */
if (!errorcount)
diff --git a/gcc/opts.c b/gcc/opts.c
index c69a399768f..51a0cb95419 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -917,7 +917,6 @@ decode_options (unsigned int argc, const char **argv)
flag_ipa_cp_clone = opt3;
if (flag_ipa_cp_clone)
flag_ipa_cp = 1;
- flag_ira_loop_pressure = opt3;
/* Just -O1/-O0 optimizations. */
opt1_max = (optimize <= 1);
diff --git a/gcc/passes.c b/gcc/passes.c
index 2d11c1f6987..db368f057db 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1618,7 +1618,8 @@ ipa_write_summaries_1 (cgraph_node_set set)
struct lto_out_decl_state *state = lto_new_out_decl_state ();
lto_push_out_decl_state (state);
- ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
+ if (!flag_wpa)
+ ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
ipa_write_summaries_2 (all_lto_gen_passes, set, state);
gcc_assert (lto_get_out_decl_state () == state);
@@ -1712,7 +1713,8 @@ ipa_read_summaries_1 (struct opt_pass *pass)
void
ipa_read_summaries (void)
{
- ipa_read_summaries_1 (all_regular_ipa_passes);
+ if (!flag_ltrans)
+ ipa_read_summaries_1 (all_regular_ipa_passes);
ipa_read_summaries_1 (all_lto_gen_passes);
}
diff --git a/gcc/rtl.c b/gcc/rtl.c
index 53a4992f482..aefbbf347d9 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -164,6 +164,20 @@ rtvec_alloc (int n)
return rt;
}
+/* Create a bitwise copy of VEC. */
+
+rtvec
+shallow_copy_rtvec (rtvec vec)
+{
+ rtvec newvec;
+ int n;
+
+ n = GET_NUM_ELEM (vec);
+ newvec = rtvec_alloc (n);
+ memcpy (&newvec->elem[0], &vec->elem[0], sizeof (rtx) * n);
+ return newvec;
+}
+
/* Return the number of bytes occupied by rtx value X. */
unsigned int
diff --git a/gcc/rtl.h b/gcc/rtl.h
index ee464b7c7f3..0f7044e5e1a 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1568,6 +1568,7 @@ extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
#define rtx_alloc(c) rtx_alloc_stat (c MEM_STAT_INFO)
extern rtvec rtvec_alloc (int);
+extern rtvec shallow_copy_rtvec (rtvec);
extern bool shared_const_p (const_rtx);
extern rtx copy_rtx (rtx);
extern void dump_rtx_statistics (void);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index f0c4d11e942..926615ec86f 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -363,7 +363,10 @@ simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
enum machine_mode op_mode;
- rtx op0, op1, op2;
+ const char *fmt;
+ rtx op0, op1, op2, newx, op;
+ rtvec vec, newvec;
+ int i, j;
/* If X is OLD_RTX, return FN (X, DATA), with a null FN. Otherwise,
if this is an expression, try to build a new expression, substituting
@@ -420,7 +423,6 @@ simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
case RTX_EXTRA:
- /* The only case we try to handle is a SUBREG. */
if (code == SUBREG)
{
op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
@@ -459,7 +461,44 @@ simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
default:
break;
}
- return x;
+
+ newx = x;
+ fmt = GET_RTX_FORMAT (code);
+ for (i = 0; fmt[i]; i++)
+ switch (fmt[i])
+ {
+ case 'E':
+ vec = XVEC (x, i);
+ newvec = XVEC (newx, i);
+ for (j = 0; j < GET_NUM_ELEM (vec); j++)
+ {
+ op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
+ old_rtx, fn, data);
+ if (op != RTVEC_ELT (vec, j))
+ {
+ if (newvec == vec)
+ {
+ newvec = shallow_copy_rtvec (vec);
+ if (x == newx)
+ newx = shallow_copy_rtx (x);
+ XVEC (newx, i) = newvec;
+ }
+ RTVEC_ELT (newvec, j) = op;
+ }
+ }
+ break;
+
+ case 'e':
+ op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
+ if (op != XEXP (x, i))
+ {
+ if (x == newx)
+ newx = shallow_copy_rtx (x);
+ XEXP (newx, i) = op;
+ }
+ break;
+ }
+ return newx;
}
/* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e827cc9eec7..178af56dde0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,107 @@
+2009-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/pack4.ads: New test.
+
+2009-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/null_pointer_deref1.adb: New test.
+ * gnat.dg/null_pointer_deref2.adb: Likewise.
+
+2009-10-24 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/41772
+ * gfortran.dg/transfer_intrinsic_3.f90.
+
+2009-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt4.adb: New test.
+
+2009-10-23 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/40033
+ * gcc.dg/noncompile/pr40033-1.c: New test.
+
+2009-10-23 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40808
+ * g++.dg/abi/mangle34.C: New test
+
+2009-10-23 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/lambda/lambda-nested2.C: New.
+
+ Core issue 899
+ * g++.dg/cpp0x/explicit4.C: New.
+
+2009-10-23 Joseph Myers <joseph@codesourcery.com>
+
+ * g++.dg/abi/rtti3.C, g++.dg/abi/thunk4.C: Skip for *-*-mingw* and
+ *-*-cygwin.
+ * g++.dg/cpp0x/lambda/lambda-mangle.C: Disable weak symbols tests
+ for *-*-mingw* and *-*-cygwin.
+ * g++.dg/opt/vt1.C: Skip for *-*-mingw* and *-*_cygwin.
+ * g++.dg/template/spec35.C: Disable weak symbol test for
+ *-*-mingw* and *-*-cygwin.
+
+ PR testsuite/31342
+ * gcc.target/i386/pic-1.c: Skip for *-*-mingw* and *-*-cygwin.
+
+2009-10-23 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41800
+ * gfortran.dg/class_10.f03: New test.
+
+2009-10-22 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/41787
+ * gcc.target/powerpc/vsx-vrsave.c: New file.
+
+2009-10-23 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/41673
+ * gcc.dg/Wstrict-aliasing-bogus-vla-1.c: New test.
+
+2009-10-23 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/41778
+ * gcc.dg/tree-ssa/ssa-pre-26.c: New testcase.
+
+2009-10-22 Richard Guenther <rguenther@suse.de>
+
+ PR lto/41791
+ * g++.dg/lto/20091022-2_0.C: New testcase.
+
+2009-10-22 Richard Guenther <rguenther@suse.de>
+
+ PR lto/41730
+ * g++.dg/lto/20091022-1_0.C: New testcase.
+
+2009-10-22 Jan Hubicka <jh@suse.cz>
+
+ * gcc.c-torture/compile/pr40556.c: New testcase.
+
+2009-10-22 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41781
+ * gfortran.dg/goto_8.f90: New test case.
+
+2009-10-21 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR tree-optimization/41497
+ * gcc.dg/tree-ssa/pr41497.c: New.
+
+2009-10-21 Steve Ellcey <sje@cup.hp.com>
+
+ * g++.dg/tree-ssa/copyprop.C: Use include to define free().
+
+2009-10-21 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/tls/pie-1.c: New test.
+
+2009-10-21 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/abi/mangle33.C: New test.
+
2009-10-21 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/discr22.adb: New test.
@@ -154,6 +258,11 @@
PR c++/38798
* g++.dg/cpp0x/trailing5.C: New.
+ * g++.dg/cpp0x/auto6.C: Rename to trailing1.C.
+ * g++.dg/cpp0x/auto8.C: Rename to trailing2.C.
+ * g++.dg/cpp0x/auto12.C: Rename to trailing3.C.
+ * g++.dg/cpp0x/auto13.C: Rename to trailing4.C.
+
2009-10-16 Janus Weil <janus@gcc.gnu.org>
PR fortran/41719
diff --git a/gcc/testsuite/g++.dg/abi/mangle33.C b/gcc/testsuite/g++.dg/abi/mangle33.C
new file mode 100644
index 00000000000..f0a4e5012d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle33.C
@@ -0,0 +1,19 @@
+// Testcase for mangling very long names.
+
+#define N \
+abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
+
+namespace N {
+ int i;
+}
+
+#undef N
+#define N \
+abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
+
+namespace N {
+ int j;
+}
+
+// { dg-final { scan-assembler "_ZN4043abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm1iE" } }
+// { dg-final { scan-assembler "_ZN4041abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk1jE" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle34.C b/gcc/testsuite/g++.dg/abi/mangle34.C
new file mode 100644
index 00000000000..08c3bc0a19b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle34.C
@@ -0,0 +1,41 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/40808
+// { dg-do compile }
+// This tests the mangling of empty template argument list in a template
+// id.
+// { dg-final { scan-assembler "_ZNK5DummyclI3GenEENT_3SigIE10ResultTypeERKS2_" } }
+
+
+struct Void {};
+
+template <class R> struct FunType {
+ typedef R ResultType;
+};
+
+struct WrongNumberOfSigArgs {};
+
+template <typename R> struct CFunType {
+ template <class Dummy1=Void, class Dummy2=Void> struct Sig : public
+FunType<WrongNumberOfSigArgs> {};
+ template <class Dummy> struct Sig<Void,Dummy> : public FunType<R> {};
+};
+
+struct Dummy {
+ template <typename F> typename F::template Sig<>::ResultType operator()(F
+const& f) const {
+ return typename F::template Sig<>::ResultType(0);
+ }
+};
+
+struct Gen: public CFunType<int> {
+ int operator()() const {return 0;}
+ Gen() {}
+};
+
+int myfunction() {
+ return Dummy()(Gen());
+}
+
+int main() {
+ myfunction();
+}
diff --git a/gcc/testsuite/g++.dg/abi/rtti3.C b/gcc/testsuite/g++.dg/abi/rtti3.C
index ee562adac59..c03e4611c0b 100644
--- a/gcc/testsuite/g++.dg/abi/rtti3.C
+++ b/gcc/testsuite/g++.dg/abi/rtti3.C
@@ -2,6 +2,7 @@
// necessarily the type info object
// { dg-require-weak "" }
+// { dg-skip-if "Linkonce not weak" { *-*-mingw* *-*-cygwin } { "*" } { "" } }
// { dg-final { scan-assembler ".weak\[ \t\]_?_ZTSPP1A" { target { ! { *-*-darwin* } } } } }
// { dg-final { scan-assembler-not ".weak\[ \t\]_?_ZTIPP1A" { target { ! { *-*-darwin* } } } } }
// { dg-final { scan-assembler ".weak_definition\[ \t\]_?_ZTSPP1A" { target { *-*-darwin* } } } }
diff --git a/gcc/testsuite/g++.dg/abi/thunk4.C b/gcc/testsuite/g++.dg/abi/thunk4.C
index 79af6624d56..fa5fbd43277 100644
--- a/gcc/testsuite/g++.dg/abi/thunk4.C
+++ b/gcc/testsuite/g++.dg/abi/thunk4.C
@@ -1,4 +1,5 @@
// { dg-require-weak "" }
+// { dg-skip-if "Linkonce not weak" { *-*-mingw* *-*-cygwin } { "*" } { "" } }
// { dg-final { scan-assembler ".weak\[ \t\]_?_ZThn._N7Derived3FooEv" { target { ! { *-*-darwin* } } } } }
// { dg-final { scan-assembler ".weak_definition\[ \t\]_?_ZThn._N7Derived3FooEv" { target { *-*-darwin* } } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit4.C b/gcc/testsuite/g++.dg/cpp0x/explicit4.C
new file mode 100644
index 00000000000..74726a99cad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/explicit4.C
@@ -0,0 +1,17 @@
+// Negative explicit conv test.
+// { dg-options "-std=c++0x" }
+
+struct A {
+ A(const A&, int = 0); // { dg-message "candidates" }
+};
+struct B
+{
+ explicit operator A();
+};
+
+int main()
+{
+ B b;
+ (A(b)); // OK
+ (A(b,1)); // { dg-error "no match" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C
index dc89d2388fb..9f7d5f3b2a9 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C
@@ -10,7 +10,7 @@ inline void g(int n) {
// The call operator of that type is _ZZ1giENKUlvE_clEv.
// { dg-final { scan-assembler "_ZZ1giENKUlvE_clEv" } }
-// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZ1giENKUlvE_clEv" { target { ! { *-*-darwin* } } } } }
+// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZ1giENKUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
algo([=]{return n+bef();});
// The captured entities do not participate in <lambda-sig>
@@ -32,7 +32,7 @@ struct S {
// Type: ZN1S1fEiiEd0_UlvE_
// Operator: _ZZN1S1fEiiEd0_NKUlvE_clEv
// { dg-final { scan-assembler "_ZZN1S1fEiiEd0_NKUlvE_clEv" } }
-// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZN1S1fEiiEd0_NKUlvE_clEv" { target { ! { *-*-darwin* } } } } }
+// { dg-final { scan-assembler "weak\[ \t\]*_?_ZZN1S1fEiiEd0_NKUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
[]{return 1;}()
// Type: ZN1S1fEiiEd0_UlvE0_
// Operator: _ZZN1S1fEiiEd0_NKUlvE0_clEv
@@ -53,7 +53,7 @@ template int R<int>::x;
// Type of lambda in intializer of R<int>::x: N1RIiE1xMUlvE_E
// Corresponding operator(): _ZNK1RIiE1xMUlvE_clEv
// { dg-final { scan-assembler "_ZNK1RIiE1xMUlvE_clEv" } }
-// { dg-final { scan-assembler "weak\[ \t\]*_?_ZNK1RIiE1xMUlvE_clEv" } }
+// { dg-final { scan-assembler "weak\[ \t\]*_?_ZNK1RIiE1xMUlvE_clEv" { target { ! { *-*-mingw* *-*-cygwin } } } } }
void bar()
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C
new file mode 100644
index 00000000000..b7887485595
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C
@@ -0,0 +1,31 @@
+// Testcase from N2998
+// { dg-options -std=c++0x }
+
+void f1(int i) {
+ int const N = 20;
+ auto m1 = [=]{
+ int const M = 30;
+ auto m2 = [i]{
+ int x[N][M]; // OK: N and M are not "used"
+ x[0][0] = i; // OK: i is explicitly captured by m2
+ // and implicitly captured by m1
+ };
+ };
+ struct s1 {
+ int f;
+ int work(int n) {
+ int m = n*n;
+ int j = 40;
+ auto m3 = [this,m]{
+ /*auto m4=*/[&,j]{ // { dg-error "j. is not captured" }
+ int x = n; // { dg-error "n. is not captured" }
+ x += m; // OK: m implicitly captured by m4
+ // and explicitly captured by m3
+ x += i; // { dg-error "i. is not captured" }
+ x += f; // OK: this captured implicitly by m4
+ // and explicitly by m3
+ };
+ };
+ }
+ };
+}
diff --git a/gcc/testsuite/g++.dg/lto/20091022-1_0.C b/gcc/testsuite/g++.dg/lto/20091022-1_0.C
new file mode 100644
index 00000000000..cb3f20a4ed2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/20091022-1_0.C
@@ -0,0 +1,13 @@
+// { dg-lto-do link }
+// { dg-extra-ld-options "-fwhole-program" }
+
+template <int dim>
+struct AutoDerivativeFunction {
+ virtual void gradient_list (void);
+};
+template <int dim>
+void AutoDerivativeFunction<dim>::gradient_list (void)
+{
+}
+template class AutoDerivativeFunction<1>;
+int main() {}
diff --git a/gcc/testsuite/g++.dg/lto/20091022-2_0.C b/gcc/testsuite/g++.dg/lto/20091022-2_0.C
new file mode 100644
index 00000000000..29ed9b6b0a0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/20091022-2_0.C
@@ -0,0 +1,12 @@
+// { dg-lto-do link }
+// { dg-lto-options {{-O3 -flto -Winline}} }
+
+#include <string>
+
+int
+main()
+{
+ std::string i;
+ i = "abc";
+}
+
diff --git a/gcc/testsuite/g++.dg/opt/vt1.C b/gcc/testsuite/g++.dg/opt/vt1.C
index ea74f52126f..ba871fba2d8 100644
--- a/gcc/testsuite/g++.dg/opt/vt1.C
+++ b/gcc/testsuite/g++.dg/opt/vt1.C
@@ -2,6 +2,7 @@
// { dg-do compile { target fpic } }
// { dg-options "-O2 -fpic -fno-rtti" }
// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } }
+// { dg-skip-if "No Windows PIC" { *-*-mingw* *-*-cygwin } { "*" } { "" } }
// Origin: Jakub Jelinek <jakub@redhat.com>
struct S
diff --git a/gcc/testsuite/g++.dg/template/spec35.C b/gcc/testsuite/g++.dg/template/spec35.C
index cae33ed3d1f..709ece5dd90 100644
--- a/gcc/testsuite/g++.dg/template/spec35.C
+++ b/gcc/testsuite/g++.dg/template/spec35.C
@@ -24,6 +24,6 @@ void instantiator ()
// { dg-final { scan-assembler-not ".glob(a|)l\[\t \]*_?_Z2f1IiEvT_" } }
f1(0); // Expected to have static linkage
- // { dg-final { scan-assembler ".weak(_definition)?\[\t \]*_?_Z2f2IiEvT_" } }
+ // { dg-final { scan-assembler ".weak(_definition)?\[\t \]*_?_Z2f2IiEvT_" { target { ! { *-*-mingw* *-*-cygwin } } } } }
f2(0); // Expected to have weak global linkage
}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/copyprop.C b/gcc/testsuite/g++.dg/tree-ssa/copyprop.C
index e785755eb07..5ba193618dd 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/copyprop.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/copyprop.C
@@ -7,8 +7,8 @@
#include <map>
#include <vector>
#include <iostream>
+#include <cstdlib>
using namespace std;
-extern void free (void *);
template<typename _FIter, typename _Tp> _FIter lower_bound(_FIter, _FIter, _Tp&);
template<class _Key> struct hash { };
template<class _Val> struct _Hashtable_node {
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40556.c b/gcc/testsuite/gcc.c-torture/compile/pr40556.c
new file mode 100644
index 00000000000..625175d7788
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40556.c
@@ -0,0 +1,11 @@
+struct A {};
+
+struct A foo()
+{
+ return foo();
+}
+
+void bar()
+{
+ foo();
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-vla-1.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-vla-1.c
new file mode 100644
index 00000000000..e9f63d36872
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-vla-1.c
@@ -0,0 +1,10 @@
+/* PR 41673: bogus -Wstrict-aliasing warning from VLA dereference. */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -O2 -Wall" } */
+
+int main(int argc, char *argv[])
+{
+ float x[argc];
+ float y[argc];
+ return 0 == __builtin_memcpy(y, x, argc * sizeof(*x));
+}
diff --git a/gcc/testsuite/gcc.dg/autopar/outer-1.c b/gcc/testsuite/gcc.dg/autopar/outer-1.c
new file mode 100644
index 00000000000..913d390f684
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/outer-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */
+
+void abort (void);
+
+void parloop (int N)
+{
+ int i, j;
+ int x[10000][10000];
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ x[i][j] = i + j + 3;
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ if (x[i][j] != i + j + 3)
+ abort ();
+}
+
+int main(void)
+{
+ parloop(10000);
+
+ return 0;
+}
+
+
+/* Check that outer loop is parallelized. */
+/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/autopar/outer-2.c b/gcc/testsuite/gcc.dg/autopar/outer-2.c
new file mode 100644
index 00000000000..351b3499e89
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/outer-2.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */
+
+void abort (void);
+
+void parloop (int N)
+{
+ int i, j,ii;
+ int x[400][10][400];
+
+for (ii = 0; ii < N; ii++)
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ x[i][j][ii] = ii+i + j + 3;
+
+for (ii = 0; ii < N; ii++)
+ for (i = 0; i < N;i++)
+ for (j = 0; j < N; j++)
+ if (x[i][j][ii] != ii+i + j + 3)
+ abort ();
+}
+
+int main(void)
+{
+ parloop(400);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/autopar/outer-3.c b/gcc/testsuite/gcc.dg/autopar/outer-3.c
new file mode 100644
index 00000000000..2f1033f9830
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/outer-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */
+
+void abort (void);
+
+void parloop (int N)
+{
+ int i, j;
+ int x[500][500];
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < i; j++)
+ x[i][j] = i + j + 3;
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < i; j++)
+ if (x[i][j] != i + j + 3)
+ abort ();
+}
+
+int main(void)
+{
+ parloop(500);
+
+ return 0;
+}
+
+
+/* Check that outer loop is parallelized. */
+/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/autopar/outer-4.c b/gcc/testsuite/gcc.dg/autopar/outer-4.c
new file mode 100644
index 00000000000..56f6123385d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/outer-4.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */
+
+void abort (void);
+
+int g_sum=0;
+int x[500][500];
+
+__attribute__((noinline))
+void parloop (int N)
+{
+ int i, j;
+ int sum;
+
+ /* Double reduction is currently not supported, outer loop is not
+ parallelized. Inner reduction is detected, inner loop is
+ parallelized. */
+ sum = 0;
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ sum += x[i][j];
+
+ g_sum = sum;
+}
+
+int main(void)
+{
+ parloop(500);
+
+ return 0;
+}
+
+
+/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/autopar/outer-5.c b/gcc/testsuite/gcc.dg/autopar/outer-5.c
new file mode 100644
index 00000000000..3a542988c26
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/outer-5.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */
+
+void abort (void);
+
+int x[500][500];
+int y[500];
+int g_sum=0;
+
+__attribute__((noinline))
+void init (int i, int j)
+{
+ x[i][j]=1;
+}
+
+__attribute__((noinline))
+void parloop (int N)
+{
+ int i, j;
+ int sum;
+
+ /* Inner cycle is currently not supported, outer loop is not
+ parallelized. Inner reduction is detected, inner loop is
+ parallelized. */
+ for (i = 0; i < N; i++)
+ {
+ sum = 0;
+ for (j = 0; j < N; j++)
+ sum += x[i][j];
+ y[i]=sum;
+ }
+ g_sum = sum;
+}
+
+int main(void)
+{
+ int i,j;
+ for (i = 0; i < 500; i++)
+ for (j = 0; j < 500; j++)
+ init(i, j);
+
+ parloop(500);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/autopar/outer-6.c b/gcc/testsuite/gcc.dg/autopar/outer-6.c
new file mode 100644
index 00000000000..6e027d2f69a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/outer-6.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */
+
+void abort (void);
+
+int x[500][500];
+int y[500];
+int g_sum=0;
+
+__attribute__((noinline))
+void init (int i, int j)
+{
+ x[i][j]=1;
+}
+
+__attribute__((noinline))
+void parloop (int N)
+{
+ int i, j;
+ int sum;
+
+ /* Outer loop reduction, outerloop is parallelized. */
+ sum=0;
+ for (i = 0; i < N; i++)
+ {
+ for (j = 0; j < N; j++)
+ y[i]=x[i][j];
+ sum += y[i];
+ }
+ g_sum = sum;
+}
+
+int main(void)
+{
+ int i,j;
+ for (i = 0; i < 500; i++)
+ for (j = 0; j < 500; j++)
+ init(i, j);
+
+ parloop(500);
+
+ return 0;
+}
+
+
+/* Check that outer loop is parallelized. */
+/* { dg-final { scan-tree-dump-times "parallelizing outer loop" 1 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "parallelizing inner loop" 0 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/noncompile/pr40033-1.c b/gcc/testsuite/gcc.dg/noncompile/pr40033-1.c
new file mode 100644
index 00000000000..4f074420783
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/noncompile/pr40033-1.c
@@ -0,0 +1,7 @@
+/* ICE from error_mark_node being wrapped in a C_MAYBE_CONST_EXPR. PR
+ 40033. */
+
+void foo()
+{
+ ({ 0,; }); /* { dg-error "expected" } */
+}
diff --git a/gcc/testsuite/gcc.dg/tls/pie-1.c b/gcc/testsuite/gcc.dg/tls/pie-1.c
new file mode 100644
index 00000000000..07eb5f1ad25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pie-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-fpie" } */
+/* { dg-require-effective-target tls } */
+
+__thread int a; int b; int main() { return a = b; }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr41497.c b/gcc/testsuite/gcc.dg/tree-ssa/pr41497.c
new file mode 100644
index 00000000000..e66ee846491
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr41497.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-Os" } */
+
+extern void abort (void);
+
+unsigned int a;
+int b, c;
+
+void
+foo (void)
+{
+ b = 0;
+ do {
+ for (a = -13; a == 0; a = (unsigned short)a)
+ c = 1;
+ b++;
+ } while (b == 0);
+}
+
+int
+main ()
+{
+ foo ();
+ if (a != -13)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-26.c
new file mode 100644
index 00000000000..978b7abab3a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-26.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fdump-tree-pre-details" } */
+
+typedef union
+{
+ int* data;
+} SA;
+
+typedef struct
+{
+ int reserved;
+ char* array;
+}SB;
+
+typedef struct
+{
+ int status;
+}SC;
+
+void foo(SA* pResult, SB* method, SC* self)
+{
+ if (method->array[0] == 'L' && !self->status && pResult->data != 0)
+ pResult->data = pResult->data;
+}
+
+/* { dg-final { scan-tree-dump "Deleted redundant store" "pre" } } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pic-1.c b/gcc/testsuite/gcc.target/i386/pic-1.c
index bc11de90b41..bdf6267c7d8 100644
--- a/gcc/testsuite/gcc.target/i386/pic-1.c
+++ b/gcc/testsuite/gcc.target/i386/pic-1.c
@@ -2,6 +2,7 @@
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
/* { dg-require-effective-target fpic } */
+/* { dg-skip-if "No Windows PIC" { *-*-mingw* *-*-cygwin } { "*" } { "" } } */
/* { dg-options "-fPIC" } */
int foo ()
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vrsave.c b/gcc/testsuite/gcc.target/powerpc/vsx-vrsave.c
new file mode 100644
index 00000000000..83125f67fcc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsx-vrsave.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mcpu=power7" } */
+/* { dg-final { scan-assembler-times "mtvrsave" 2 } } */
+
+/* Check whether VRSAVE is set to non-zero if VSX vector operations were
+ used, but it should not be set if there are no vector operations. */
+
+void
+generates_vrsave (vector double *a, vector double *b, vector double *c)
+{
+ *a = *b + *c;
+}
+
+void
+no_vrsave (double *a, double *b, double *c)
+{
+ *a = *b + *c;
+}
diff --git a/gcc/testsuite/gfortran.dg/class_10.f03 b/gcc/testsuite/gfortran.dg/class_10.f03
new file mode 100644
index 00000000000..f238a597a65
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_10.f03
@@ -0,0 +1,32 @@
+! { dg-do compile }
+!
+! PR 41800: [OOP] ICE in fold_convert_loc, at fold-const.c:2789
+!
+! Contributed by Harald Anlauf <anlauf@gmx.de>
+
+module abstract_gradient
+
+ implicit none
+ private
+
+ type, public, abstract :: gradient_class
+ contains
+ procedure, nopass :: inner_product
+ end type
+
+contains
+
+ function inner_product ()
+ class(gradient_class), pointer :: inner_product
+ inner_product => NULL()
+ end function
+
+end module
+
+
+ use abstract_gradient
+ class(gradient_class), pointer :: g_initial, ip_save
+ ip_save => g_initial%inner_product() ! ICE
+end
+
+! { dg-final { cleanup-modules "abstract_gradient" } }
diff --git a/gcc/testsuite/gfortran.dg/goto_8.f90 b/gcc/testsuite/gfortran.dg/goto_8.f90
new file mode 100644
index 00000000000..a5f1f7f07b9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goto_8.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+!
+! PR 41781: [OOP] bogus undefined label error with SELECT TYPE.
+!
+! Contributed by Salvatore Filippone <sfilippone@uniroma2.it>
+! and Tobias Burnus >burnus@gcc.gnu.org>
+
+! 1st example: jumping out of SELECT TYPE (valid)
+type bar
+ integer :: i
+end type bar
+class(bar), pointer :: var
+select type(var)
+class default
+ goto 9999
+end select
+9999 continue
+
+! 2nd example: jumping out of BLOCK (valid)
+block
+ goto 88
+end block
+88 continue
+
+! 3rd example: jumping into BLOCK (invalid)
+goto 99 ! { dg-error "is not in the same block" }
+block
+ 99 continue ! { dg-error "is not in the same block" }
+end block
+
+end
diff --git a/gcc/testsuite/gfortran.dg/transfer_intrinsic_3.f90 b/gcc/testsuite/gfortran.dg/transfer_intrinsic_3.f90
new file mode 100644
index 00000000000..f0b9b546877
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transfer_intrinsic_3.f90
@@ -0,0 +1,38 @@
+! { dg-do run }
+! Tests the fix for PR41772 in which the empty array reference
+! 'qname(1:n-1)' was not handled correctly in TRANSFER.
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+!
+module m
+ implicit none
+contains
+ pure function str_vs(vs) result(s)
+ character, dimension(:), intent(in) :: vs
+ character(len=size(vs)) :: s
+ s = transfer(vs, s)
+ end function str_vs
+ subroutine has_key_ns(uri, localname, n)
+ character(len=*), intent(in) :: uri, localname
+ integer, intent(in) :: n
+ if ((n .lt. 2) .and. (len (uri) .ne. 0)) then
+ call abort
+ else IF ((n .ge. 2) .and. (len (uri) .ne. n - 1)) then
+ call abort
+ end if
+ end subroutine
+end module m
+
+ use m
+ implicit none
+ character, dimension(:), pointer :: QName
+ integer :: n
+ allocate(qname(6))
+ qname = (/ 'a','b','c','d','e','f' /)
+
+ do n = 0, 3
+ call has_key_ns(str_vs(qname(1:n-1)),"", n)
+ end do
+ deallocate(qname)
+end
+! { dg-final { cleanup-modules "m" } } \ No newline at end of file
diff --git a/gcc/testsuite/gnat.dg/null_pointer_deref1.adb b/gcc/testsuite/gnat.dg/null_pointer_deref1.adb
new file mode 100644
index 00000000000..817155dc1c9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/null_pointer_deref1.adb
@@ -0,0 +1,21 @@
+-- { dg-do run }
+-- { dg-options "-gnatp" }
+
+-- This test requires architecture- and OS-specific support code for unwinding
+-- through signal frames (typically located in *-unwind.h) to pass. Feel free
+-- to disable it if this code hasn't been implemented yet.
+
+procedure Null_Pointer_Deref1 is
+ type Int_Ptr is access all Integer;
+
+ function Ident return Int_Ptr is
+ begin
+ return null;
+ end;
+
+ Data : Int_Ptr := Ident;
+begin
+ Data.all := 1;
+exception
+ when Storage_Error => null;
+end;
diff --git a/gcc/testsuite/gnat.dg/null_pointer_deref2.adb b/gcc/testsuite/gnat.dg/null_pointer_deref2.adb
new file mode 100644
index 00000000000..b1dd548f01b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/null_pointer_deref2.adb
@@ -0,0 +1,28 @@
+-- { dg-do run }
+-- { dg-options "-gnatp" }
+
+-- This test requires architecture- and OS-specific support code for unwinding
+-- through signal frames (typically located in *-unwind.h) to pass. Feel free
+-- to disable it if this code hasn't been implemented yet.
+
+procedure Null_Pointer_Deref2 is
+
+ task T;
+
+ task body T is
+ type Int_Ptr is access all Integer;
+
+ function Ident return Int_Ptr is
+ begin
+ return null;
+ end;
+ Data : Int_Ptr := Ident;
+ begin
+ Data.all := 1;
+ exception
+ when Storage_Error => null;
+ end T;
+
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt4.adb b/gcc/testsuite/gnat.dg/opt4.adb
new file mode 100644
index 00000000000..caa5ab3a6cb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt4.adb
@@ -0,0 +1,22 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+procedure Opt4 is
+
+ type Rec (D : Natural) is record
+ S : String (1..D);
+ end record;
+
+ procedure Test (R : Rec) is
+ begin
+ if R.D /= 9 then
+ raise Program_Error;
+ end if;
+ end;
+
+ R : Rec(9);
+
+begin
+ R := (9, "123456789");
+ Test (R);
+end;
diff --git a/gcc/testsuite/gnat.dg/specs/pack4.ads b/gcc/testsuite/gnat.dg/specs/pack4.ads
new file mode 100644
index 00000000000..82b76d2f457
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/pack4.ads
@@ -0,0 +1,12 @@
+package Pack4 is
+
+ type Buffer is array (Natural range <>) of Boolean;
+
+ type Root (Size : Natural) is tagged record
+ Data : Buffer (1..Size);
+ end record;
+ pragma Pack (Root);
+
+ type Derived is new Root with null record;
+
+end Pack4;
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 1c820a3e3c5..4a34cefd2a4 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -4850,6 +4850,31 @@ gimple_duplicate_bb (basic_block bb)
return new_bb;
}
+/* Add phi arguments to the phi nodes in E_COPY->dest according to
+ the phi arguments coming from the equivalent edge at
+ the phi nodes of DEST. */
+
+static void
+add_phi_args_after_redirect (edge e_copy, edge orig_e)
+{
+ gimple_stmt_iterator psi, psi_copy;
+ gimple phi, phi_copy;
+ tree def;
+
+ for (psi = gsi_start_phis (orig_e->dest),
+ psi_copy = gsi_start_phis (e_copy->dest);
+ !gsi_end_p (psi);
+ gsi_next (&psi), gsi_next (&psi_copy))
+ {
+
+ phi = gsi_stmt (psi);
+ phi_copy = gsi_stmt (psi_copy);
+ def = PHI_ARG_DEF_FROM_EDGE (phi, orig_e);
+ add_phi_arg (phi_copy, def, e_copy,
+ gimple_phi_arg_location_from_edge (phi, orig_e));
+ }
+}
+
/* Adds phi node arguments for edge E_COPY after basic block duplication. */
static void
@@ -5131,9 +5156,14 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
int total_freq = 0, exit_freq = 0;
gcov_type total_count = 0, exit_count = 0;
edge exits[2], nexits[2], e;
- gimple_stmt_iterator gsi;
+ gimple_stmt_iterator gsi,gsi1;
gimple cond_stmt;
- edge sorig, snew;
+ edge sorig, snew, orig_e;
+ basic_block exit_bb;
+ edge_iterator ei;
+ VEC (edge, heap) *redirect_edges;
+ basic_block iters_bb, orig_src;
+ tree new_rhs;
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
exits[0] = exit;
@@ -5149,17 +5179,13 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
it will work, but the resulting code will not be correct. */
for (i = 0; i < n_region; i++)
{
- /* We do not handle subloops, i.e. all the blocks must belong to the
- same loop. */
- if (region[i]->loop_father != orig_loop)
- return false;
-
if (region[i] == orig_loop->latch)
return false;
}
initialize_original_copy_tables ();
set_loop_copy (orig_loop, loop);
+ duplicate_subloops (orig_loop, loop);
if (!region_copy)
{
@@ -5225,8 +5251,36 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
cond_stmt = last_stmt (exit->src);
gcc_assert (gimple_code (cond_stmt) == GIMPLE_COND);
cond_stmt = gimple_copy (cond_stmt);
+
+ /* If the block consisting of the exit condition has the latch as
+ successor, then the body of the loop is executed before
+ the exit condition is tested. In such case, moving the
+ condition to the entry, causes that the loop will iterate
+ one less iteration (which is the wanted outcome, since we
+ peel out the last iteration). If the body is executed after
+ the condition, moving the condition to the entry requires
+ decrementing one iteration. */
+ if (exits[1]->dest == orig_loop->latch)
+ new_rhs = gimple_cond_rhs (cond_stmt);
+ else
+ {
+ new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (gimple_cond_rhs (cond_stmt)),
+ gimple_cond_rhs (cond_stmt),
+ build_int_cst (TREE_TYPE (gimple_cond_rhs (cond_stmt)), 1));
+
+ if (TREE_CODE (gimple_cond_rhs (cond_stmt)) == SSA_NAME)
+ {
+ iters_bb = gimple_bb (SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)));
+ for (gsi1 = gsi_start_bb (iters_bb); !gsi_end_p (gsi1); gsi_next (&gsi1))
+ if (gsi_stmt (gsi1) == SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)))
+ break;
+
+ new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true,
+ NULL_TREE,false,GSI_CONTINUE_LINKING);
+ }
+ }
+ gimple_cond_set_rhs (cond_stmt, unshare_expr (new_rhs));
gimple_cond_set_lhs (cond_stmt, unshare_expr (gimple_cond_lhs (cond_stmt)));
- gimple_cond_set_rhs (cond_stmt, unshare_expr (gimple_cond_rhs (cond_stmt)));
gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
sorig = single_succ_edge (switch_bb);
@@ -5238,13 +5292,74 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
/* Add the PHI node arguments. */
add_phi_args_after_copy (region_copy, n_region, snew);
-
+
/* Get rid of now superfluous conditions and associated edges (and phi node
arguments). */
+ exit_bb = exit->dest;
+
e = redirect_edge_and_branch (exits[0], exits[1]->dest);
PENDING_STMT (e) = NULL;
- e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
- PENDING_STMT (e) = NULL;
+
+ /* If the block consisting of the exit condition has the latch as
+ successor, then the body of the loop is executed before
+ the exit condition is tested.
+
+ { body }
+ { cond } (exit[0]) -> { latch }
+ |
+ V (exit[1])
+
+ { exit_bb }
+
+
+ In such case, the equivalent copied edge nexits[1]
+ (for the peeled iteration) needs to be redirected to exit_bb.
+
+ Otherwise,
+
+ { cond } (exit[0]) -> { body }
+ |
+ V (exit[1])
+
+ { exit_bb }
+
+
+ exit[0] is pointing to the body of the loop,
+ and the equivalent nexits[0] needs to be redirected to
+ the copied body (of the peeled iteration). */
+
+ if (exits[1]->dest == orig_loop->latch)
+ e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
+ else
+ e = redirect_edge_and_branch (nexits[0], nexits[1]->dest);
+ PENDING_STMT (e) = NULL;
+
+ redirect_edges = VEC_alloc (edge, heap, 10);
+
+ for (i = 0; i < n_region; i++)
+ region_copy[i]->flags |= BB_DUPLICATED;
+
+ /* Iterate all incoming edges to latch. All those coming from
+ copied bbs will be redirected to exit_bb. */
+ FOR_EACH_EDGE (e, ei, orig_loop->latch->preds)
+ {
+ if (e->src->flags & BB_DUPLICATED)
+ VEC_safe_push (edge, heap, redirect_edges, e);
+ }
+
+ for (i = 0; i < n_region; i++)
+ region_copy[i]->flags &= ~BB_DUPLICATED;
+
+ for (i = 0; VEC_iterate (edge, redirect_edges, i, e); ++i)
+ {
+ e = redirect_edge_and_branch (e, exit_bb);
+ PENDING_STMT (e) = NULL;
+ orig_src = get_bb_original (e->src);
+ orig_e = find_edge (orig_src, orig_loop->latch);
+ add_phi_args_after_redirect (e, orig_e);
+ }
+
+ VEC_free (edge, heap, redirect_edges);
/* Anything that is outside of the region, but was dominated by something
inside needs to update dominance info. */
diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h
index f21aa74d795..545db38a730 100644
--- a/gcc/tree-chrec.h
+++ b/gcc/tree-chrec.h
@@ -115,6 +115,7 @@ no_evolution_in_loop_p (tree chrec, unsigned loop_num, bool *res)
|| chrec_contains_symbols_defined_in_loop (chrec, loop_num))
return false;
+ STRIP_NOPS (chrec);
scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num);
*res = !tree_is_chrec (scev);
return true;
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 681e04612e4..61e372a54c3 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -255,7 +255,13 @@ loop_parallel_p (struct loop *loop)
bool ret = false;
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "\nConsidering loop %d\n", loop->num);
+ {
+ fprintf (dump_file, "Considering loop %d\n", loop->num);
+ if (!loop->inner)
+ fprintf (dump_file, "loop is innermost\n");
+ else
+ fprintf (dump_file, "loop NOT innermost\n");
+ }
/* Check for problems with dependences. If the loop can be reversed,
the iterations are independent. */
@@ -1289,8 +1295,9 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
bool ok;
edge exit = single_dom_exit (loop), hpred;
tree control, control_name, res, t;
- gimple phi, nphi, cond_stmt, stmt;
+ gimple phi, nphi, cond_stmt, stmt, cond_nit;
gimple_stmt_iterator gsi;
+ tree nit_1;
split_block_after_labels (loop->header);
orig_header = single_succ (loop->header);
@@ -1308,7 +1315,6 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
res = PHI_RESULT (phi);
t = make_ssa_name (SSA_NAME_VAR (res), phi);
SET_PHI_RESULT (phi, t);
-
nphi = create_phi_node (res, orig_header);
SSA_NAME_DEF_STMT (res) = nphi;
add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
@@ -1320,10 +1326,11 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
control = t;
}
}
-
bbs = get_loop_body_in_dom_order (loop);
- for (n = 0; bbs[n] != exit->src; n++)
+
+ for (n = 0; bbs[n] != loop->latch; n++)
continue;
+ n--;
nbbs = XNEWVEC (basic_block, n);
ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
bbs + 1, n, nbbs);
@@ -1358,7 +1365,6 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
struct reduction_info *red;
tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
-
red = reduction_phi (reduction_list, SSA_NAME_DEF_STMT (val));
if (red)
{
@@ -1374,12 +1380,15 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
}
gcc_assert (control_name != NULL_TREE);
- /* Initialize the control variable to NIT. */
+ /* Initialize the control variable to number of iterations
+ according to the rhs of the exit condition. */
gsi = gsi_after_labels (ex_bb);
- nit = force_gimple_operand_gsi (&gsi,
- fold_convert (TREE_TYPE (control_name), nit),
+ cond_nit = last_stmt (exit->src);
+ nit_1 = gimple_cond_rhs (cond_nit);
+ nit_1 = force_gimple_operand_gsi (&gsi,
+ fold_convert (TREE_TYPE (control_name), nit_1),
false, NULL_TREE, false, GSI_SAME_STMT);
- stmt = gimple_build_assign (control_name, nit);
+ stmt = gimple_build_assign (control_name, nit_1);
gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
SSA_NAME_DEF_STMT (control_name) = stmt;
}
@@ -1740,7 +1749,7 @@ gather_scalar_reductions (loop_p loop, htab_t reduction_list)
&& simple_loop_info)
{
gimple reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi, true, &double_reduc);
- if (reduc_stmt)
+ if (reduc_stmt && !double_reduc)
build_new_reduction (reduction_list, reduc_stmt, phi);
}
}
@@ -1890,15 +1899,32 @@ parallelize_loops (void)
FOR_EACH_LOOP (li, loop, 0)
{
htab_empty (reduction_list);
-
- /* If we use autopar in graphite pass, we use it's marked dependency
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Trying loop %d as candidate\n",loop->num);
+ if (loop->inner)
+ fprintf (dump_file, "loop %d is not innermost\n",loop->num);
+ else
+ fprintf (dump_file, "loop %d is innermost\n",loop->num);
+ }
+
+ /* If we use autopar in graphite pass, we use its marked dependency
checking results. */
if (flag_loop_parallelize_all && !loop->can_be_parallel)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "loop is not parallel according to graphite\n");
continue;
+ }
- /* FIXME: Only consider innermost loops with just one exit. */
- if (loop->inner || !single_dom_exit (loop))
+ if (!single_dom_exit (loop))
+ {
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "loop is !single_dom_exit\n");
+
continue;
+ }
if (/* And of course, the loop must be parallelizable. */
!can_duplicate_loop_p (loop)
@@ -1915,7 +1941,7 @@ parallelize_loops (void)
/* Do not bother with loops in cold areas. */
|| optimize_loop_nest_for_size_p (loop)))
continue;
-
+
if (!try_get_loop_niter (loop, &niter_desc))
continue;
@@ -1926,6 +1952,14 @@ parallelize_loops (void)
continue;
changed = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "parallelizing ");
+ if (loop->inner)
+ fprintf (dump_file, "outer loop\n");
+ else
+ fprintf (dump_file, "inner loop\n");
+ }
gen_parallel_loop (loop, reduction_list,
n_threads, &niter_desc);
verify_flow_info ();
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 02a4eed646e..70af0fda610 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1492,18 +1492,29 @@ analyze_evolution_in_loop (gimple loop_phi_node,
bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
if (!flow_bb_inside_loop_p (loop, bb))
continue;
-
+
if (TREE_CODE (arg) == SSA_NAME)
{
+ bool val = false;
+
ssa_chain = SSA_NAME_DEF_STMT (arg);
/* Pass in the initial condition to the follow edge function. */
ev_fn = init_cond;
res = follow_ssa_edge (loop, ssa_chain, loop_phi_node, &ev_fn, 0);
+
+ /* If ev_fn has no evolution in the inner loop, and the
+ init_cond is not equal to ev_fn, then we have an
+ ambiguity between two possible values, as we cannot know
+ the number of iterations at this point. */
+ if (TREE_CODE (ev_fn) != POLYNOMIAL_CHREC
+ && no_evolution_in_loop_p (ev_fn, loop->num, &val) && val
+ && !operand_equal_p (init_cond, ev_fn, 0))
+ ev_fn = chrec_dont_know;
}
else
res = t_false;
-
+
/* When it is impossible to go back on the same
loop_phi_node by following the ssa edges, the
evolution is represented by a peeled chrec, i.e. the
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index e619190386c..ba5cbbc9488 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -553,10 +553,10 @@ same_type_for_tbaa (tree type1, tree type2)
on an indirect reference may alias. */
static bool
-nonaliasing_component_refs_p (tree ref1, tree type1,
- HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1,
- tree ref2, tree type2,
- HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2)
+aliasing_component_refs_p (tree ref1, tree type1,
+ HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1,
+ tree ref2, tree type2,
+ HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2)
{
/* If one reference is a component references through pointers try to find a
common base and apply offset based disambiguation. This handles
@@ -600,9 +600,19 @@ nonaliasing_component_refs_p (tree ref1, tree type1,
offset1 -= offadj;
return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
}
- /* If we have two type access paths B1.path1 and B2.path2 they may
- only alias if either B1 is in B2.path2 or B2 is in B1.path1. */
- return false;
+
+ /* We haven't found any common base to apply offset-based disambiguation.
+ There are two cases:
+ 1. The base access types have the same alias set. This can happen
+ in Ada when a function with an unconstrained parameter passed by
+ reference is called on a constrained object and inlined: the types
+ have the same alias set but aren't equivalent. The references may
+ alias in this case.
+ 2. The base access types don't have the same alias set, i.e. one set
+ is a subset of the other. We have proved that B1 is not in the
+ access path B2.path and that B2 is not in the access path B1.path
+ so the references may not alias. */
+ return get_alias_set (type1) == get_alias_set (type2);
}
/* Return true if two memory references based on the variables BASE1
@@ -681,10 +691,10 @@ indirect_ref_may_alias_decl_p (tree ref1, tree ptr1,
if (ref1 && ref2
&& handled_component_p (ref1)
&& handled_component_p (ref2))
- return nonaliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)),
- offset1, max_size1,
- ref2, TREE_TYPE (base2),
- offset2, max_size2);
+ return aliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)),
+ offset1, max_size1,
+ ref2, TREE_TYPE (base2),
+ offset2, max_size2);
return true;
}
@@ -742,10 +752,10 @@ indirect_refs_may_alias_p (tree ref1, tree ptr1,
if (ref1 && ref2
&& handled_component_p (ref1)
&& handled_component_p (ref2))
- return nonaliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)),
- offset1, max_size1,
- ref2, TREE_TYPE (TREE_TYPE (ptr2)),
- offset2, max_size2);
+ return aliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)),
+ offset1, max_size1,
+ ref2, TREE_TYPE (TREE_TYPE (ptr2)),
+ offset2, max_size2);
return true;
}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 5da6c63b400..6ae05b5a866 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3405,6 +3405,7 @@ do_regular_insertion (basic_block block, basic_block dom)
pre_expr eprime = NULL;
edge_iterator ei;
pre_expr edoubleprime = NULL;
+ bool do_insertion = false;
val = get_expr_value_id (expr);
if (bitmap_set_contains_value (PHI_GEN (block), val))
@@ -3456,6 +3457,10 @@ do_regular_insertion (basic_block block, basic_block dom)
{
avail[bprime->index] = edoubleprime;
by_some = true;
+ /* We want to perform insertions to remove a redundancy on
+ a path in the CFG we want to optimize for speed. */
+ if (optimize_edge_for_speed_p (pred))
+ do_insertion = true;
if (first_s == NULL)
first_s = edoubleprime;
else if (!pre_expr_eq (first_s, edoubleprime))
@@ -3466,7 +3471,8 @@ do_regular_insertion (basic_block block, basic_block dom)
already existing along every predecessor, and
it's defined by some predecessor, it is
partially redundant. */
- if (!cant_insert && !all_same && by_some && dbg_cnt (treepre_insert))
+ if (!cant_insert && !all_same && by_some && do_insertion
+ && dbg_cnt (treepre_insert))
{
if (insert_into_preds_of_block (block, get_expression_id (expr),
avail))
@@ -4526,11 +4532,11 @@ fini_pre (bool do_fre)
only wants to do full redundancy elimination. */
static unsigned int
-execute_pre (bool do_fre ATTRIBUTE_UNUSED)
+execute_pre (bool do_fre)
{
unsigned int todo = 0;
- do_partial_partial = optimize > 2;
+ do_partial_partial = optimize > 2 && optimize_function_for_speed_p (cfun);
/* This has to happen before SCCVN runs because
loop_optimizer_init may create new phis, etc. */
@@ -4615,8 +4621,7 @@ do_pre (void)
static bool
gate_pre (void)
{
- /* PRE tends to generate bigger code. */
- return flag_tree_pre != 0 && optimize_function_for_speed_p (cfun);
+ return flag_tree_pre != 0;
}
struct gimple_opt_pass pass_pre =