summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-03-02 19:28:05 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-03-02 19:28:05 +0000
commit9d63dbe6b454a33381a73e1ca93aff85b0594f05 (patch)
treef8a1cb507af3e7ceb424d8056fc0f50558e9cd28 /gcc
parentf98abc094eceacf320655d4f16c9f71243455544 (diff)
downloadgcc-9d63dbe6b454a33381a73e1ca93aff85b0594f05.tar.gz
2008-03-02 Basile Starynkevitch <basile@starynkevitch.net>
merged with trunk 132817 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@132818 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog610
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in23
-rw-r--r--gcc/ada/ChangeLog18
-rw-r--r--gcc/ada/misc.c2
-rw-r--r--gcc/ada/s-fileio.adb16
-rw-r--r--gcc/ada/sem_ch13.adb6
-rw-r--r--gcc/ada/trans.c19
-rw-r--r--gcc/attribs.c6
-rw-r--r--gcc/basic-block.h180
-rw-r--r--gcc/bb-reorder.c50
-rw-r--r--gcc/builtins.c1
-rw-r--r--gcc/builtins.def1
-rw-r--r--gcc/c-common.c28
-rw-r--r--gcc/c-common.h6
-rw-r--r--gcc/c-decl.c14
-rw-r--r--gcc/c-errors.c4
-rw-r--r--gcc/c-lex.c49
-rw-r--r--gcc/c-opts.c21
-rw-r--r--gcc/c-parser.c2
-rw-r--r--gcc/c-pch.c11
-rw-r--r--gcc/c-ppoutput.c23
-rw-r--r--gcc/c-pragma.c108
-rw-r--r--gcc/c-pragma.h4
-rw-r--r--gcc/c.opt4
-rw-r--r--gcc/cfgcleanup.c132
-rw-r--r--gcc/cfgexpand.c14
-rw-r--r--gcc/cfglayout.c19
-rw-r--r--gcc/cfgrtl.c11
-rw-r--r--gcc/common.opt13
-rw-r--r--gcc/config.in6
-rw-r--r--gcc/config/arm/arm.c17
-rw-r--r--gcc/config/arm/arm.h35
-rw-r--r--gcc/config/arm/arm.md78
-rw-r--r--gcc/config/arm/constraints.md9
-rw-r--r--gcc/config/arm/ieee754-df.S4
-rw-r--r--gcc/config/arm/iwmmxt.md27
-rw-r--r--gcc/config/arm/thumb2.md11
-rw-r--r--gcc/config/arm/vfp.md56
-rw-r--r--gcc/config/darwin.c17
-rw-r--r--gcc/config/darwin.h5
-rw-r--r--gcc/config/mips/iris.h3
-rw-r--r--gcc/config/mips/mips.h1
-rw-r--r--gcc/config/mips/openbsd.h3
-rw-r--r--gcc/config/mips/sde.h3
-rw-r--r--gcc/config/mips/vxworks.h3
-rw-r--r--gcc/config/rs6000/rs6000.c42
-rw-r--r--gcc/config/sh/sh.c18
-rw-r--r--gcc/config/sh/sh.h6
-rw-r--r--gcc/configure.ac9
-rw-r--r--gcc/cp/ChangeLog98
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/call.c15
-rw-r--r--gcc/cp/class.c26
-rw-r--r--gcc/cp/cvt.c14
-rw-r--r--gcc/cp/decl.c30
-rw-r--r--gcc/cp/decl2.c21
-rw-r--r--gcc/cp/error.c4
-rw-r--r--gcc/cp/lex.c33
-rw-r--r--gcc/cp/parser.c149
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/cp/rtti.c37
-rw-r--r--gcc/dbgcnt.def19
-rw-r--r--gcc/dce.c6
-rw-r--r--gcc/df-scan.c50
-rw-r--r--gcc/df.h4
-rw-r--r--gcc/diagnostic.c60
-rw-r--r--gcc/diagnostic.h18
-rw-r--r--gcc/doc/invoke.texi26
-rw-r--r--gcc/dse.c22
-rw-r--r--gcc/emit-rtl.c11
-rw-r--r--gcc/expr.c10
-rw-r--r--gcc/final.c7
-rw-r--r--gcc/flags.h4
-rw-r--r--gcc/fold-const.c26
-rw-r--r--gcc/fortran/ChangeLog85
-rw-r--r--gcc/fortran/data.c5
-rw-r--r--gcc/fortran/decl.c2
-rw-r--r--gcc/fortran/error.c4
-rw-r--r--gcc/fortran/expr.c27
-rw-r--r--gcc/fortran/f95-lang.c59
-rw-r--r--gcc/fortran/gfortran.h8
-rw-r--r--gcc/fortran/interface.c30
-rw-r--r--gcc/fortran/iresolve.c101
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/fortran/options.c4
-rw-r--r--gcc/fortran/resolve.c11
-rw-r--r--gcc/fortran/scanner.c19
-rw-r--r--gcc/fortran/trans-decl.c72
-rw-r--r--gcc/fortran/trans-expr.c5
-rw-r--r--gcc/fortran/trans-intrinsic.c395
-rw-r--r--gcc/fortran/trans-io.c4
-rw-r--r--gcc/fortran/trans.c13
-rw-r--r--gcc/fortran/trans.h4
-rw-r--r--gcc/gcse.c33
-rw-r--r--gcc/gengtype.c48
-rw-r--r--gcc/gimple-low.c6
-rw-r--r--gcc/graphds.h1
-rw-r--r--gcc/gthr-dce.h10
-rw-r--r--gcc/gthr-mipssde.h6
-rw-r--r--gcc/gthr-nks.h6
-rw-r--r--gcc/gthr-posix.h13
-rw-r--r--gcc/gthr-posix95.h13
-rw-r--r--gcc/gthr-rtems.h6
-rw-r--r--gcc/gthr-single.h6
-rw-r--r--gcc/gthr-solaris.h9
-rw-r--r--gcc/gthr-tpf.h10
-rw-r--r--gcc/gthr-vxworks.h6
-rw-r--r--gcc/gthr-win32.h5
-rw-r--r--gcc/gthr.h2
-rw-r--r--gcc/haifa-sched.c6
-rw-r--r--gcc/ifcvt.c19
-rw-r--r--gcc/input.h71
-rw-r--r--gcc/java/ChangeLog19
-rw-r--r--gcc/java/class.c6
-rw-r--r--gcc/java/decl.c7
-rw-r--r--gcc/java/expr.c11
-rw-r--r--gcc/java/java-tree.h4
-rw-r--r--gcc/java/jcf-parse.c46
-rw-r--r--gcc/java/lang.c4
-rw-r--r--gcc/lambda.h17
-rw-r--r--gcc/langhooks.c4
-rw-r--r--gcc/libgcc2.c24
-rw-r--r--gcc/objc/ChangeLog4
-rw-r--r--gcc/objc/objc-act.c9
-rw-r--r--gcc/optc-gen.awk2
-rw-r--r--gcc/opth-gen.awk2
-rw-r--r--gcc/opts.c5
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/print-tree.c13
-rw-r--r--gcc/profile.c15
-rw-r--r--gcc/recog.c11
-rw-r--r--gcc/rtl-error.c9
-rw-r--r--gcc/rtl.def26
-rw-r--r--gcc/rtl.h19
-rw-r--r--gcc/rtlanal.c7
-rw-r--r--gcc/simplify-rtx.c25
-rw-r--r--gcc/stor-layout.c4
-rw-r--r--gcc/struct-equiv.c1339
-rw-r--r--gcc/system.h5
-rw-r--r--gcc/testsuite/ChangeLog197
-rw-r--r--gcc/testsuite/g++.dg/cpp/pedantic-errors.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp/string-2.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto1.C8
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib32.C22
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/typeinfo2.C23
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/typeinfo3.C24
-rw-r--r--gcc/testsuite/g++.dg/warn/pragma-system_header2.C4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr34971.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr35390.c13
-rw-r--r--gcc/testsuite/gcc.dg/20021023-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wlarger-than2.c7
-rw-r--r--gcc/testsuite/gcc.dg/bf-ms-attrib.c1
-rw-r--r--gcc/testsuite/gcc.dg/empty-source-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/empty-source-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/preprocess-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/pack-test-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr17301-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr17301-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr34351.c4
-rw-r--r--gcc/testsuite/gcc.dg/pragma-ep-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pragma-re-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr34999.c45
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-1.c38
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-10.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-11.c33
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-12.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-1a.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-2.c31
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-3.c34
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-5.c33
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-6.c38
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-7.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-8.c34
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-9.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c6
-rw-r--r--gcc/testsuite/gcc.dg/va-arg-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/mmx-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/mmx-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/mmx-4.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-13.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-14.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-6.c4
-rw-r--r--gcc/testsuite/gfortran.dg/arrayio_11.f909
-rw-r--r--gcc/testsuite/gfortran.dg/arrayio_12.f909
-rw-r--r--gcc/testsuite/gfortran.dg/assignment_2.f9049
-rw-r--r--gcc/testsuite/gfortran.dg/f2c_9.f9052
-rw-r--r--gcc/testsuite/gfortran.dg/ldist-1.f9033
-rw-r--r--gcc/testsuite/gfortran.dg/module_read_1.f905
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_1.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/pr32242.f907
-rw-r--r--gcc/testsuite/gfortran.dg/result_in_spec_3.f904
-rw-r--r--gcc/testsuite/gfortran.dg/use_12.f903
-rw-r--r--gcc/testsuite/gfortran.dg/warn_function_without_result.f9057
-rw-r--r--gcc/testsuite/gnat.dg/specs/pr34799.ads19
-rw-r--r--gcc/testsuite/gnat.dg/test_direct_io.adb15
-rw-r--r--gcc/timevar.def1
-rw-r--r--gcc/toplev.c101
-rw-r--r--gcc/toplev.h1
-rw-r--r--gcc/tree-cfg.c83
-rw-r--r--gcc/tree-data-ref.c538
-rw-r--r--gcc/tree-data-ref.h108
-rw-r--r--gcc/tree-dump.c4
-rw-r--r--gcc/tree-flow-inline.h2
-rw-r--r--gcc/tree-flow.h3
-rw-r--r--gcc/tree-inline.c3
-rw-r--r--gcc/tree-loop-distribution.c1173
-rw-r--r--gcc/tree-loop-linear.c33
-rw-r--r--gcc/tree-mudflap.c6
-rw-r--r--gcc/tree-optimize.c4
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-pretty-print.c14
-rw-r--r--gcc/tree-sra.c12
-rw-r--r--gcc/tree-ssa-pre.c4
-rw-r--r--gcc/tree-ssa-sccvn.c56
-rw-r--r--gcc/tree-stdarg.c1
-rw-r--r--gcc/tree-vect-analyze.c21
-rw-r--r--gcc/tree-vect-transform.c6
-rw-r--r--gcc/tree-vectorizer.c23
-rw-r--r--gcc/tree-vectorizer.h21
-rw-r--r--gcc/tree.c118
-rw-r--r--gcc/tree.h19
-rw-r--r--gcc/treelang/ChangeLog7
-rw-r--r--gcc/treelang/lex.l10
-rw-r--r--gcc/treelang/tree1.c14
226 files changed, 5303 insertions, 3411 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b917101614d..1cbee22c9b1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,374 @@
+2008-03-02 Basile Starynkevitch <basile@starynkevitch.net>
+ merged with trunk 132817
+
+2008-03-02 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 24924
+ * c-common.c (flag_permissive): Delete.
+ (constant_expression_warnings): Check flags first.
+ (constant_expression_error): New.
+ * c-common.h (flag_permissive): Delete.
+ (constant_expression_error): Declare.
+ * flags.h (flag_permissive): Declare. Update description.
+ * diagnostic.c (pedwarn): Update.
+ (permerror): New.
+ * diagnostic.h: (pedantic_error_kind): Rename as pedantic_warning_kind.
+ (permissive_error_kind): New.
+ * toplev.c (flag_permissive): Define. Update description.
+ * toplev.h (permissive_error_kind): Declare.
+ * c-errors.c (pedwarn_c99): Use pedantic_warning_kind.
+ (pedwarn_c90): Use pedantic_warning_kind.
+ * c-opts.c (c_common_post_options): flag_permissive does not affect
+ flag_pedantic_errors.
+
+2008-03-02 Joseph Myers <joseph@codesourcery.com>
+
+ * libgcc2.c (__addvSI3, __addvsi3, __addvDI3, __subvSI3,
+ __subvsi3, __subvDI3, __negvSI2, __negvsi2, __negvDI2, __absvSI2,
+ __absvsi2, __absvDI2): Use unsigned arithmetic.
+
+2008-03-02 Andi Kleen <ak@suse.de>
+ Richard Guenther <rguenther@suse.de>
+
+ * struct-equiv.c: Remove file.
+ * cfg_cleanup.c (condjump_equiv_p): Remove.
+ * Makefile.in (OBJS-common): Remove struct-equiv.o.
+ (struct-equiv.o): Remove rule.
+ * basic-block.h (struct_equiv_checkpoint, STRUCT_EQUIV_*,
+ insns_match_p, struct_equiv_block_eq, struct_equiv_init,
+ rtx_equiv_p, condjump_equiv_p): Remove prototypes.
+
+2008-03-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * ifcvt.c (noce_process_if_block): Try to handle only the then
+ block if the else block exists but isn't suitable.
+
+2008-03-01 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR gcc/35063
+ * gthr-posix.h (__gthread_mutex_destroy): Remove extra declarations.
+ * gthr-posix95.h (__gthread_mutex_destroy): Likewise. Note this fixes
+ regression from previous patch.
+
+2008-03-01 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR gcc/35063
+ * gthr.h: Add __gthread_mutex_destroy as a function that must be
+ implemented.
+ * gthr-vxworks.h (__gthread_mutex_destroy): Null implementation.
+ * gthr-single.h (__gthread_mutex_destroy): Likewise.
+ * gthr-rtems.h (__gthread_mutex_destroy): Likewise.
+ * gthr-mipssde.h (__gthread_mutex_destroy): Likewise.
+ * gthr-nks.h (__gthread_mutex_destroy): Likewise.
+ * gthr-solaris.h (__gthread_mutex_destroy): Call mutex_destroy.
+ * gthr-win32.h (__GTHREAD_MUTEX_DESTROY_FUNCTION): Remove.
+ (__gthread_mutex_destroy_function): Rename to
+ __gthread_mutex_destroy.
+ * gthr-dce.h (__gthread_mutex_destroy): Call
+ pthread_mutex_destroy.
+ * gthr-tpf.h (__gthread_mutex_destroy): Likewise.
+ * gthr-posix.h (__gthread_mutex_destroy): Likewise.
+ * gthr-posix95.h (__gthread_mutex_destroy): Likewise.
+
+2008-03-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * df-scan.c (df_ref_chain_change_bb): Simplify.
+ (df_insn_change_bb): Add new_bb argument. Simplify. Call
+ set_block_for_insn if there's any change.
+ * df.h ((df_insn_change_bb): Fix prototype.
+ * cfgrtl.c (update_bb_for_insn_chain): Pass bb to
+ df_insn_change_bb, don't call set_block_for_insn.
+ * emit-rtl.c (reorder_insns): Likewise.
+ * haifa-sched.c (move_insn): Likewise.
+
+2008-03-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * rtlanal.c (loc_mentioned_in_p): Test XVECEXPs correctly.
+
+2008-03-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * tree-flow-inline.h (next_readonly_imm_use): Return
+ NULL_USE_OPERAND_P after the end.
+
+2008-03-01 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/35411
+ * tree-sra.c (sra_build_assignment): Split conversion to
+ final type to a separate statement if we are not assigning
+ to a register.
+
+2008-02-29 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ * fold-const.c (fold_convertible_p): Correct the logic to follow
+ that in fold_convert().
+
+2008-02-29 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/35315
+ * tree-inline.c (build_duplicate_type): When we make a
+ duplicate type, make it unique in the canonical types system.
+
+2008-02-29 Tom Tromey <tromey@redhat.com>
+
+ * toplev.c (input_file_stack, input_file_stack_tick, fs_p,
+ input_file_stack_history, input_file_stack_restored): Remove.
+ (push_srcloc, pop_srcloc, restore_input_file_stack): Likewise.
+ * input.h (struct file_stack): Remove.
+ (push_srcloc, pop_srcloc, restore_input_file_stack): Likewise.
+ (input_file_stack, input_file_stack_tick, INPUT_FILE_STACK_BITS):
+ Likewise.
+ * diagnostic.h (struct diagnostic_context) <last_module>: Change
+ type.
+ (diagnostic_last_module_changed): Add 'map' argument.
+ (diagnostic_set_last_function): Likewise.
+ * diagnostic.c (undiagnostic_report_current_module): Iterate using
+ line map, not input_file_stack.
+ * c-lex.c (fe_file_change): Don't use push_srcloc or pop_srcloc.
+
+2008-02-29 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.md (arm_addsi3): Add r/k/n alternative.
+
+2008-02-29 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/ieee754-df.S (muldf3): Use RET macros.
+
+2008-02-29 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-pre.c (get_sccvn_value): Create missing VNs via
+ vn_lookup_or_add.
+ * tree-ssa-sccnv.c (visit_reference_op_store): Use the rhs
+ value for comparing for a store match.
+ (simplify_unary_expression): Do nothing for SSA_NAMEs.
+ (try_to_simplify): Do not do a full-blown reference lookup.
+
+2008-02-29 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (sh_scalar_mode_supported_p): New function.
+ (TARGET_SCALAR_MODE_SUPPORTED_P): Define.
+
+ * config/sh/sh.h (OVERRIDE_OPTIONS): Don't warn for profiling.
+
+2008-02-29 Sebastian Pop <sebastian.pop@amd.com>
+
+ * tree-loop-linear.c (try_interchange_loops): Compare memory access
+ strides against cache sizes.
+
+2008-02-29 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (sh_secondary_reload): Handle loading a float
+ constant to fpul.
+
+2008-02-28 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * simplify-rtx.c (simplify_unary_operation_1): Extend the handling
+ of SUBREG_PROMOTED_VAR_P to cope with cases where the extended value
+ is smaller than the original promoted value.
+ (simplify_subreg): If OP is a SUBREG, try to preserve its
+ SUBREG_PROMOTED_VAR_P information.
+
+2008-02-28 Steven Bosscher <stevenb.gcc@gmail.com>
+
+ * tree-ssa-sccvn (vn_ssa_aux_obstack): New obstack.
+ (VN_INFO_GET): Allocate new objects on the obstack.
+ (init_scc_vn): Initialize the obstack. Use XDELETE instead of free
+ for rpo_numbers_temp, for consistency.
+ (free_scc_vn): Free the obstack.
+
+2008-02-28 Sebastian Pop <sebastian.pop@amd.com>
+
+ * doc/invoke.texi: Document -ftree-loop-distribution.
+ * tree-loop-distribution.c: New.
+ * tree-pass.h (pass_loop_distribution): New.
+ * graphds.h (struct graph): Add htab_t indices.
+ * timevar.def (TV_TREE_LOOP_DISTRIBUTION): New.
+ * tree-vectorizer.c (rename_variables_in_loop): Extern.
+ (slpeel_tree_duplicate_loop_to_edge_cfg): Init PENDING_STMT to NULL.
+ * tree-vectorizer.h (tree_duplicate_loop_on_edge): Declared.
+ * tree-data-ref.c (debug_data_dependence_relations): New.
+ (dump_data_dependence_relation): Also print data references.
+ (free_data_ref): Extern.
+ (same_access_functions): Moved...
+ (find_vertex_for_stmt): Renamed rdg_vertex_for_stmt.
+ (dump_rdg_vertex, debug_rdg_vertex, dump_rdg_component,
+ debug_rdg_component, dump_rdg, debug_rdg, dot_rdg_1, dot_rdg,
+ struct rdg_vertex_info, rdg_vertex_for_stmt): New.
+ (create_rdg_edge_for_ddr, create_rdg_vertices): Cleaned up.
+ (stmts_from_loop): Skip LABEL_EXPR.
+ (hash_stmt_vertex_info, eq_stmt_vertex_info, hash_stmt_vertex_del): New.
+ (build_rdg): Initialize rdg->indices htab.
+ (free_rdg, stores_from_loop, ref_base_address,
+ rdg_defs_used_in_other_loops_p, have_similar_memory_accesses,
+ have_similar_memory_accesses_1, ref_base_address_1,
+ remove_similar_memory_refs): New.
+ * tree-data-ref.h: Depend on tree-chrec.h.
+ (debug_data_dependence_relations, free_data_ref): Declared.
+ (same_access_functions): ... here.
+ (ddr_is_anti_dependent, ddrs_have_anti_deps, ddr_dependence_level): New.
+ (struct rdg_vertex): Add has_mem_write and has_mem_reads.
+ (RDGV_HAS_MEM_WRITE, RDGV_HAS_MEM_READS, RDG_STMT,
+ RDG_MEM_WRITE_STMT, RDG_MEM_READS_STMT): New.
+ (dump_rdg_vertex, debug_rdg_vertex, dump_rdg_component,
+ debug_rdg_component, dump_rdg, debug_rdg, dot_rdg,
+ rdg_vertex_for_stmt): Declared.
+ (struct rdg_edge): Add level.
+ (RDGE_LEVEL): New.
+ (free_rdg, stores_from_loop, remove_similar_memory_refs,
+ rdg_defs_used_in_other_loops_p, have_similar_memory_accesses): Declared.
+ (rdg_has_similar_memory_accesses): New.
+ * tree-vect-analyze.c: Remove unused static decls.
+ * lambda.h (dependence_level): New.
+ * common.opt (ftree-loop-distribution): New.
+ * tree-flow.h (mark_virtual_ops_in_bb,
+ slpeel_tree_duplicate_loop_to_edge_cfg,
+ rename_variables_in_loop): Declared.
+ * Makefile.in (TREE_DATA_REF_H): Depend on tree-chrec.h.
+ (OBJS-common): Add tree-loop-distribution.o.
+ (tree-loop-distribution.o): New rule.
+ * tree-cfg.c (mark_virtual_ops_in_bb): New.
+ (mark_virtual_ops_in_region): Use mark_virtual_ops_in_bb.
+ * passes.c (init_optimization_passes): Schedule pass_loop_distribution.
+
+2008-02-28 Joseph Myers <joseph@codesourcery.com>
+
+ PR target/33963
+ * tree.c (handle_dll_attribute): Disallow TYPE_DECLs for types
+ other than structures and unions.
+
+2008-02-28 Richard Guenther <rguenther@suse.de>
+
+ Revert:
+ 2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * tree-flow.h (uid_decl_map_hash, uid_decl_map_eq): Move ...
+ * tree.h (uid_decl_map_hash, uid_decl_map_eq): ... here.
+ (lookup_decl_from_uid): Declare.
+ (remove_decl_from_map): Likewise.
+ * tree-ssa.c (uid_decl_map_eq, uid_decl_map_hash): Move ...
+ * tree.c (uid_decl_map_eq, uid_decl_map_hash): ... here.
+ (decl_for_uid_map): New global hashtable mapping DECL_UID
+ to the decl tree.
+ (init_ttree): Allocate it.
+ (insert_decl_to_uid_decl_map): New helper function.
+ (make_node_stat): Insert new decls into the map.
+ (copy_node_stat): Likewise.
+ (lookup_decl_from_uid): New function.
+ (remove_decl_from_map): Likewise.
+ (print_decl_for_uid_map_statistics): New helper.
+ (dump_tree_statistics): Call it.
+
+ * tree-flow.h (struct gimple_df): Make referenced_vars a bitmap.
+ (referenced_var_iterator): Adjust.
+ (FOR_EACH_REFERENCED_VAR): Adjust.
+ (FOR_EACH_REFERENCED_VAR_IN_BITMAP): New iterator.
+ (num_referenced_vars): Adjust.
+ * tree-flow-inline.h (gimple_referenced_vars): Adjust.
+ (first_referenced_var): Remove.
+ (end_referenced_vars_p): Likewise.
+ (next_referenced_var): Likewise.
+ (referenced_var_iterator_set): New helper function.
+ * tree-dfa.c (referenced_var_lookup): Adjust.
+ (referenced_var_check_and_insert): Likewise.
+ (remove_referenced_var): Likewise.
+ * tree-ssa.c (verify_flow_insensitive_alias_info): Use
+ FOR_EACH_REFERENCED_VAR_IN_BITMAP.
+ (verify_call_clobbering): Likewise.
+ (verify_memory_partitions): Likewise.
+ (init_tree_ssa): Allocate bitmap instead of hashtable for
+ referenced_vars.
+ (delete_tree_ssa): Adjust.
+ * tree-ssa-alias.c (mark_aliases_call_clobbered): Use
+ FOR_EACH_REFERENCED_VAR_IN_BITMAP.
+ (compute_tag_properties): Likewise.
+ (set_initial_properties): Likewise.
+ (find_partition_for): Likewise.
+ (update_reference_counts): Likewise.
+ (dump_may_aliases_for): Likewise.
+ * tree-ssa-operands.c (add_virtual_operand): Likewise.
+ (add_call_clobber_ops): Likewise.
+ (add_call_read_ops): Likewise.
+ (get_asm_expr_operands): Likewise.
+ * tree-into-ssa.c (dump_decl_set): Likewise.
+ (update_ssa): Likewise.
+ * tree-sra.c (scan_function): Likewise.
+ (decide_instantiations): Likewise.
+ (scalarize_parms): Likewise.
+ * tree-ssa-alias-warnings.c (build_reference_table): Likewise.
+ (dsa_named_for): Likewise.
+ * tree-ssa-structalias.c (update_alias_info): Likewise.
+ (merge_smts_into): Likewise.
+
+2008-02-27 David Daney <ddaney@avtrex.com>
+
+ PR target/34409
+ * config/mips/iris.h (MIPS_DEBUGGING_INFO): Define.
+ * config/mips/openbsd.h (MIPS_DEBUGGING_INFO): Same.
+ * config/mips/sde.h (MIPS_DEBUGGING_INFO): Remove undef.
+ * config/mips/vxworks.h (MIPS_DEBUGGING_INFO): Same.
+ * config/mips/mips.h (MIPS_DEBUGGING_INFO): Remove define.
+
+2008-02-27 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/25477
+ * config/darwin-ppc-ldouble-patch.def (BUILT_IN_NANL): Add.
+ (BUILT_IN_NEXTTOWARD): Remove.
+ (BUILT_IN_NEXTTOWARDF): Ditto.
+ * config/darwin.c (darwin_patch_builtin): Use ACONCAT instead of
+ alloca/strcpy/strcat. Remove commented-out code. Fix whitespace.
+
+2008-02-27 Tom Tromey <tromey@redhat.com>
+
+ * tree-dump.c (dequeue_and_dump) <FUNCTION_DECL>: Check
+ DECL_SAVED_TREE, not DECL_LANG_SPECIFIC, when dumping body.
+
+2008-02-27 Jan Beulich <jbeulich@novell.com>
+
+ * c-decl.c (merge_decls): Use DECL_USER_ALIGN() on olddecl to
+ update the respective field on newdecl.
+
+2008-02-27 Revital Eres <eres@il.ibm.com>
+
+ PR rtl-optimization/34999
+ * bb-reorder.c (add_labels_and_missing_jumps): Do not handle
+ crossing edges that ends with a call insn.
+ (fix_up_fall_thru_edges): Handle crossing edges that ends with a
+ call insn and clear the EDGE_CROSSING flag of the crossing edge
+ when fixing fallthru edges.
+
+2008-02-27 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/35390
+ * fold-const.c (fold_unary): Return the correct argument,
+ converted to the result type.
+
+2008-02-27 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34971
+ * expr.c (expand_expr_real_1): Assert on rotates that operate
+ on partial modes.
+ * fold-const.c (fold_binary): Use the types precision, not the
+ bitsize of the mode if folding rotate expressions. Build rotates
+ only for full modes.
+
+2008-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ * c-ppoutput.c (scan_translation_unit): Handle CPP_PRAGMA
+ and CPP_PRAGMA_EOL.
+ * c-pragma.c (pragma_ns_name): New typedef.
+ (registered_pp_pragmas): New variable.
+ (c_pp_lookup_pragma): New function.
+ (c_register_pragma_1): If flag_preprocess_only, do nothing
+ for non-expanded pragmas, for expanded ones push pragma's
+ namespace and name into registered_pp_pragmas vector.
+ (c_invoke_pragma_handler): Register OpenMP pragmas even when
+ flag_preprocess_only, don't register GCC pch_preprocess
+ pragma if flag_preprocess_only.
+ * c-opts.c (c_common_init): Call init_pragma even if
+ flag_preprocess_only.
+ * c-pragma.c (c_pp_lookup_pragma): New prototype.
+ * config/darwin.h (DARWIN_REGISTER_TARGET_PRAGMAS): Don't call
+ cpp_register_pragma if flag_preprocess_only.
+
2008-02-26 Basile Starynkevitch <basile@starynkevitch.net>
* Makefile.in: adding melt-private-include/ thing
* melt/ : subdirectory moved here (was in ..)
@@ -8,6 +379,242 @@
svn+ssh://bstarynk@gcc.gnu.org/svn/gcc/trunk
* toplev.c (toplev_main): comprobe_finish() called before the print_ignored_options()
+2008-02-26 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR c/28800
+ * c-parser.c (c_parser_translation_unit): Warn for empty
+ translation unit, not empty source file.
+
+2008-02-26 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (thumb_set_frame_pointer): Ensure SP is first
+ operand for Thumb-2.
+ * config/arm/arm.h (reg_class): Add CORE_REGS.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Ditto.
+ (BASE_REG_CLASS): Use CORE_REGS.
+ (PREFERRED_RELOAD_CLASS): Add STACK_REG.
+ (REGNO_MODE_OK_FOR_REG_BASE_P): Use REGNO_MODE_OK_FOR_BASE_P.
+ (REGNO_OK_FOR_INDEX_P): Exclude SP.
+ (ARM_REG_OK_FOR_INDEX_P): Always define. Use
+ ARM_REGNO_OK_FOR_INDEX_P.
+ (ARM_PRINT_OPERAND_ADDRESS): Swap operands for [reg, sp].
+ * config/arm/arm.md (arm_addsi3, thumb1_addsi3, arm_subsi3_insn,
+ arm_movsi_insn, thumb1_movsi_insni, stack_tie): Add "k" alternatives.
+ (ldm/stm peepholes): Ditto.
+ * config/arm/thumb2.md (thumb2_movdi): Add "k" alternatives.
+ * config/arm/vfp.md (arm_movsi_vfp, thumb2_movsi_vfp): Ditto.
+ * config/arm/iwmmxt.md (iwmmxt_movsi_insn): Ditto.
+ * config/arm/constraints.md: Enable "k" constraint on ARM.
+
+2008-02-27 Ben Elliston <bje@au.ibm.com>
+
+ * config/rs6000/rs6000.c: Annotate cache line size field in all
+ instances of struct processor_costs.
+
+2008-02-26 David Edelsohn <edelsohn@gnu.org>
+
+ * dbgcnt.def (cfg_cleanup, cprop1, cprop2, dce_fast, dce_ud, dse1,
+ dse2, gcse, if_conversion, if_after_combine, if_after_reload,
+ jump_bypass): New counters.
+ * cfgcleanup.c (cleanup_cfg): Add dbg_cnt.
+ * dce.c (gate_ud_dce): Same.
+ (gate_fast_dce): Same.
+ * dse.c (gate_dse1): New function.
+ (gate_dse2): New function.
+ (gate_dse): Merge results of new gate functions.
+ * gcse.c (gcse_main): Bracket cprop1 and cprop2 with dbg_cnt.
+ (gate_handle_jump_bypass): Add dbg_cnt.
+ (gate_handle_gcse): Add dbg_cnt.
+ * ifcvt.c (gate_handle_if_conversion): Same.
+ (gate_handle_if_after_combine): Same.
+ (gate_handle_if_after_reload): Same.
+ * Makefile.in: Add DBGCNT_H to cfgcleanup.o and ifcvt.o.
+
+2008-02-26 Edmar Wienskoski <edmar@freescale.com>
+
+ * config/rs6000/rs6000.c (processor_costs): Update e300 cache
+ line sizes.
+ * doc/invoke.texi: Add e300c2 and e300c3 to list of cpus.
+
+2008-02-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/35315
+ * attribs.c (decl_attributes): Leave ATTR_FLAG_TYPE_IN_PLACE
+ alone if it's the naming decl for the type's main variant.
+
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * system.h (USE_MAPPED_LOCATION): Poison.
+ * Makefile.in (GTFILES): Put CPP_ID_DATA_H first.
+ * tree-cfg.c (make_cond_expr_edges): Remove old location code.
+ (make_goto_expr_edges): Likewise.
+ (remove_bb): Likewise.
+ (execute_warn_function_return): Likewise.
+ * basic-block.h (struct edge_def) <goto_locus>: Change type to
+ location_t.
+ * c-common.c (fname_decl): Remove old location code.
+ * tree-vect-transform.c (vect_finish_stmt_generation): Remove old
+ location code.
+ * rtl.h (ASM_OPERANDS_SOURCE_LOCATION): Remove old-location
+ variant.
+ (ASM_INPUT_SOURCE_LOCATION): Likewise.
+ (gen_rtx_ASM_INPUT): Likewise.
+ (gen_rtx_ASM_INPUT_loc): Likewise.
+ (get_rtx_asm_OPERANDS): Remove.
+ * cfglayout.c (insn_locators_alloc): Remove old location code.
+ (set_curr_insn_source_location): Likewise.
+ (curr_insn_locator): Likewise.
+ * print-tree.c (print_node): Remove old location code.
+ * tree-mudflap.c (mf_varname_tree): Remove old location code.
+ (mf_file_function_line_tree): Remove test of USE_MAPPED_LOCATION.
+ * cfgexpand.c (expand_gimple_cond_expr): Don't use
+ location_from_locus.
+ (construct_exit_block): Remove old location code.
+ * emit-rtl.c (force_next_line_note): Remove old location code.
+ * profile.c (branch_prob): Remove old location code.
+ * tree-vectorizer.h (LOC, UNKNOWN_LOC, EXPR_LOC, LOC_FILE,
+ LOC_LINE): Remove old-location variants.
+ * langhooks.c (lhd_print_error_function): Remove old location
+ code.
+ * configure, config.in: Rebuilt.
+ * configure.ac (--enable-mapped-location): Remove.
+ * c-decl.c (c_init_decl_processing): Remove old location code.
+ (finish_function): Likewise.
+ * recog.c (decode_asm_operands): Remove old location code.
+ * c-pch.c (c_common_read_pch): Remove old location code.
+ * rtl.def (ASM_INPUT, ASM_OPERANDS): Remove old location
+ variants.
+ * gimple-low.c (lower_function_body): Remove old location code.
+ * toplev.c (unknown_location): Remove.
+ (push_srcloc): Remove old-location variant.
+ (process_options): Remove old location code.
+ (lang_dependent_init): Likewise.
+ * input.h (UNKNOWN_LOCATION): Move definition.
+ (location_t): Undeprecate.
+ (source_locus): Remove.
+ (location_from_locus): Remove.
+ (struct location_s): Remove.
+ Remove all old-location code.
+ (input_line, input_filename): Remove.
+ * final.c (final_scan_insn): Remove old location code.
+ * diagnostic.c (diagnostic_build_prefix): Remove
+ USE_MAPPED_LOCATION test.
+ * tree.h (gimple_stmt) <locus>: Now a location_t.
+ (tree_exp) <locus>: Likewise.
+ (DECL_IS_BUILTIN): Remove old-location variant.
+ (annotate_with_file_line, annotate_with_locus): Likewise.
+ (expr_locus, set_expr_locus): Update.
+ * tree.c (build1_stat): Remove old location code.
+ (last_annotated_node): Remove.
+ (annotate_with_file_line): Remove old-location variant.
+ (annotate_with_locus): Likewise.
+ (expr_location): Remove old location code.
+ (set_expr_location): Likewise.
+ (expr_has_location): Likewise.
+ (expr_locus): Likewise.
+ (set_expr_locus): Likewise.
+ (expr_filename): Don't use location_from_locus.
+ (expr_lineno): Likewise.
+ * rtl-error.c (location_for_asm): Remove old location code.
+ * c-lex.c (cb_line_change): Remove old location code.
+ (fe_file_change): Likewise.
+ (cb_def_pragma): Likewise.
+ (c_lex_with_flags): Likewise.
+ * gengtype.c (do_typedef): Don't special-case location types.
+ (define_location_structures): Remove.
+ (main): Don't call define_location_structures.
+ * tree-pretty-print.c (dump_implicit_edges): Remove old location
+ code.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 26264
+ * builtins.def (BUILT_IN_STDARG_START): Remove.
+ * builtins.c (expand_builtin): Remove BUILT_IN_STDARG_START.
+ * tree-stdarg.c (execute_optimize_stdarg): Likewise.
+ * tree-inline.c (inline_forbidden_p_1): Likewise.
+
+2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * tree-flow.h (uid_decl_map_hash, uid_decl_map_eq): Move ...
+ * tree.h (uid_decl_map_hash, uid_decl_map_eq): ... here.
+ (lookup_decl_from_uid): Declare.
+ (remove_decl_from_map): Likewise.
+ * tree-ssa.c (uid_decl_map_eq, uid_decl_map_hash): Move ...
+ * tree.c (uid_decl_map_eq, uid_decl_map_hash): ... here.
+ (decl_for_uid_map): New global hashtable mapping DECL_UID
+ to the decl tree.
+ (init_ttree): Allocate it.
+ (insert_decl_to_uid_decl_map): New helper function.
+ (make_node_stat): Insert new decls into the map.
+ (copy_node_stat): Likewise.
+ (lookup_decl_from_uid): New function.
+ (remove_decl_from_map): Likewise.
+ (print_decl_for_uid_map_statistics): New helper.
+ (dump_tree_statistics): Call it.
+
+ * tree-flow.h (struct gimple_df): Make referenced_vars a bitmap.
+ (referenced_var_iterator): Adjust.
+ (FOR_EACH_REFERENCED_VAR): Adjust.
+ (FOR_EACH_REFERENCED_VAR_IN_BITMAP): New iterator.
+ (num_referenced_vars): Adjust.
+ * tree-flow-inline.h (gimple_referenced_vars): Adjust.
+ (first_referenced_var): Remove.
+ (end_referenced_vars_p): Likewise.
+ (next_referenced_var): Likewise.
+ (referenced_var_iterator_set): New helper function.
+ * tree-dfa.c (referenced_var_lookup): Adjust.
+ (referenced_var_check_and_insert): Likewise.
+ (remove_referenced_var): Likewise.
+ * tree-ssa.c (verify_flow_insensitive_alias_info): Use
+ FOR_EACH_REFERENCED_VAR_IN_BITMAP.
+ (verify_call_clobbering): Likewise.
+ (verify_memory_partitions): Likewise.
+ (init_tree_ssa): Allocate bitmap instead of hashtable for
+ referenced_vars.
+ (delete_tree_ssa): Adjust.
+ * tree-ssa-alias.c (mark_aliases_call_clobbered): Use
+ FOR_EACH_REFERENCED_VAR_IN_BITMAP.
+ (compute_tag_properties): Likewise.
+ (set_initial_properties): Likewise.
+ (find_partition_for): Likewise.
+ (update_reference_counts): Likewise.
+ (dump_may_aliases_for): Likewise.
+ * tree-ssa-operands.c (add_virtual_operand): Likewise.
+ (add_call_clobber_ops): Likewise.
+ (add_call_read_ops): Likewise.
+ (get_asm_expr_operands): Likewise.
+ * tree-into-ssa.c (dump_decl_set): Likewise.
+ (update_ssa): Likewise.
+ * tree-sra.c (scan_function): Likewise.
+ (decide_instantiations): Likewise.
+ (scalarize_parms): Likewise.
+ * tree-ssa-alias-warnings.c (build_reference_table): Likewise.
+ (dsa_named_for): Likewise.
+ * tree-ssa-structalias.c (update_alias_info): Likewise.
+ (merge_smts_into): Likewise.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 34351
+ * doc/invoke.texi (-Wall): Add -Wvolatile-register-var.
+ * c-opts.c (c_common_handle_option): Wall enables
+ Wvolatile-register-var.
+ * common.opt: Move Wvolatile-register-var to...
+ * c.opt: ...here.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * common.opt (Wlarger-than=): New.
+ * doc/invoke.texi (Warning Options): Replace -Wlarger-than- with
+ -Wlarger-than=.
+ * opts.c (common_handle_option): Handle -Wlarger-than=.
+ * optc-gen.awk: Likewise.
+ * opth-gen.awk: Likewise.
+ * stor-layout.c (layout_decl): Use -Wlarger-than= for warning.
+ * tree-optimize.c (tree_rest_of_compilation): Likewise.
+
+>>>>>>> .merge-right.r132817
2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* c-common.c (match_case_to_enum_1): Add appropriate
@@ -185,8 +792,7 @@
2008-02-25 Jan Beulich <jbeulich@novell.com>
- * Makefile.in: Also prefix uses of crt0.o and mcrt0.o with
- $(T).
+ * Makefile.in: Also prefix uses of crt0.o and mcrt0.o with $(T).
* config/i386/netware-libgcc.exp: Add __bswap?i2,
__emultls_get_address, __emultls_register_common,
__floatundi?f, and _Unwind_GetIPInfo.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index a7056adecde..2094f4c4415 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20080226
+20080302
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 4e775d517a2..205a495eefe 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -852,7 +852,7 @@ DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h
C_PRETTY_PRINT_H = c-pretty-print.h $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H)
SCEV_H = tree-scalar-evolution.h $(GGC_H) tree-chrec.h $(PARAMS_H)
LAMBDA_H = lambda.h $(TREE_H) vec.h $(GGC_H)
-TREE_DATA_REF_H = tree-data-ref.h $(LAMBDA_H) omega.h graphds.h
+TREE_DATA_REF_H = tree-data-ref.h $(LAMBDA_H) omega.h graphds.h tree-chrec.h
VARRAY_H = varray.h $(MACHMODE_H) $(SYSTEM_H) coretypes.h $(TM_H)
TREE_INLINE_H = tree-inline.h $(VARRAY_H) pointer-set.h
REAL_H = real.h $(MACHMODE_H)
@@ -1155,7 +1155,6 @@ OBJS-common = \
stmt.o \
stor-layout.o \
stringpool.o \
- struct-equiv.o \
targhooks.o \
timevar.o \
toplev.o \
@@ -1173,6 +1172,7 @@ OBJS-common = \
tree-if-conv.o \
tree-into-ssa.o \
tree-iterator.o \
+ tree-loop-distribution.o \
tree-loop-linear.o \
tree-nested.o \
tree-nrv.o \
@@ -2302,6 +2302,11 @@ tree-loop-linear.o: tree-loop-linear.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) $(LAMBDA_H) \
$(TARGET_H) tree-chrec.h $(OBSTACK_H)
+tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
+ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
+ tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) \
+ $(TARGET_H) tree-chrec.h tree-vectorizer.h
tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_FLOW_H) $(TREE_H) $(RTL_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(GGC_H) \
$(DIAGNOSTIC_H) tree-pass.h $(SCEV_H) langhooks.h gt-tree-parloops.h \
@@ -2565,7 +2570,7 @@ cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
output.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \
except.h $(TARGET_H) $(PARAMS_H) rtlhooks-def.h tree-pass.h $(REAL_H) \
- $(DF_H) $(DBGCNT_H)
+ $(DF_H) $(DBGCNT_H)
dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(DF_H) cselib.h \
$(DBGCNT_H) dce.h timevar.h tree-pass.h $(DBGCNT_H)
@@ -2686,7 +2691,7 @@ cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TIMEVAR_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \
toplev.h insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \
$(REGS_H) $(EMIT_RTL_H) $(CFGLAYOUT_H) tree-pass.h $(CFGLOOP_H) $(EXPR_H) \
- $(DF_H)
+ $(DF_H) $(DBGCNT_H)
cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(FLAGS_H) $(FUNCTION_H) \
$(OBSTACK_H) toplev.h $(TREE_FLOW_H) $(TREE_H) pointer-set.h output.h \
@@ -2696,10 +2701,6 @@ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(OBSTACK_H) output.h graphds.h
graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) bitmap.h $(OBSTACK_H) \
coretypes.h vec.h vecprim.h
-struct-equiv.o : struct-equiv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(RTL_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \
- insn-config.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \
- $(REGS_H) $(EMIT_RTL_H) $(DF_H)
loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H) \
output.h intl.h $(DF_H) $(HASHTAB_H)
@@ -2885,7 +2886,7 @@ ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) toplev.h $(FLAGS_H) insn-config.h $(FUNCTION_H) $(RECOG_H) \
$(TARGET_H) $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) \
$(REAL_H) $(OPTABS_H) $(CFGLOOP_H) hard-reg-set.h $(TIMEVAR_H) tree-pass.h \
- $(DF_H)
+ $(DF_H) $(DBGCNT_H)
lambda-mat.o : lambda-mat.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
$(TM_H) coretypes.h $(TREE_H)
lambda-trans.o: lambda-trans.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
@@ -3112,8 +3113,8 @@ s-constrs-h: $(MD_DEPS) build/genpreds$(build_exeext)
$(SHELL) $(srcdir)/../move-if-change tmp-constrs.h tm-constrs.h
$(STAMP) s-constrs-h
-GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
- $(CPP_ID_DATA_H) $(host_xm_file_list) \
+GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
+ $(host_xm_file_list) \
$(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
$(srcdir)/alias.h $(srcdir)/coverage.c $(srcdir)/rtl.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/function.h $(srcdir)/libfuncs.h $(SYMTAB_H) \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 954f1a90c5a..d86bfeb22eb 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,21 @@
+2008-02-27 Samuel Tardieu <sam@rfc1149.net>
+
+ PR ada/22255
+ * s-fileio.adb (Reset): Do not raise Use_Error if mode isn't changed.
+
+2008-02-27 Samuel Tardieu <sam@rfc1149.net>
+
+ PR ada/34799
+ * sem_ch13.adb (Analyze_Record_Representation_Clause): Check
+ that underlying type is present.
+
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * misc.c (internal_error_function): Remove test of
+ USE_MAPPED_LOCATION.
+ * trans.c (gigi): Remove test of USE_MAPPED_LOCATION.
+ (Sloc_to_locus): Remove old location code.
+
2008-02-25 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* gnat_rm.texi, gnat_ugn.texi: Fix spacing after `e.g.' and
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index c54bd9f7b90..4ddf10f23a9 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -412,11 +412,9 @@ internal_error_function (const char *msgid, va_list *ap)
fp.Array = buffer;
s = expand_location (input_location);
-#ifdef USE_MAPPED_LOCATION
if (flag_show_column && s.column != 0)
asprintf (&loc, "%s:%d:%d", s.file, s.line, s.column);
else
-#endif
asprintf (&loc, "%s:%d", s.file, s.line);
temp_loc.Low_Bound = 1;
temp_loc.High_Bound = strlen (loc);
diff --git a/gcc/ada/s-fileio.adb b/gcc/ada/s-fileio.adb
index a56877e2ad6..7a490cdc15c 100644
--- a/gcc/ada/s-fileio.adb
+++ b/gcc/ada/s-fileio.adb
@@ -1074,13 +1074,15 @@ package body System.File_IO is
begin
Check_File_Open (File);
- -- Change of mode not allowed for shared file or file with no name
- -- or file that is not a regular file, or for a system file.
-
- if File.Shared_Status = Yes
- or else File.Name'Length <= 1
- or else File.Is_System_File
- or else not File.Is_Regular_File
+ -- Change of mode not allowed for shared file or file with no name or
+ -- file that is not a regular file, or for a system file. Note that we
+ -- allow the "change" of mode if it is not in fact doing a change.
+
+ if Mode /= File.Mode
+ and then (File.Shared_Status = Yes
+ or else File.Name'Length <= 1
+ or else File.Is_System_File
+ or else not File.Is_Regular_File)
then
raise Use_Error;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 33a55a825b3..2b58c12edcd 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -2747,7 +2747,10 @@ package body Sem_Ch13 is
-- We are only interested in the case where there is at least one
-- unrepped component, and at least half the components have rep
-- clauses. We figure that if less than half have them, then the
- -- partial rep clause is really intentional.
+ -- partial rep clause is really intentional. If the component
+ -- type has no underlying type set at this point (as for a generic
+ -- formal type), we don't know enough to give a warning on the
+ -- component.
if Num_Unrepped_Components > 0
and then Num_Unrepped_Components < Num_Repped_Components
@@ -2756,6 +2759,7 @@ package body Sem_Ch13 is
while Present (Comp) loop
if No (Component_Clause (Comp))
and then Comes_From_Source (Comp)
+ and then Present (Underlying_Type (Etype (Comp)))
and then (Is_Scalar_Type (Underlying_Type (Etype (Comp)))
or else Size_Known_At_Compile_Time
(Underlying_Type (Etype (Comp))))
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index d1b454ca4d8..34cb297d245 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -244,7 +244,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
type_annotate_only = (gigi_operating_mode == 1);
-#ifdef USE_MAPPED_LOCATION
for (i = 0; i < number_files; i++)
{
/* Use the identifier table to make a permanent copy of the filename as
@@ -268,7 +267,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
linemap_position_for_column (line_table, 252 - 1);
linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
}
-#endif
/* Initialize ourselves. */
init_code_table ();
@@ -6650,7 +6648,6 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
return false;
if (Sloc <= Standard_Location)
-#ifdef USE_MAPPED_LOCATION
{
*locus = BUILTINS_LOCATION;
return false;
@@ -6667,22 +6664,6 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
+ ((line - map->to_line) << map->column_bits)
+ (column & ((1 << map->column_bits) - 1));
}
-#else
- return false;
-
- /* Use the identifier table to make a hashed, permanent copy of the filename,
- since the name table gets reallocated after Gigi returns but before all
- the debugging information is output. The __gnat_to_canonical_file_spec
- call translates filenames from pragmas Source_Reference that contain host
- style syntax not understood by gdb. */
- locus->file
- = IDENTIFIER_POINTER
- (get_identifier
- (__gnat_to_canonical_file_spec
- (Get_Name_String (Full_Debug_Name (Get_Source_File_Index (Sloc))))));
-
- locus->line = Get_Logical_Line_Number (Sloc);
-#endif
ref_filename
= IDENTIFIER_POINTER
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 31b92cad508..767035b5dd1 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -280,7 +280,11 @@ decl_attributes (tree *node, tree attributes, int flags)
if (spec->type_required && DECL_P (*anode))
{
anode = &TREE_TYPE (*anode);
- flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
+ /* Allow ATTR_FLAG_TYPE_IN_PLACE for the type's naming decl. */
+ if (!(TREE_CODE (*anode) == TYPE_DECL
+ && *anode == TYPE_NAME (TYPE_MAIN_VARIANT
+ (TREE_TYPE (*anode)))))
+ flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
}
if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index c04ef896102..10059235d7d 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -1,6 +1,6 @@
/* Define control and data flow tables, and regsets.
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -130,7 +130,7 @@ struct edge_def GTY(())
PTR GTY ((skip (""))) aux;
/* Location of any goto implicit in the edge, during tree-ssa. */
- source_locus goto_locus;
+ location_t goto_locus;
/* The index number corresponding to this edge in the edge vector
dest->preds. */
@@ -819,17 +819,6 @@ edge find_edge (basic_block, basic_block);
insns. */
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
-/* The following are ORed in on top of the CLEANUP* flags in calls to
- struct_equiv_block_eq. */
-#define STRUCT_EQUIV_START 64 /* Initializes the search range. */
-#define STRUCT_EQUIV_RERUN 128 /* Rerun to find register use in
- found equivalence. */
-#define STRUCT_EQUIV_FINAL 256 /* Make any changes necessary to get
- actual equivalence. */
-#define STRUCT_EQUIV_NEED_FULL_BLOCK 512 /* struct_equiv_block_eq is required
- to match only full blocks */
-#define STRUCT_EQUIV_MATCH_JUMPS 1024 /* Also include the jumps at the end of the block in the comparison. */
-
/* In lcm.c */
extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *,
sbitmap *, sbitmap *, sbitmap **,
@@ -969,171 +958,6 @@ extern rtx insert_insn_end_bb_new (rtx, basic_block);
#include "cfghooks.h"
-/* In struct-equiv.c */
-
-/* Constants used to size arrays in struct equiv_info (currently only one).
- When these limits are exceeded, struct_equiv returns zero.
- The maximum number of pseudo registers that are different in the two blocks,
- but appear in equivalent places and are dead at the end (or where one of
- a pair is dead at the end). */
-#define STRUCT_EQUIV_MAX_LOCAL 16
-/* The maximum number of references to an input register that struct_equiv
- can handle. */
-
-/* Structure used to track state during struct_equiv that can be rolled
- back when we find we can't match an insn, or if we want to match part
- of it in a different way.
- This information pertains to the pair of partial blocks that has been
- matched so far. Since this pair is structurally equivalent, this is
- conceptually just one partial block expressed in two potentially
- different ways. */
-struct struct_equiv_checkpoint
-{
- int ninsns; /* Insns are matched so far. */
- int local_count; /* Number of block-local registers. */
- int input_count; /* Number of inputs to the block. */
-
- /* X_START and Y_START are the first insns (in insn stream order)
- of the partial blocks that have been considered for matching so far.
- Since we are scanning backwards, they are also the instructions that
- are currently considered - or the last ones that have been considered -
- for matching (Unless we tracked back to these because a preceding
- instruction failed to match). */
- rtx x_start, y_start;
-
- /* INPUT_VALID indicates if we have actually set up X_INPUT / Y_INPUT
- during the current pass; we keep X_INPUT / Y_INPUT around between passes
- so that we can match REG_EQUAL / REG_EQUIV notes referring to these. */
- bool input_valid;
-
- /* Some information would be expensive to exactly checkpoint, so we
- merely increment VERSION any time information about local
- registers, inputs and/or register liveness changes. When backtracking,
- it is decremented for changes that can be undone, and if a discrepancy
- remains, NEED_RERUN in the relevant struct equiv_info is set to indicate
- that a new pass should be made over the entire block match to get
- accurate register information. */
- int version;
-};
-
-/* A struct equiv_info is used to pass information to struct_equiv and
- to gather state while two basic blocks are checked for structural
- equivalence. */
-
-struct equiv_info
-{
- /* Fields set up by the caller to struct_equiv_block_eq */
-
- basic_block x_block, y_block; /* The two blocks being matched. */
-
- /* MODE carries the mode bits from cleanup_cfg if we are called from
- try_crossjump_to_edge, and additionally it carries the
- STRUCT_EQUIV_* bits described above. */
- int mode;
-
- /* INPUT_COST is the cost that adding an extra input to the matched blocks
- is supposed to have, and is taken into account when considering if the
- matched sequence should be extended backwards. input_cost < 0 means
- don't accept any inputs at all. */
- int input_cost;
-
-
- /* Fields to track state inside of struct_equiv_block_eq. Some of these
- are also outputs. */
-
- /* X_INPUT and Y_INPUT are used by struct_equiv to record a register that
- is used as an input parameter, i.e. where different registers are used
- as sources. This is only used for a register that is live at the end
- of the blocks, or in some identical code at the end of the blocks;
- Inputs that are dead at the end go into X_LOCAL / Y_LOCAL. */
- rtx x_input, y_input;
- /* When a previous pass has identified a valid input, INPUT_REG is set
- by struct_equiv_block_eq, and it is henceforth replaced in X_BLOCK
- for the input. */
- rtx input_reg;
-
- /* COMMON_LIVE keeps track of the registers which are currently live
- (as we scan backwards from the end) and have the same numbers in both
- blocks. N.B. a register that is in common_live is unsuitable to become
- a local reg. */
- regset common_live;
- /* Likewise, X_LOCAL_LIVE / Y_LOCAL_LIVE keep track of registers that are
- local to one of the blocks; these registers must not be accepted as
- identical when encountered in both blocks. */
- regset x_local_live, y_local_live;
-
- /* EQUIV_USED indicates for which insns a REG_EQUAL or REG_EQUIV note is
- being used, to avoid having to backtrack in the next pass, so that we
- get accurate life info for this insn then. For each such insn,
- the bit with the number corresponding to the CUR.NINSNS value at the
- time of scanning is set. */
- bitmap equiv_used;
-
- /* Current state that can be saved & restored easily. */
- struct struct_equiv_checkpoint cur;
- /* BEST_MATCH is used to store the best match so far, weighing the
- cost of matched insns COSTS_N_INSNS (CUR.NINSNS) against the cost
- CUR.INPUT_COUNT * INPUT_COST of setting up the inputs. */
- struct struct_equiv_checkpoint best_match;
- /* If a checkpoint restore failed, or an input conflict newly arises,
- NEED_RERUN is set. This has to be tested by the caller to re-run
- the comparison if the match appears otherwise sound. The state kept in
- x_start, y_start, equiv_used and check_input_conflict ensures that
- we won't loop indefinitely. */
- bool need_rerun;
- /* If there is indication of an input conflict at the end,
- CHECK_INPUT_CONFLICT is set so that we'll check for input conflicts
- for each insn in the next pass. This is needed so that we won't discard
- a partial match if there is a longer match that has to be abandoned due
- to an input conflict. */
- bool check_input_conflict;
- /* HAD_INPUT_CONFLICT is set if CHECK_INPUT_CONFLICT was already set and we
- have passed a point where there were multiple dying inputs. This helps
- us decide if we should set check_input_conflict for the next pass. */
- bool had_input_conflict;
-
- /* LIVE_UPDATE controls if we want to change any life info at all. We
- set it to false during REG_EQUAL / REG_EUQIV note comparison of the final
- pass so that we don't introduce new registers just for the note; if we
- can't match the notes without the current register information, we drop
- them. */
- bool live_update;
-
- /* X_LOCAL and Y_LOCAL are used to gather register numbers of register pairs
- that are local to X_BLOCK and Y_BLOCK, with CUR.LOCAL_COUNT being the index
- to the next free entry. */
- rtx x_local[STRUCT_EQUIV_MAX_LOCAL], y_local[STRUCT_EQUIV_MAX_LOCAL];
- /* LOCAL_RVALUE is nonzero if the corresponding X_LOCAL / Y_LOCAL entry
- was a source operand (including STRICT_LOW_PART) for the last invocation
- of struct_equiv mentioning it, zero if it was a destination-only operand.
- Since we are scanning backwards, this means the register is input/local
- for the (partial) block scanned so far. */
- bool local_rvalue[STRUCT_EQUIV_MAX_LOCAL];
-
-
- /* Additional fields that are computed for the convenience of the caller. */
-
- /* DYING_INPUTS is set to the number of local registers that turn out
- to be inputs to the (possibly partial) block. */
- int dying_inputs;
- /* X_END and Y_END are the last insns in X_BLOCK and Y_BLOCK, respectively,
- that are being compared. A final jump insn will not be included. */
- rtx x_end, y_end;
-
- /* If we are matching tablejumps, X_LABEL in X_BLOCK corresponds to
- Y_LABEL in Y_BLOCK. */
- rtx x_label, y_label;
-
-};
-
-extern bool insns_match_p (rtx, rtx, struct equiv_info *);
-extern int struct_equiv_block_eq (int, struct equiv_info *);
-extern bool struct_equiv_init (int, struct equiv_info *);
-extern bool rtx_equiv_p (rtx *, rtx, int, struct equiv_info *);
-
-/* In cfgcleanup.c */
-extern bool condjump_equiv_p (struct equiv_info *, bool);
-
/* Return true when one of the predecessor edges of BB is marked with EDGE_EH. */
static inline bool
bb_has_eh_pred (basic_block bb)
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 352c9889172..18e9405a7ae 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -1289,11 +1289,14 @@ add_labels_and_missing_jumps (edge *crossing_edges, int n_crossing_edges)
{
label = block_label (dest);
- /* Make sure source block ends with a jump. */
+ /* Make sure source block ends with a jump. If the
+ source block does not end with a jump it might end
+ with a call_insn; this case will be handled in
+ fix_up_fall_thru_edges function. */
if (src && (src != ENTRY_BLOCK_PTR))
{
- if (!JUMP_P (BB_END (src)))
+ if (!JUMP_P (BB_END (src)) && !block_ends_with_call_p (src))
/* bb just falls through. */
{
/* make sure there's only one successor */
@@ -1318,13 +1321,13 @@ add_labels_and_missing_jumps (edge *crossing_edges, int n_crossing_edges)
}
/* Find any bb's where the fall-through edge is a crossing edge (note that
- these bb's must also contain a conditional jump; we've already
- dealt with fall-through edges for blocks that didn't have a
- conditional jump in the call to add_labels_and_missing_jumps).
- Convert the fall-through edge to non-crossing edge by inserting a
- new bb to fall-through into. The new bb will contain an
- unconditional jump (crossing edge) to the original fall through
- destination. */
+ these bb's must also contain a conditional jump or end with a call
+ instruction; we've already dealt with fall-through edges for blocks
+ that didn't have a conditional jump or didn't end with call instruction
+ in the call to add_labels_and_missing_jumps). Convert the fall-through
+ edge to non-crossing edge by inserting a new bb to fall-through into.
+ The new bb will contain an unconditional jump (crossing edge) to the
+ original fall through destination. */
static void
fix_up_fall_thru_edges (void)
@@ -1369,6 +1372,19 @@ fix_up_fall_thru_edges (void)
fall_thru = succ2;
cond_jump = succ1;
}
+ else if (!fall_thru && succ1 && block_ends_with_call_p (cur_bb))
+ {
+ edge e;
+ edge_iterator ei;
+
+ /* Find EDGE_CAN_FALLTHRU edge. */
+ FOR_EACH_EDGE (e, ei, cur_bb->succs)
+ if (e->flags & EDGE_CAN_FALLTHRU)
+ {
+ fall_thru = e;
+ break;
+ }
+ }
if (fall_thru && (fall_thru->dest != EXIT_BLOCK_PTR))
{
@@ -1426,8 +1442,14 @@ fix_up_fall_thru_edges (void)
/* This is the case where both edges out of the basic
block are crossing edges. Here we will fix up the
fall through edge. The jump edge will be taken care
- of later. */
-
+ of later. The EDGE_CROSSING flag of fall_thru edge
+ is unset before the call to force_nonfallthru
+ function because if a new basic-block is created
+ this edge remains in the current section boundary
+ while the edge between new_bb and the fall_thru->dest
+ becomes EDGE_CROSSING. */
+
+ fall_thru->flags &= ~EDGE_CROSSING;
new_bb = force_nonfallthru (fall_thru);
if (new_bb)
@@ -1441,6 +1463,12 @@ fix_up_fall_thru_edges (void)
BB_COPY_PARTITION (new_bb, cur_bb);
single_succ_edge (new_bb)->flags |= EDGE_CROSSING;
}
+ else
+ {
+ /* If a new basic-block was not created; restore
+ the EDGE_CROSSING flag. */
+ fall_thru->flags |= EDGE_CROSSING;
+ }
/* Add barrier after new jump */
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 5e6ebf5d116..31b9df2d5dd 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6702,7 +6702,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
case BUILT_IN_VA_START:
- case BUILT_IN_STDARG_START:
return expand_builtin_va_start (exp);
case BUILT_IN_VA_END:
return expand_builtin_va_end (exp);
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 836e241a931..dd6741e29b3 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -693,7 +693,6 @@ DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
-DEF_GCC_BUILTIN (BUILT_IN_STDARG_START, "stdarg_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 2b8790d0729..f3de12a7359 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -443,11 +443,6 @@ int flag_use_cxa_atexit = DEFAULT_USE_CXA_ATEXIT;
int flag_use_cxa_get_exception_ptr = 2;
-/* Nonzero means make the default pedwarns warnings instead of errors.
- The value of this flag is ignored if -pedantic is specified. */
-
-int flag_permissive;
-
/* Nonzero means to implement standard semantics for exception
specifications, calling unexpected if an exception is thrown that
doesn't match the specification. Zero means to treat them as
@@ -840,11 +835,7 @@ fname_decl (unsigned int rid, tree id)
it from appearing in the RTL. */
tree stmts;
location_t saved_location = input_location;
-#ifdef USE_MAPPED_LOCATION
input_location = UNKNOWN_LOCATION;
-#else
- input_line = 0;
-#endif
stmts = push_stmt_list ();
decl = (*make_fname_decl) (id, fname_vars[ix].pretty);
@@ -931,14 +922,25 @@ fix_string_type (tree value)
void
constant_expression_warning (tree value)
{
+ if (warn_overflow && pedantic
+ && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
+ || TREE_CODE (value) == FIXED_CST
+ || TREE_CODE (value) == VECTOR_CST
+ || TREE_CODE (value) == COMPLEX_CST)
+ && TREE_OVERFLOW (value))
+ pedwarn ("overflow in constant expression");
+}
+
+/* The same as above but print an unconditional error. */
+void
+constant_expression_error (tree value)
+{
if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
|| TREE_CODE (value) == FIXED_CST
|| TREE_CODE (value) == VECTOR_CST
|| TREE_CODE (value) == COMPLEX_CST)
- && TREE_OVERFLOW (value)
- && warn_overflow
- && pedantic)
- pedwarn ("overflow in constant expression");
+ && TREE_OVERFLOW (value))
+ error ("overflow in constant expression");
}
/* Print a warning if an expression had overflow in folding and its
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 99209c71ce3..a072710c9ab 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -584,11 +584,6 @@ extern int flag_use_cxa_atexit;
extern int flag_use_cxa_get_exception_ptr;
-/* Nonzero means make the default pedwarns warnings instead of errors.
- The value of this flag is ignored if -pedantic is specified. */
-
-extern int flag_permissive;
-
/* Nonzero means to implement standard semantics for exception
specifications, calling unexpected if an exception is thrown that
doesn't match the specification. Zero means to treat them as
@@ -688,6 +683,7 @@ extern void binary_op_error (enum tree_code, tree, tree);
extern tree fix_string_type (tree);
struct varray_head_tag;
extern void constant_expression_warning (tree);
+extern void constant_expression_error (tree);
extern bool strict_aliasing_warning (tree, tree, tree);
extern void empty_if_body_warning (tree, tree);
extern void warnings_for_convert_and_check (tree, tree, tree);
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 4e9564d25e1..04b36d50d88 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1667,7 +1667,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
{
DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
- DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
+ DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
}
}
@@ -2760,12 +2760,7 @@ c_init_decl_processing (void)
/* Declarations from c_common_nodes_and_builtins must not be associated
with this input file, lest we get differences between using and not
using preprocessed headers. */
-#ifdef USE_MAPPED_LOCATION
input_location = BUILTINS_LOCATION;
-#else
- input_location.file = "<built-in>";
- input_location.line = 0;
-#endif
build_common_tree_nodes (flag_signed_char, false);
@@ -6721,7 +6716,6 @@ finish_function (void)
if (flag_isoc99)
{
tree stmt = c_finish_return (integer_zero_node);
-#ifdef USE_MAPPED_LOCATION
/* Hack. We don't want the middle-end to warn that this return
is unreachable, so we mark its location as special. Using
UNKNOWN_LOCATION has the problem that it gets clobbered in
@@ -6729,12 +6723,6 @@ finish_function (void)
ensure ! should_carry_locus_p (stmt), but that needs a flag.
*/
SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION);
-#else
- /* Hack. We don't want the middle-end to warn that this
- return is unreachable, so put the statement on the
- special line 0. */
- annotate_with_file_line (stmt, input_filename, 0);
-#endif
}
}
}
diff --git a/gcc/c-errors.c b/gcc/c-errors.c
index c85d3978330..dc47b764f39 100644
--- a/gcc/c-errors.c
+++ b/gcc/c-errors.c
@@ -38,7 +38,7 @@ pedwarn_c99 (const char *gmsgid, ...)
va_start (ap, gmsgid);
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
- flag_isoc99 ? pedantic_error_kind () : DK_WARNING);
+ flag_isoc99 ? pedantic_warning_kind () : DK_WARNING);
report_diagnostic (&diagnostic);
va_end (ap);
}
@@ -56,7 +56,7 @@ pedwarn_c90 (const char *gmsgid, ...)
va_start (ap, gmsgid);
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
- flag_isoc99 ? DK_WARNING : pedantic_error_kind ());
+ flag_isoc99 ? DK_WARNING : pedantic_warning_kind ());
report_diagnostic (&diagnostic);
va_end (ap);
}
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index 5cad2609a4a..617cd7ee52c 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -1,6 +1,6 @@
/* Mainly the interface between cpplib and the C front ends.
Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -190,15 +190,7 @@ cb_line_change (cpp_reader * ARG_UNUSED (pfile), const cpp_token *token,
int parsing_args)
{
if (token->type != CPP_EOF && !parsing_args)
-#ifdef USE_MAPPED_LOCATION
input_location = token->src_loc;
-#else
- {
- source_location loc = token->src_loc;
- const struct line_map *map = linemap_lookup (line_table, loc);
- input_line = SOURCE_LINE (map, loc);
- }
-#endif
}
void
@@ -213,17 +205,9 @@ fe_file_change (const struct line_map *new_map)
we already did in compile_file. */
if (!MAIN_FILE_P (new_map))
{
-#ifdef USE_MAPPED_LOCATION
int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
- input_location = included_at;
- push_srcloc (new_map->start_location);
-#else
- int included_at = LAST_SOURCE_LINE (new_map - 1);
-
- input_line = included_at;
- push_srcloc (new_map->to_file, 1);
-#endif
+ input_location = new_map->start_location;
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
if (c_header_level)
@@ -246,19 +230,14 @@ fe_file_change (const struct line_map *new_map)
--pending_lang_change;
}
#endif
- pop_srcloc ();
+ input_location = new_map->start_location;
(*debug_hooks->end_source_file) (new_map->to_line);
}
update_header_times (new_map->to_file);
in_system_header = new_map->sysp != 0;
-#ifdef USE_MAPPED_LOCATION
input_location = new_map->start_location;
-#else
- input_filename = new_map->to_file;
- input_line = new_map->to_line;
-#endif
}
static void
@@ -271,14 +250,7 @@ cb_def_pragma (cpp_reader *pfile, source_location loc)
{
const unsigned char *space, *name;
const cpp_token *s;
-#ifndef USE_MAPPED_LOCATION
- location_t fe_loc;
- const struct line_map *map = linemap_lookup (line_table, loc);
- fe_loc.file = map->to_file;
- fe_loc.line = SOURCE_LINE (map, loc);
-#else
location_t fe_loc = loc;
-#endif
space = name = (const unsigned char *) "";
s = cpp_get_token (pfile);
@@ -329,12 +301,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
timevar_push (TV_CPP);
retry:
-#ifdef USE_MAPPED_LOCATION
tok = cpp_get_token_with_location (parse_in, loc);
-#else
- tok = cpp_get_token (parse_in);
- *loc = input_location;
-#endif
type = tok->type;
retry_after_at:
@@ -381,19 +348,11 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
/* An @ may give the next token special significance in Objective-C. */
if (c_dialect_objc ())
{
-#ifdef USE_MAPPED_LOCATION
location_t atloc = *loc;
location_t newloc;
-#else
- location_t atloc = input_location;
-#endif
retry_at:
-#ifdef USE_MAPPED_LOCATION
tok = cpp_get_token_with_location (parse_in, &newloc);
-#else
- tok = cpp_get_token (parse_in);
-#endif
type = tok->type;
switch (type)
{
@@ -417,9 +376,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
default:
/* ... or not. */
error ("%Hstray %<@%> in program", &atloc);
-#ifdef USE_MAPPED_LOCATION
*loc = newloc;
-#endif
goto retry_after_at;
}
break;
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index 4cb76872be3..69c4d544885 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -1,5 +1,5 @@
/* C/ObjC/C++ command line option handling.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Neil Booth.
@@ -407,6 +407,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
if (warn_strict_overflow == -1)
warn_strict_overflow = value;
warn_array_bounds = value;
+ warn_volatile_register_var = value;
/* Only warn about unknown pragmas that are not in system
headers. */
@@ -1106,18 +1107,6 @@ c_common_post_options (const char **pfilename)
/* Adjust various flags for C++ based on command-line settings. */
if (c_dialect_cxx ())
{
- if (!flag_permissive)
- {
- flag_pedantic_errors = 1;
- /* FIXME: For consistency pedantic_errors should have the
- same value in the front-end and in CPP. However, this
- will break existing applications. The right fix is
- disentagle flag_permissive from flag_pedantic_errors,
- create a new diagnostic function permerror that is
- controlled by flag_permissive and convert most C++
- pedwarns to this new function.
- cpp_opts->pedantic_errors = 1; */
- }
if (!flag_no_inline)
{
flag_inline_trees = 1;
@@ -1238,6 +1227,9 @@ c_common_init (void)
if (version_flag)
c_common_print_pch_checksum (stderr);
+ /* Has to wait until now so that cpplib has its hash table. */
+ init_pragma ();
+
if (flag_preprocess_only)
{
finish_options ();
@@ -1245,9 +1237,6 @@ c_common_init (void)
return false;
}
- /* Has to wait until now so that cpplib has its hash table. */
- init_pragma ();
-
return true;
}
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 72f8a21c0fe..1e63c14ef8b 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -1069,7 +1069,7 @@ c_parser_translation_unit (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_EOF))
{
if (pedantic)
- pedwarn ("%HISO C forbids an empty source file",
+ pedwarn ("%HISO C forbids an empty translation unit",
&c_parser_peek_token (parser)->location);
}
else
diff --git a/gcc/c-pch.c b/gcc/c-pch.c
index ccf3c86590c..691e12a2f79 100644
--- a/gcc/c-pch.c
+++ b/gcc/c-pch.c
@@ -1,5 +1,5 @@
/* Precompiled header implementation for the C languages.
- Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -410,16 +410,7 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
}
/* Save the location and then restore it after reading the PCH. */
-#ifdef USE_MAPPED_LOCATION
saved_loc = expand_location (line_table->highest_line);
-#else
- {
- const struct line_map *map = linemap_lookup (line_table,
- line_table->highest_line);
- saved_loc.file = map->to_file;
- saved_loc.line = SOURCE_LINE (map, line_table->highest_line);
- }
-#endif
cpp_prepare_state (pfile, &smd);
diff --git a/gcc/c-ppoutput.c b/gcc/c-ppoutput.c
index f02d6cd2b76..6a251fe995c 100644
--- a/gcc/c-ppoutput.c
+++ b/gcc/c-ppoutput.c
@@ -1,6 +1,6 @@
/* Preprocess only, using cpplib.
- Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
+ 2008 Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
This program is free software; you can redistribute it and/or modify it
@@ -177,7 +177,24 @@ scan_translation_unit (cpp_reader *pfile)
avoid_paste = false;
print.source = NULL;
print.prev = token;
- cpp_output_token (token, print.outf);
+ if (token->type == CPP_PRAGMA)
+ {
+ const char *space;
+ const char *name;
+
+ maybe_print_line (token->src_loc);
+ fputs ("#pragma ", print.outf);
+ c_pp_lookup_pragma (token->val.pragma, &space, &name);
+ if (space)
+ fprintf (print.outf, "%s %s", space, name);
+ else
+ fprintf (print.outf, "%s", name);
+ print.printed = 1;
+ }
+ else if (token->type == CPP_PRAGMA_EOL)
+ maybe_print_line (token->src_loc);
+ else
+ cpp_output_token (token, print.outf);
if (token->type == CPP_COMMENT)
account_for_newlines (token->val.str.text, token->val.str.len);
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index f7da67622ce..44e95b81c0a 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -1,6 +1,6 @@
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007 Free Software Foundation, Inc.
+ 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -872,6 +872,61 @@ DEF_VEC_ALLOC_O (pragma_handler, heap);
static VEC(pragma_handler, heap) *registered_pragmas;
+typedef struct
+{
+ const char *space;
+ const char *name;
+} pragma_ns_name;
+
+DEF_VEC_O (pragma_ns_name);
+DEF_VEC_ALLOC_O (pragma_ns_name, heap);
+
+static VEC(pragma_ns_name, heap) *registered_pp_pragmas;
+
+struct omp_pragma_def { const char *name; unsigned int id; };
+static const struct omp_pragma_def omp_pragmas[] = {
+ { "atomic", PRAGMA_OMP_ATOMIC },
+ { "barrier", PRAGMA_OMP_BARRIER },
+ { "critical", PRAGMA_OMP_CRITICAL },
+ { "flush", PRAGMA_OMP_FLUSH },
+ { "for", PRAGMA_OMP_FOR },
+ { "master", PRAGMA_OMP_MASTER },
+ { "ordered", PRAGMA_OMP_ORDERED },
+ { "parallel", PRAGMA_OMP_PARALLEL },
+ { "section", PRAGMA_OMP_SECTION },
+ { "sections", PRAGMA_OMP_SECTIONS },
+ { "single", PRAGMA_OMP_SINGLE },
+ { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
+};
+
+void
+c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
+{
+ const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
+ int i;
+
+ for (i = 0; i < n_omp_pragmas; ++i)
+ if (omp_pragmas[i].id == id)
+ {
+ *space = "omp";
+ *name = omp_pragmas[i].name;
+ return;
+ }
+
+ if (id >= PRAGMA_FIRST_EXTERNAL
+ && (id < PRAGMA_FIRST_EXTERNAL
+ + VEC_length (pragma_ns_name, registered_pp_pragmas)))
+ {
+ *space = VEC_index (pragma_ns_name, registered_pp_pragmas,
+ id - PRAGMA_FIRST_EXTERNAL)->space;
+ *name = VEC_index (pragma_ns_name, registered_pp_pragmas,
+ id - PRAGMA_FIRST_EXTERNAL)->name;
+ return;
+ }
+
+ gcc_unreachable ();
+}
+
/* Front-end wrappers for pragma registration to avoid dragging
cpplib.h in almost everywhere. */
@@ -881,13 +936,29 @@ c_register_pragma_1 (const char *space, const char *name,
{
unsigned id;
- VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
- id = VEC_length (pragma_handler, registered_pragmas);
- id += PRAGMA_FIRST_EXTERNAL - 1;
+ if (flag_preprocess_only)
+ {
+ pragma_ns_name ns_name;
- /* The C++ front end allocates 6 bits in cp_token; the C front end
- allocates 7 bits in c_token. At present this is sufficient. */
- gcc_assert (id < 64);
+ if (!allow_expansion)
+ return;
+
+ ns_name.space = space;
+ ns_name.name = name;
+ VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas, &ns_name);
+ id = VEC_length (pragma_ns_name, registered_pp_pragmas);
+ id += PRAGMA_FIRST_EXTERNAL - 1;
+ }
+ else
+ {
+ VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
+ id = VEC_length (pragma_handler, registered_pragmas);
+ id += PRAGMA_FIRST_EXTERNAL - 1;
+
+ /* The C++ front end allocates 6 bits in cp_token; the C front end
+ allocates 7 bits in c_token. At present this is sufficient. */
+ gcc_assert (id < 64);
+ }
cpp_register_deferred_pragma (parse_in, space, name, id,
allow_expansion, false);
@@ -921,24 +992,8 @@ c_invoke_pragma_handler (unsigned int id)
void
init_pragma (void)
{
- if (flag_openmp && !flag_preprocess_only)
+ if (flag_openmp)
{
- struct omp_pragma_def { const char *name; unsigned int id; };
- static const struct omp_pragma_def omp_pragmas[] = {
- { "atomic", PRAGMA_OMP_ATOMIC },
- { "barrier", PRAGMA_OMP_BARRIER },
- { "critical", PRAGMA_OMP_CRITICAL },
- { "flush", PRAGMA_OMP_FLUSH },
- { "for", PRAGMA_OMP_FOR },
- { "master", PRAGMA_OMP_MASTER },
- { "ordered", PRAGMA_OMP_ORDERED },
- { "parallel", PRAGMA_OMP_PARALLEL },
- { "section", PRAGMA_OMP_SECTION },
- { "sections", PRAGMA_OMP_SECTIONS },
- { "single", PRAGMA_OMP_SINGLE },
- { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
- };
-
const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
int i;
@@ -947,8 +1002,9 @@ init_pragma (void)
omp_pragmas[i].id, true, true);
}
- cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
- PRAGMA_GCC_PCH_PREPROCESS, false, false);
+ if (!flag_preprocess_only)
+ cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
+ PRAGMA_GCC_PCH_PREPROCESS, false, false);
#ifdef HANDLE_PRAGMA_PACK
#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
diff --git a/gcc/c-pragma.h b/gcc/c-pragma.h
index 9896f434bd3..747a053b2e8 100644
--- a/gcc/c-pragma.h
+++ b/gcc/c-pragma.h
@@ -1,6 +1,6 @@
/* Pragma related interfaces.
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -124,4 +124,6 @@ extern enum cpp_ttype pragma_lex (tree *);
extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *,
int);
+extern void c_pp_lookup_pragma (unsigned int, const char **, const char **);
+
#endif /* GCC_C_PRAGMA_H */
diff --git a/gcc/c.opt b/gcc/c.opt
index 72165b96660..d3f81b0e1c7 100644
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -465,6 +465,10 @@ Wvla
C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning
Warn if a variable length array is used
+Wvolatile-register-var
+C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning
+Warn when a register variable is declared volatile
+
Wwrite-strings
C ObjC C++ ObjC++ Var(warn_write_strings) Warning
In C++, nonzero means warn about deprecated conversion from string literals to `char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 3ec7d3f3781..a95204cf4fc 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "df.h"
#include "dce.h"
+#include "dbgcnt.h"
#define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK)
@@ -1133,134 +1134,6 @@ flow_find_cross_jump (int mode ATTRIBUTE_UNUSED, basic_block bb1,
return ninsns;
}
-/* Return true iff the condbranches at the end of BB1 and BB2 match. */
-bool
-condjump_equiv_p (struct equiv_info *info, bool call_init)
-{
- basic_block bb1 = info->x_block;
- basic_block bb2 = info->y_block;
- edge b1 = BRANCH_EDGE (bb1);
- edge b2 = BRANCH_EDGE (bb2);
- edge f1 = FALLTHRU_EDGE (bb1);
- edge f2 = FALLTHRU_EDGE (bb2);
- bool reverse, match;
- rtx set1, set2, cond1, cond2;
- rtx src1, src2;
- enum rtx_code code1, code2;
-
- /* Get around possible forwarders on fallthru edges. Other cases
- should be optimized out already. */
- if (FORWARDER_BLOCK_P (f1->dest))
- f1 = single_succ_edge (f1->dest);
-
- if (FORWARDER_BLOCK_P (f2->dest))
- f2 = single_succ_edge (f2->dest);
-
- /* To simplify use of this function, return false if there are
- unneeded forwarder blocks. These will get eliminated later
- during cleanup_cfg. */
- if (FORWARDER_BLOCK_P (f1->dest)
- || FORWARDER_BLOCK_P (f2->dest)
- || FORWARDER_BLOCK_P (b1->dest)
- || FORWARDER_BLOCK_P (b2->dest))
- return false;
-
- if (f1->dest == f2->dest && b1->dest == b2->dest)
- reverse = false;
- else if (f1->dest == b2->dest && b1->dest == f2->dest)
- reverse = true;
- else
- return false;
-
- set1 = pc_set (BB_END (bb1));
- set2 = pc_set (BB_END (bb2));
- if ((XEXP (SET_SRC (set1), 1) == pc_rtx)
- != (XEXP (SET_SRC (set2), 1) == pc_rtx))
- reverse = !reverse;
-
- src1 = SET_SRC (set1);
- src2 = SET_SRC (set2);
- cond1 = XEXP (src1, 0);
- cond2 = XEXP (src2, 0);
- code1 = GET_CODE (cond1);
- if (reverse)
- code2 = reversed_comparison_code (cond2, BB_END (bb2));
- else
- code2 = GET_CODE (cond2);
-
- if (code2 == UNKNOWN)
- return false;
-
- if (call_init && !struct_equiv_init (STRUCT_EQUIV_START | info->mode, info))
- gcc_unreachable ();
- /* Make the sources of the pc sets unreadable so that when we call
- insns_match_p it won't process them.
- The death_notes_match_p from insns_match_p won't see the local registers
- used for the pc set, but that could only cause missed optimizations when
- there are actually condjumps that use stack registers. */
- SET_SRC (set1) = pc_rtx;
- SET_SRC (set2) = pc_rtx;
- /* Verify codes and operands match. */
- if (code1 == code2)
- {
- match = (insns_match_p (BB_END (bb1), BB_END (bb2), info)
- && rtx_equiv_p (&XEXP (cond1, 0), XEXP (cond2, 0), 1, info)
- && rtx_equiv_p (&XEXP (cond1, 1), XEXP (cond2, 1), 1, info));
-
- }
- else if (code1 == swap_condition (code2))
- {
- match = (insns_match_p (BB_END (bb1), BB_END (bb2), info)
- && rtx_equiv_p (&XEXP (cond1, 1), XEXP (cond2, 0), 1, info)
- && rtx_equiv_p (&XEXP (cond1, 0), XEXP (cond2, 1), 1, info));
-
- }
- else
- match = false;
- SET_SRC (set1) = src1;
- SET_SRC (set2) = src2;
- match &= verify_changes (0);
-
- /* If we return true, we will join the blocks. Which means that
- we will only have one branch prediction bit to work with. Thus
- we require the existing branches to have probabilities that are
- roughly similar. */
- if (match
- && !optimize_size
- && maybe_hot_bb_p (bb1)
- && maybe_hot_bb_p (bb2))
- {
- int prob2;
-
- if (b1->dest == b2->dest)
- prob2 = b2->probability;
- else
- /* Do not use f2 probability as f2 may be forwarded. */
- prob2 = REG_BR_PROB_BASE - b2->probability;
-
- /* Fail if the difference in probabilities is greater than 50%.
- This rules out two well-predicted branches with opposite
- outcomes. */
- if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 2)
- {
- if (dump_file)
- fprintf (dump_file,
- "Outcomes of branch in bb %i and %i differ too much (%i %i)\n",
- bb1->index, bb2->index, b1->probability, prob2);
-
- match = false;
- }
- }
-
- if (dump_file && match)
- fprintf (dump_file, "Conditionals in bb %i and %i match.\n",
- bb1->index, bb2->index);
-
- if (!match)
- cancel_changes (0);
- return match;
-}
-
/* Return true iff outgoing edges of BB1 and BB2 match, together with
the branch instruction. This means that if we commonize the control
flow before end of the basic block, the semantic remains unchanged.
@@ -2250,6 +2123,9 @@ cleanup_cfg (int mode)
if (mode & CLEANUP_CROSSJUMP)
add_noreturn_fake_exit_edges ();
+ if (!dbg_cnt (cfg_cleanup))
+ return changed;
+
while (try_optimize_cfg (mode))
{
delete_unreachable_blocks (), changed = true;
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index d22facbabe3..943a0704168 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1,5 +1,5 @@
/* A pass for lowering trees to RTL.
- Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1316,7 +1316,7 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
add_reg_br_prob_note (last, true_edge->probability);
maybe_dump_rtl_for_tree_stmt (stmt, last);
if (true_edge->goto_locus)
- set_curr_insn_source_location (location_from_locus (true_edge->goto_locus));
+ set_curr_insn_source_location (true_edge->goto_locus);
false_edge->flags |= EDGE_FALLTHRU;
return NULL;
}
@@ -1326,7 +1326,7 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
add_reg_br_prob_note (last, false_edge->probability);
maybe_dump_rtl_for_tree_stmt (stmt, last);
if (false_edge->goto_locus)
- set_curr_insn_source_location (location_from_locus (false_edge->goto_locus));
+ set_curr_insn_source_location (false_edge->goto_locus);
true_edge->flags |= EDGE_FALLTHRU;
return NULL;
}
@@ -1357,7 +1357,7 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
maybe_dump_rtl_for_tree_stmt (stmt, last2);
if (false_edge->goto_locus)
- set_curr_insn_source_location (location_from_locus (false_edge->goto_locus));
+ set_curr_insn_source_location (false_edge->goto_locus);
return new_bb;
}
@@ -1624,7 +1624,7 @@ expand_gimple_basic_block (basic_block bb)
{
emit_jump (label_rtx_for_bb (e->dest));
if (e->goto_locus)
- set_curr_insn_source_location (location_from_locus (e->goto_locus));
+ set_curr_insn_source_location (e->goto_locus);
e->flags &= ~EDGE_FALLTHRU;
}
@@ -1724,11 +1724,7 @@ construct_exit_block (void)
/* Make sure the locus is set to the end of the function, so that
epilogue line numbers and warnings are set properly. */
-#ifdef USE_MAPPED_LOCATION
if (cfun->function_end_locus != UNKNOWN_LOCATION)
-#else
- if (cfun->function_end_locus.file)
-#endif
input_location = cfun->function_end_locus;
/* The following insns belong to the top scope. */
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index c70348c9a4d..5387b388260 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -1,5 +1,5 @@
/* Basic block reordering routines for the GNU compiler.
- Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -255,13 +255,8 @@ insn_locators_alloc (void)
locations_locators_locs = VEC_alloc (int, heap, 32);
locations_locators_vals = VEC_alloc (location_t, heap, 32);
-#ifdef USE_MAPPED_LOCATION
last_location = -1;
curr_location = -1;
-#else
- last_location.line = -1;
- curr_location.line = -1;
-#endif
curr_block = NULL;
last_block = NULL;
curr_rtl_loc = 0;
@@ -284,15 +279,8 @@ set_curr_insn_source_location (location_t location)
time locators are not initialized. */
if (curr_rtl_loc == -1)
return;
-#ifdef USE_MAPPED_LOCATION
if (location == last_location)
return;
-#else
- if (location.file && last_location.file
- && !strcmp (location.file, last_location.file)
- && location.line == last_location.line)
- return;
-#endif
curr_location = location;
}
@@ -321,12 +309,7 @@ curr_insn_locator (void)
VEC_safe_push (tree, gc, block_locators_blocks, curr_block);
last_block = curr_block;
}
-#ifdef USE_MAPPED_LOCATION
if (last_location != curr_location)
-#else
- if (last_location.file != curr_location.file
- || last_location.line != curr_location.line)
-#endif
{
curr_rtl_loc++;
VEC_safe_push (int, heap, locations_locators_locs, curr_rtl_loc);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 1b9c5057162..c157e08d84b 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1,6 +1,6 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -477,13 +477,8 @@ update_bb_for_insn_chain (rtx begin, rtx end, basic_block bb)
end = NEXT_INSN (end);
for (insn = begin; insn != end; insn = NEXT_INSN (insn))
- {
- if (!BARRIER_P (insn))
- {
- set_block_for_insn (insn, bb);
- df_insn_change_bb (insn);
- }
- }
+ if (!BARRIER_P (insn))
+ df_insn_change_bb (insn, bb);
}
/* Update BLOCK_FOR_INSN of insns in BB to BB,
diff --git a/gcc/common.opt b/gcc/common.opt
index f1927138271..454d00ca453 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -127,7 +127,10 @@ Warn when an inlined function cannot be inlined
Wlarger-than-
Common RejectNegative Joined UInteger Warning
--Wlarger-than-<number> Warn if an object is larger than <number> bytes
+
+Wlarger-than=
+Common RejectNegative Joined UInteger Warning
+-Wlarger-than=<number> Warn if an object is larger than <number> bytes
Wlogical-op
Common Warning Var(warn_logical_op)
@@ -229,10 +232,6 @@ Wunused-variable
Common Var(warn_unused_variable) Warning
Warn when a variable is unused
-Wvolatile-register-var
-Common Var(warn_register_var) Warning
-Warn when a register variable is declared volatile
-
Wcoverage-mismatch
Common RejectNegative Var(warn_coverage_mismatch) Warning
Warn instead of error in case profiles in -fprofile-use do not match
@@ -1138,6 +1137,10 @@ ftree-fre
Common Report Var(flag_tree_fre) Optimization
Enable Full Redundancy Elimination (FRE) on trees
+ftree-loop-distribution
+Common Report Var(flag_tree_loop_distribution)
+Enable loop distribution on trees
+
ftree-loop-im
Common Report Var(flag_tree_loop_im) Init(1) Optimization
Enable loop invariant motion on trees
diff --git a/gcc/config.in b/gcc/config.in
index 49007bd346a..efe4a178eaa 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1466,12 +1466,6 @@
#endif
-/* Define if location_t is fileline integer cookie. */
-#ifndef USED_FOR_TARGET
-#undef USE_MAPPED_LOCATION
-#endif
-
-
/* Define to be the last component of the Windows registry key under which to
look for installation paths. The full key used will be
HKEY_LOCAL_MACHINE/SOFTWARE/Free Software Foundation/{WIN32_REGISTRY_KEY}.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index ea9719a5d6e..c66b51ec328 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -12229,9 +12229,20 @@ thumb_set_frame_pointer (arm_stack_offsets *offsets)
else
{
emit_insn (gen_movsi (hard_frame_pointer_rtx, GEN_INT (amount)));
- insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
- hard_frame_pointer_rtx,
- stack_pointer_rtx));
+ /* Thumb-2 RTL patterns expect sp as the first input. Thumb-1
+ expects the first two operands to be the same. */
+ if (TARGET_THUMB2)
+ {
+ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
+ stack_pointer_rtx,
+ hard_frame_pointer_rtx));
+ }
+ else
+ {
+ insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
+ hard_frame_pointer_rtx,
+ stack_pointer_rtx));
+ }
dwarf = gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
plus_constant (stack_pointer_rtx, amount));
RTX_FRAME_RELATED_P (dwarf) = 1;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 2b83335caaf..fcb90ab3ca6 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1106,6 +1106,7 @@ enum reg_class
CC_REG,
VFPCC_REG,
GENERAL_REGS,
+ CORE_REGS,
ALL_REGS,
LIM_REG_CLASSES
};
@@ -1131,6 +1132,7 @@ enum reg_class
"CC_REG", \
"VFPCC_REG", \
"GENERAL_REGS", \
+ "CORE_REGS", \
"ALL_REGS", \
}
@@ -1151,10 +1153,11 @@ enum reg_class
{ 0x000000FF, 0x00000000, 0x00000000, 0x00000000 }, /* LO_REGS */ \
{ 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \
{ 0x000020FF, 0x00000000, 0x00000000, 0x00000000 }, /* BASE_REGS */ \
- { 0x0000FF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \
+ { 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \
{ 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */ \
- { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
+ { 0x0200DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
+ { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \
{ 0xFAFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \
}
@@ -1187,13 +1190,13 @@ enum reg_class
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS)
-#define BASE_REG_CLASS (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS)
+#define BASE_REG_CLASS (TARGET_THUMB1 ? LO_REGS : CORE_REGS)
/* For the Thumb the high registers cannot be used as base registers
when addressing quantities in QI or HI mode; if we don't know the
mode, then we must be conservative. */
#define MODE_BASE_REG_CLASS(MODE) \
- (TARGET_32BIT ? GENERAL_REGS : \
+ (TARGET_32BIT ? CORE_REGS : \
(((MODE) == SImode) ? BASE_REGS : LO_REGS))
/* For Thumb we can not support SP+reg addressing, so we return LO_REGS
@@ -1213,7 +1216,8 @@ enum reg_class
#define PREFERRED_RELOAD_CLASS(X, CLASS) \
(TARGET_ARM ? (CLASS) : \
((CLASS) == GENERAL_REGS || (CLASS) == HI_REGS \
- || (CLASS) == NO_REGS ? LO_REGS : (CLASS)))
+ || (CLASS) == NO_REGS || (CLASS) == STACK_REG \
+ ? LO_REGS : (CLASS)))
/* Must leave BASE_REGS reloads alone */
#define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
@@ -1908,12 +1912,13 @@ typedef struct
/* Nonzero if X can be the base register in a reg+reg addressing mode.
For Thumb, we can not use SP + reg, so reject SP. */
#define REGNO_MODE_OK_FOR_REG_BASE_P(X, MODE) \
- REGNO_OK_FOR_INDEX_P (X)
+ REGNO_MODE_OK_FOR_BASE_P (X, QImode)
/* For ARM code, we don't care about the mode, but for Thumb, the index
must be suitable for use in a QImode load. */
#define REGNO_OK_FOR_INDEX_P(REGNO) \
- REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
+ (REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode) \
+ && !TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM))
/* Maximum number of registers that can appear in a valid memory address.
Shifts in addresses can't be by a register. */
@@ -2051,6 +2056,13 @@ typedef struct
|| REGNO (X) == FRAME_POINTER_REGNUM \
|| REGNO (X) == ARG_POINTER_REGNUM)
+#define ARM_REG_OK_FOR_INDEX_P(X) \
+ ((REGNO (X) <= LAST_ARM_REGNUM \
+ && REGNO (X) != STACK_POINTER_REGNUM) \
+ || REGNO (X) >= FIRST_PSEUDO_REGISTER \
+ || REGNO (X) == FRAME_POINTER_REGNUM \
+ || REGNO (X) == ARG_POINTER_REGNUM)
+
#define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE) \
(REGNO (X) <= LAST_LO_REGNUM \
|| REGNO (X) >= FIRST_PSEUDO_REGISTER \
@@ -2066,6 +2078,9 @@ typedef struct
#define ARM_REG_OK_FOR_BASE_P(X) \
ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
+#define ARM_REG_OK_FOR_INDEX_P(X) \
+ ARM_REGNO_OK_FOR_INDEX_P (REGNO (X))
+
#define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE) \
THUMB1_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
@@ -2080,8 +2095,6 @@ typedef struct
? THUMB1_REG_MODE_OK_FOR_BASE_P (X, MODE) \
: ARM_REG_OK_FOR_BASE_P (X))
-#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X)
-
/* For 16-bit Thumb, a valid index register is anything that can be used in
a byte load instruction. */
#define THUMB1_REG_OK_FOR_INDEX_P(X) \
@@ -2479,10 +2492,12 @@ extern int making_const_table;
rtx base = XEXP (X, 0); \
rtx index = XEXP (X, 1); \
HOST_WIDE_INT offset = 0; \
- if (GET_CODE (base) != REG) \
+ if (GET_CODE (base) != REG \
+ || (GET_CODE (index) == REG && REGNO (index) == SP_REGNUM)) \
{ \
/* Ensure that BASE is a register. */ \
/* (one of them must be). */ \
+ /* Also ensure the SP is not used as in index register. */ \
rtx temp = base; \
base = index; \
index = temp; \
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 04ca8ac37f5..765b89bb84c 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -517,12 +517,14 @@
)
(define_insn_and_split "*arm_addsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
- (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
+ [(set (match_operand:SI 0 "s_register_operand" "=r, !k,r, !k,r")
+ (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,!k,rk,!k,rk")
+ (match_operand:SI 2 "reg_or_int_operand" "rI, rI,L, L,?n")))]
"TARGET_32BIT"
"@
add%?\\t%0, %1, %2
+ add%?\\t%0, %1, %2
+ sub%?\\t%0, %1, #%n2
sub%?\\t%0, %1, #%n2
#"
"TARGET_32BIT &&
@@ -536,7 +538,7 @@
operands[1], 0);
DONE;
"
- [(set_attr "length" "4,4,16")
+ [(set_attr "length" "4,4,4,4,16")
(set_attr "predicable" "yes")]
)
@@ -545,9 +547,9 @@
;; so never allow those alternatives to match if reloading is needed.
(define_insn "*thumb1_addsi3"
- [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
+ [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,!k")
(plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
- (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
+ (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O")))]
"TARGET_THUMB1"
"*
static const char * const asms[] =
@@ -991,12 +993,13 @@
; ??? Check Thumb-2 split length
(define_insn_and_split "*arm_subsi3_insn"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
- (match_operand:SI 2 "s_register_operand" "r,r")))]
+ [(set (match_operand:SI 0 "s_register_operand" "=r,rk,r")
+ (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,!k,?n")
+ (match_operand:SI 2 "s_register_operand" "r, r, r")))]
"TARGET_32BIT"
"@
rsb%?\\t%0, %2, %1
+ sub%?\\t%0, %1, %2
#"
"TARGET_32BIT
&& GET_CODE (operands[1]) == CONST_INT
@@ -1007,7 +1010,7 @@
INTVAL (operands[1]), operands[0], operands[2], 0);
DONE;
"
- [(set_attr "length" "4,16")
+ [(set_attr "length" "4,4,16")
(set_attr "predicable" "yes")]
)
@@ -4786,22 +4789,23 @@
)
(define_insn "*arm_movsi_insn"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r, m")
- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
+ (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk"))]
"TARGET_ARM && ! TARGET_IWMMXT
&& !(TARGET_HARD_FLOAT && TARGET_VFP)
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
mov%?\\t%0, %1
+ mov%?\\t%0, %1
mvn%?\\t%0, #%B1
movw%?\\t%0, %1
ldr%?\\t%0, %1
str%?\\t%1, %0"
- [(set_attr "type" "*,*,*,load1,store1")
+ [(set_attr "type" "*,*,*,*,load1,store1")
(set_attr "predicable" "yes")
- (set_attr "pool_range" "*,*,*,4096,*")
- (set_attr "neg_pool_range" "*,*,*,4084,*")]
+ (set_attr "pool_range" "*,*,*,*,4096,*")
+ (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
)
(define_split
@@ -4819,8 +4823,8 @@
)
(define_insn "*thumb1_movsi_insn"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
- (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lhk")
+ (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lhk"))]
"TARGET_THUMB1
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
@@ -10181,13 +10185,13 @@
; reversed, check that the memory references aren't volatile.
(define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "=rk")
(match_operand:SI 4 "memory_operand" "m"))
- (set (match_operand:SI 1 "s_register_operand" "=r")
+ (set (match_operand:SI 1 "s_register_operand" "=rk")
(match_operand:SI 5 "memory_operand" "m"))
- (set (match_operand:SI 2 "s_register_operand" "=r")
+ (set (match_operand:SI 2 "s_register_operand" "=rk")
(match_operand:SI 6 "memory_operand" "m"))
- (set (match_operand:SI 3 "s_register_operand" "=r")
+ (set (match_operand:SI 3 "s_register_operand" "=rk")
(match_operand:SI 7 "memory_operand" "m"))]
"TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
"*
@@ -10196,11 +10200,11 @@
)
(define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "=rk")
(match_operand:SI 3 "memory_operand" "m"))
- (set (match_operand:SI 1 "s_register_operand" "=r")
+ (set (match_operand:SI 1 "s_register_operand" "=rk")
(match_operand:SI 4 "memory_operand" "m"))
- (set (match_operand:SI 2 "s_register_operand" "=r")
+ (set (match_operand:SI 2 "s_register_operand" "=rk")
(match_operand:SI 5 "memory_operand" "m"))]
"TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
"*
@@ -10209,9 +10213,9 @@
)
(define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "=rk")
(match_operand:SI 2 "memory_operand" "m"))
- (set (match_operand:SI 1 "s_register_operand" "=r")
+ (set (match_operand:SI 1 "s_register_operand" "=rk")
(match_operand:SI 3 "memory_operand" "m"))]
"TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
"*
@@ -10221,13 +10225,13 @@
(define_peephole
[(set (match_operand:SI 4 "memory_operand" "=m")
- (match_operand:SI 0 "s_register_operand" "r"))
+ (match_operand:SI 0 "s_register_operand" "rk"))
(set (match_operand:SI 5 "memory_operand" "=m")
- (match_operand:SI 1 "s_register_operand" "r"))
+ (match_operand:SI 1 "s_register_operand" "rk"))
(set (match_operand:SI 6 "memory_operand" "=m")
- (match_operand:SI 2 "s_register_operand" "r"))
+ (match_operand:SI 2 "s_register_operand" "rk"))
(set (match_operand:SI 7 "memory_operand" "=m")
- (match_operand:SI 3 "s_register_operand" "r"))]
+ (match_operand:SI 3 "s_register_operand" "rk"))]
"TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
"*
return emit_stm_seq (operands, 4);
@@ -10236,11 +10240,11 @@
(define_peephole
[(set (match_operand:SI 3 "memory_operand" "=m")
- (match_operand:SI 0 "s_register_operand" "r"))
+ (match_operand:SI 0 "s_register_operand" "rk"))
(set (match_operand:SI 4 "memory_operand" "=m")
- (match_operand:SI 1 "s_register_operand" "r"))
+ (match_operand:SI 1 "s_register_operand" "rk"))
(set (match_operand:SI 5 "memory_operand" "=m")
- (match_operand:SI 2 "s_register_operand" "r"))]
+ (match_operand:SI 2 "s_register_operand" "rk"))]
"TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
"*
return emit_stm_seq (operands, 3);
@@ -10249,9 +10253,9 @@
(define_peephole
[(set (match_operand:SI 2 "memory_operand" "=m")
- (match_operand:SI 0 "s_register_operand" "r"))
+ (match_operand:SI 0 "s_register_operand" "rk"))
(set (match_operand:SI 3 "memory_operand" "=m")
- (match_operand:SI 1 "s_register_operand" "r"))]
+ (match_operand:SI 1 "s_register_operand" "rk"))]
"TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
"*
return emit_stm_seq (operands, 2);
@@ -10610,8 +10614,8 @@
(define_insn "stack_tie"
[(set (mem:BLK (scratch))
- (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "s_register_operand" "r")]
+ (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
+ (match_operand:SI 1 "s_register_operand" "rk")]
UNSPEC_PRLG_STK))]
""
""
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index b336e0df4f8..0f441ad181c 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -20,8 +20,8 @@
;; The following register constraints have been used:
;; - in ARM/Thumb-2 state: f, t, v, w, x, y, z
-;; - in Thumb state: h, k, b
-;; - in both states: l, c
+;; - in Thumb state: h, b
+;; - in both states: l, c, k
;; In ARM state, 'l' is an alias for 'r'
;; The following normal constraints have been used:
@@ -65,9 +65,8 @@
(define_register_constraint "h" "TARGET_THUMB ? HI_REGS : NO_REGS"
"In Thumb state the core registers @code{r8}-@code{r15}.")
-(define_register_constraint "k" "TARGET_THUMB ? STACK_REG : NO_REGS"
- "@internal
- Thumb only. The stack register.")
+(define_register_constraint "k" "STACK_REG"
+ "@internal The stack register.")
(define_register_constraint "b" "TARGET_THUMB ? BASE_REGS : NO_REGS"
"@internal
diff --git a/gcc/config/arm/ieee754-df.S b/gcc/config/arm/ieee754-df.S
index a0370ad20eb..ebf7e58dabb 100644
--- a/gcc/config/arm/ieee754-df.S
+++ b/gcc/config/arm/ieee754-df.S
@@ -840,7 +840,7 @@ LSYM(Lml_d):
orr xh, xh, r6
teq r5, #0
do_it ne
- movne pc, lr
+ RETc(ne)
2: and r6, yh, #0x80000000
3: movs yl, yl, lsl #1
adc yh, yh, yh
@@ -849,7 +849,7 @@ LSYM(Lml_d):
subeq r5, r5, #1
beq 3b
orr yh, yh, r6
- mov pc, lr
+ RET
LSYM(Lml_s):
@ Isolate the INF and NAN cases away
diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index 11188732bc7..633aaaa875f 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -105,8 +105,8 @@
)
(define_insn "*iwmmxt_movsi_insn"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r,?z,Uy,z")
- (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,z,Uy,z,z"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk, m,z,r,?z,Uy,z")
+ (match_operand:SI 1 "general_operand" "rk, I,K,mi,rk,r,z,Uy,z, z"))]
"TARGET_REALLY_IWMMXT
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
@@ -114,19 +114,20 @@
switch (which_alternative)
{
case 0: return \"mov\\t%0, %1\";
- case 1: return \"mvn\\t%0, #%B1\";
- case 2: return \"ldr\\t%0, %1\";
- case 3: return \"str\\t%1, %0\";
- case 4: return \"tmcr\\t%0, %1\";
- case 5: return \"tmrc\\t%0, %1\";
- case 6: return arm_output_load_gr (operands);
- case 7: return \"wstrw\\t%1, %0\";
+ case 1: return \"mov\\t%0, %1\";
+ case 2: return \"mvn\\t%0, #%B1\";
+ case 3: return \"ldr\\t%0, %1\";
+ case 4: return \"str\\t%1, %0\";
+ case 5: return \"tmcr\\t%0, %1\";
+ case 6: return \"tmrc\\t%0, %1\";
+ case 7: return arm_output_load_gr (operands);
+ case 8: return \"wstrw\\t%1, %0\";
default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\";
}"
- [(set_attr "type" "*,*,load1,store1,*,*,load1,store1,*")
- (set_attr "length" "*,*,*, *,*,*, 16, *,8")
- (set_attr "pool_range" "*,*,4096, *,*,*,1024, *,*")
- (set_attr "neg_pool_range" "*,*,4084, *,*,*, *, 1012,*")
+ [(set_attr "type" "*,*,*,load1,store1,*,*,load1,store1,*")
+ (set_attr "length" "*,*,*,*, *,*,*, 16, *,8")
+ (set_attr "pool_range" "*,*,*,4096, *,*,*,1024, *,*")
+ (set_attr "neg_pool_range" "*,*,*,4084, *,*,*, *, 1012,*")
;; Note - the "predicable" attribute is not allowed to have alternatives.
;; Since the wSTRw wCx instruction is not predicable, we cannot support
;; predicating any of the alternatives in this template. Instead,
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index c7ce4a0f010..0efe31f0f6d 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -224,22 +224,23 @@
)
(define_insn "*thumb2_movsi_insn"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r, m")
- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
+ (match_operand:SI 1 "general_operand" "rk ,I,K,N,mi,rk"))]
"TARGET_THUMB2 && ! TARGET_IWMMXT
&& !(TARGET_HARD_FLOAT && TARGET_VFP)
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
mov%?\\t%0, %1
+ mov%?\\t%0, %1
mvn%?\\t%0, #%B1
movw%?\\t%0, %1
ldr%?\\t%0, %1
str%?\\t%1, %0"
- [(set_attr "type" "*,*,*,load1,store1")
+ [(set_attr "type" "*,*,*,*,load1,store1")
(set_attr "predicable" "yes")
- (set_attr "pool_range" "*,*,*,4096,*")
- (set_attr "neg_pool_range" "*,*,*,0,*")]
+ (set_attr "pool_range" "*,*,*,*,4096,*")
+ (set_attr "neg_pool_range" "*,*,*,*,0,*")]
)
;; ??? We can probably do better with thumb2
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 39f0a228e46..23aa202778f 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -120,77 +120,77 @@
;; ??? For now do not allow loading constants into vfp regs. This causes
;; problems because small constants get converted into adds.
(define_insn "*arm_movsi_vfp"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r ,m,*t,r,*t,*t, *Uv")
- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r,r,*t,*t,*Uvi,*t"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
+ (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
"TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
&& ( s_register_operand (operands[0], SImode)
|| s_register_operand (operands[1], SImode))"
"*
switch (which_alternative)
{
- case 0:
+ case 0: case 1:
return \"mov%?\\t%0, %1\";
- case 1:
- return \"mvn%?\\t%0, #%B1\";
case 2:
- return \"movw%?\\t%0, %1\";
+ return \"mvn%?\\t%0, #%B1\";
case 3:
- return \"ldr%?\\t%0, %1\";
+ return \"movw%?\\t%0, %1\";
case 4:
- return \"str%?\\t%1, %0\";
+ return \"ldr%?\\t%0, %1\";
case 5:
- return \"fmsr%?\\t%0, %1\\t%@ int\";
+ return \"str%?\\t%1, %0\";
case 6:
- return \"fmrs%?\\t%0, %1\\t%@ int\";
+ return \"fmsr%?\\t%0, %1\\t%@ int\";
case 7:
+ return \"fmrs%?\\t%0, %1\\t%@ int\";
+ case 8:
return \"fcpys%?\\t%0, %1\\t%@ int\";
- case 8: case 9:
+ case 9: case 10:
return output_move_vfp (operands);
default:
gcc_unreachable ();
}
"
[(set_attr "predicable" "yes")
- (set_attr "type" "*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
- (set_attr "pool_range" "*,*,*,4096,*,*,*,*,1020,*")
- (set_attr "neg_pool_range" "*,*,*,4084,*,*,*,*,1008,*")]
+ (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
+ (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
+ (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
)
(define_insn "*thumb2_movsi_vfp"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*t,r,*t,*t, *Uv")
- (match_operand:SI 1 "general_operand" "rI,K,N,mi,r,r,*t,*t,*Uvi,*t"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
+ (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
"TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
&& ( s_register_operand (operands[0], SImode)
|| s_register_operand (operands[1], SImode))"
"*
switch (which_alternative)
{
- case 0:
+ case 0: case 1:
return \"mov%?\\t%0, %1\";
- case 1:
- return \"mvn%?\\t%0, #%B1\";
case 2:
- return \"movw%?\\t%0, %1\";
+ return \"mvn%?\\t%0, #%B1\";
case 3:
- return \"ldr%?\\t%0, %1\";
+ return \"movw%?\\t%0, %1\";
case 4:
- return \"str%?\\t%1, %0\";
+ return \"ldr%?\\t%0, %1\";
case 5:
- return \"fmsr%?\\t%0, %1\\t%@ int\";
+ return \"str%?\\t%1, %0\";
case 6:
- return \"fmrs%?\\t%0, %1\\t%@ int\";
+ return \"fmsr%?\\t%0, %1\\t%@ int\";
case 7:
+ return \"fmrs%?\\t%0, %1\\t%@ int\";
+ case 8:
return \"fcpys%?\\t%0, %1\\t%@ int\";
- case 8: case 9:
+ case 9: case 10:
return output_move_vfp (operands);
default:
gcc_unreachable ();
}
"
[(set_attr "predicable" "yes")
- (set_attr "type" "*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
- (set_attr "pool_range" "*,*,*,4096,*,*,*,*,1020,*")
- (set_attr "neg_pool_range" "*,*,*, 0,*,*,*,*,1008,*")]
+ (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
+ (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
+ (set_attr "neg_pool_range" "*,*,*,*, 0,*,*,*,*,1008,*")]
)
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 13aa021f4c6..6c2de252fe3 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -1748,18 +1748,13 @@ darwin_patch_builtin (int fncode)
return;
sym = DECL_ASSEMBLER_NAME (fn);
- newname = alloca (IDENTIFIER_LENGTH (sym) + 10);
- strcpy (newname, "_");
- strcat (newname, IDENTIFIER_POINTER (sym));
- strcat (newname, "$LDBL128");
+ newname = ACONCAT (("_", IDENTIFIER_POINTER (sym), "$LDBL128", NULL));
+
set_user_assembler_name (fn, newname);
- /*sym = get_identifier (newname);
- SET_DECL_ASSEMBLER_NAME (fn, sym);*/
fn = implicit_built_in_decls[fncode];
if (fn)
set_user_assembler_name (fn, newname);
- /*SET_DECL_ASSEMBLER_NAME (fn, sym);*/
}
void
@@ -1769,11 +1764,11 @@ darwin_patch_builtins (void)
return;
#define PATCH_BUILTIN(fncode) darwin_patch_builtin (fncode);
-#define PATCH_BUILTIN_NO64(fncode) \
- if (!TARGET_64BIT) \
+#define PATCH_BUILTIN_NO64(fncode) \
+ if (!TARGET_64BIT) \
darwin_patch_builtin (fncode);
-#define PATCH_BUILTIN_VARIADIC(fncode) \
- if (!TARGET_64BIT \
+#define PATCH_BUILTIN_VARIADIC(fncode) \
+ if (!TARGET_64BIT \
&& (strverscmp (darwin_macosx_version_min, "10.3.9") >= 0)) \
darwin_patch_builtin (fncode);
#include "darwin-ppc-ldouble-patch.def"
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index d4c7ce515e4..c2685a893f6 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -892,8 +892,9 @@ enum machopic_addr_class {
#define DARWIN_REGISTER_TARGET_PRAGMAS() \
do { \
- cpp_register_pragma (parse_in, NULL, "mark", \
- darwin_pragma_ignore, false); \
+ if (!flag_preprocess_only) \
+ cpp_register_pragma (parse_in, NULL, "mark", \
+ darwin_pragma_ignore, false); \
c_register_pragma (0, "options", darwin_pragma_options); \
c_register_pragma (0, "segment", darwin_pragma_ignore); \
c_register_pragma (0, "unused", darwin_pragma_unused); \
diff --git a/gcc/config/mips/iris.h b/gcc/config/mips/iris.h
index 7b1b607de15..312845b3923 100644
--- a/gcc/config/mips/iris.h
+++ b/gcc/config/mips/iris.h
@@ -22,6 +22,9 @@ along with GCC; see the file COPYING3. If not see
#undef TARGET_IRIX
#define TARGET_IRIX 1
+/* MIPS specific debugging info */
+#define MIPS_DEBUGGING_INFO 1
+
/* The size in bytes of a DWARF field indicating an offset or length
relative to a debug info section, specified to be 4 bytes in the DWARF-2
specification. The SGI/MIPS ABI defines it to be the same as PTR_SIZE. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 7d94ebddd56..3bc9dfe36ab 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1078,7 +1078,6 @@ enum mips_code_readable_setting {
#endif
#define DBX_DEBUGGING_INFO 1 /* generate stabs (OSF/rose) */
-#define MIPS_DEBUGGING_INFO 1 /* MIPS specific debugging info */
#define DWARF2_DEBUGGING_INFO 1 /* dwarf2 debugging info */
#ifndef PREFERRED_DEBUGGING_TYPE
diff --git a/gcc/config/mips/openbsd.h b/gcc/config/mips/openbsd.h
index dc5c5eb344f..af420f386a3 100644
--- a/gcc/config/mips/openbsd.h
+++ b/gcc/config/mips/openbsd.h
@@ -95,3 +95,6 @@ along with GCC; see the file COPYING3. If not see
/* Switch into a generic section. */
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
+
+/* MIPS specific debugging info */
+#define MIPS_DEBUGGING_INFO 1
diff --git a/gcc/config/mips/sde.h b/gcc/config/mips/sde.h
index 94fd1f58731..beb8d1df7bf 100644
--- a/gcc/config/mips/sde.h
+++ b/gcc/config/mips/sde.h
@@ -72,9 +72,8 @@ along with GCC; see the file COPYING3. If not see
#undef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 0
-/* SDE-MIPS won't ever support SDB or MIPS debugging info. */
+/* SDE-MIPS won't ever support SDB debugging info. */
#undef SDB_DEBUGGING_INFO
-#undef MIPS_DEBUGGING_INFO
/* Describe how we implement __builtin_eh_return. */
diff --git a/gcc/config/mips/vxworks.h b/gcc/config/mips/vxworks.h
index f26b64c931e..16679a0b32b 100644
--- a/gcc/config/mips/vxworks.h
+++ b/gcc/config/mips/vxworks.h
@@ -79,9 +79,6 @@ VXWORKS_LINK_SPEC
#undef MIPS_DEFAULT_GVALUE
#define MIPS_DEFAULT_GVALUE 0
-/* Other formats are already disabled in config/vxworks.h. */
-#undef MIPS_DEBUGGING_INFO
-
/* No _mcount profiling on VxWorks. */
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 9b9fefda2af..30f226bf46e 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -358,7 +358,7 @@ struct processor_costs rios1_cost = {
COSTS_N_INSNS (2), /* dmul */
COSTS_N_INSNS (19), /* sdiv */
COSTS_N_INSNS (19), /* ddiv */
- 128,
+ 128, /* cache line size */
64, /* l1 cache */
512, /* l2 cache */
0, /* streams */
@@ -377,7 +377,7 @@ struct processor_costs rios2_cost = {
COSTS_N_INSNS (2), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (17), /* ddiv */
- 256,
+ 256, /* cache line size */
256, /* l1 cache */
1024, /* l2 cache */
0, /* streams */
@@ -396,7 +396,7 @@ struct processor_costs rs64a_cost = {
COSTS_N_INSNS (4), /* dmul */
COSTS_N_INSNS (31), /* sdiv */
COSTS_N_INSNS (31), /* ddiv */
- 128,
+ 128, /* cache line size */
128, /* l1 cache */
2048, /* l2 cache */
1, /* streams */
@@ -415,7 +415,7 @@ struct processor_costs mpccore_cost = {
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (10), /* sdiv */
COSTS_N_INSNS (17), /* ddiv */
- 32,
+ 32, /* cache line size */
4, /* l1 cache */
16, /* l2 cache */
1, /* streams */
@@ -434,7 +434,7 @@ struct processor_costs ppc403_cost = {
COSTS_N_INSNS (11), /* dmul */
COSTS_N_INSNS (11), /* sdiv */
COSTS_N_INSNS (11), /* ddiv */
- 32,
+ 32, /* cache line size */
4, /* l1 cache */
16, /* l2 cache */
1, /* streams */
@@ -453,7 +453,7 @@ struct processor_costs ppc405_cost = {
COSTS_N_INSNS (11), /* dmul */
COSTS_N_INSNS (11), /* sdiv */
COSTS_N_INSNS (11), /* ddiv */
- 32,
+ 32, /* cache line size */
16, /* l1 cache */
128, /* l2 cache */
1, /* streams */
@@ -472,7 +472,7 @@ struct processor_costs ppc440_cost = {
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (19), /* sdiv */
COSTS_N_INSNS (33), /* ddiv */
- 32,
+ 32, /* cache line size */
32, /* l1 cache */
256, /* l2 cache */
1, /* streams */
@@ -491,7 +491,7 @@ struct processor_costs ppc601_cost = {
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (31), /* ddiv */
- 32,
+ 32, /* cache line size */
32, /* l1 cache */
256, /* l2 cache */
1, /* streams */
@@ -510,7 +510,7 @@ struct processor_costs ppc603_cost = {
COSTS_N_INSNS (4), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (33), /* ddiv */
- 32,
+ 32, /* cache line size */
8, /* l1 cache */
64, /* l2 cache */
1, /* streams */
@@ -529,7 +529,7 @@ struct processor_costs ppc604_cost = {
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (32), /* ddiv */
- 32,
+ 32, /* cache line size */
16, /* l1 cache */
512, /* l2 cache */
1, /* streams */
@@ -548,7 +548,7 @@ struct processor_costs ppc604e_cost = {
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (32), /* ddiv */
- 32,
+ 32, /* cache line size */
32, /* l1 cache */
1024, /* l2 cache */
1, /* streams */
@@ -567,7 +567,7 @@ struct processor_costs ppc620_cost = {
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (32), /* ddiv */
- 128,
+ 128, /* cache line size */
32, /* l1 cache */
1024, /* l2 cache */
1, /* streams */
@@ -586,7 +586,7 @@ struct processor_costs ppc630_cost = {
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (21), /* ddiv */
- 128,
+ 128, /* cache line size */
64, /* l1 cache */
1024, /* l2 cache */
1, /* streams */
@@ -606,7 +606,7 @@ struct processor_costs ppccell_cost = {
COSTS_N_INSNS (10/2), /* dmul */
COSTS_N_INSNS (74/2), /* sdiv */
COSTS_N_INSNS (74/2), /* ddiv */
- 128,
+ 128, /* cache line size */
32, /* l1 cache */
512, /* l2 cache */
6, /* streams */
@@ -625,7 +625,7 @@ struct processor_costs ppc750_cost = {
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (31), /* ddiv */
- 32,
+ 32, /* cache line size */
32, /* l1 cache */
512, /* l2 cache */
1, /* streams */
@@ -644,7 +644,7 @@ struct processor_costs ppc7450_cost = {
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (21), /* sdiv */
COSTS_N_INSNS (35), /* ddiv */
- 32,
+ 32, /* cache line size */
32, /* l1 cache */
1024, /* l2 cache */
1, /* streams */
@@ -663,7 +663,7 @@ struct processor_costs ppc8540_cost = {
COSTS_N_INSNS (4), /* dmul */
COSTS_N_INSNS (29), /* sdiv */
COSTS_N_INSNS (29), /* ddiv */
- 32,
+ 32, /* cache line size */
32, /* l1 cache */
256, /* l2 cache */
1, /* prefetch streams /*/
@@ -683,8 +683,8 @@ struct processor_costs ppce300c2c3_cost = {
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (33), /* ddiv */
32,
- 32, /* l1 cache */
- 256, /* l2 cache */
+ 16, /* l1 cache */
+ 16, /* l2 cache */
1, /* prefetch streams /*/
};
@@ -701,7 +701,7 @@ struct processor_costs power4_cost = {
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (17), /* ddiv */
- 128,
+ 128, /* cache line size */
32, /* l1 cache */
1024, /* l2 cache */
8, /* prefetch streams /*/
@@ -720,7 +720,7 @@ struct processor_costs power6_cost = {
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (13), /* sdiv */
COSTS_N_INSNS (16), /* ddiv */
- 128,
+ 128, /* cache line size */
64, /* l1 cache */
2048, /* l2 cache */
16, /* prefetch streams */
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index dccbc1ea350..f2a0ba94bcc 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -256,6 +256,7 @@ static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
static int sh_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+static bool sh_scalar_mode_supported_p (enum machine_mode);
static int sh_dwarf_calling_convention (const_tree);
@@ -431,6 +432,8 @@ static int sh_dwarf_calling_convention (const_tree);
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR sh_gimplify_va_arg_expr
+#undef TARGET_SCALAR_MODE_SUPPORTED_P
+#define TARGET_SCALAR_MODE_SUPPORTED_P sh_scalar_mode_supported_p
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P sh_vector_mode_supported_p
@@ -9201,6 +9204,17 @@ sh_md_finish_global (FILE *dump ATTRIBUTE_UNUSED,
}
}
+/* The scalar modes supported differs from the default version in TImode
+ for 32-bit SHMEDIA. */
+static bool
+sh_scalar_mode_supported_p (enum machine_mode mode)
+{
+ if (TARGET_SHMEDIA32 && mode == TImode)
+ return false;
+
+ return default_scalar_mode_supported_p (mode);
+}
+
/* Cache the can_issue_more so that we can return it from reorder2. Also,
keep count of register pressures on SImode and SFmode. */
static int
@@ -10875,8 +10889,10 @@ sh_secondary_reload (bool in_p, rtx x, enum reg_class class,
return GENERAL_REGS;
if (class == FPUL_REGS && immediate_operand (x, mode))
{
- if (satisfies_constraint_I08 (x))
+ if (satisfies_constraint_I08 (x) || fp_zero_operand (x))
return GENERAL_REGS;
+ else if (mode == SFmode)
+ return FP_REGS;
sri->icode = CODE_FOR_reload_insi__i_fpul;
return NO_REGS;
}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 844ea23c633..7a1547932e5 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -623,12 +623,6 @@ do { \
} \
TARGET_CBRANCHDI4 = 0; \
} \
- /* -fprofile-arcs needs a working libgcov . In unified tree \
- configurations with newlib, this requires to configure with \
- --with-newlib --with-headers. But there is no way to check \
- here we have a working libgcov, so just assume that we have. */\
- if (profile_flag) \
- warning (0, "profiling is still experimental for this target");\
} \
else \
{ \
diff --git a/gcc/configure.ac b/gcc/configure.ac
index a24f1ac20ee..1509c009caa 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -729,15 +729,6 @@ fi
AC_SUBST(valgrind_path_defines)
AC_SUBST(valgrind_command)
-AC_ARG_ENABLE(mapped-location,
-[ --enable-mapped-location location_t is fileline integer cookie],,
-enable_mapped_location=yes)
-
-if test "$enable_mapped_location" = yes ; then
- AC_DEFINE(USE_MAPPED_LOCATION, 1,
-[Define if location_t is fileline integer cookie.])
-fi
-
# Enable code coverage collection
AC_ARG_ENABLE(coverage,
[ --enable-coverage[=LEVEL]
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index aa4bf07f4ea..3c79d1dd910 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,99 @@
+2008-03-02 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 24924
+ * class.c (finish_struct_anon): Use permerror instead of pedwarn.
+ (check_field_decls): Likewise.
+ (note_name_declared_in_class): Likewise.
+ * call.c (build_new_op): Likewise.
+ (convert_like_real): Likewise.
+ (build_over_call): Likewise.
+ * lex.c (unqualified_fn_lookup_error): Likewise.
+ * parser.c (cp_parser_template_id): Likewise.
+ * cvt.c (warn_ref_binding): Likewise.
+ (convert_to_reference): Likewise.
+ (ocp_convert): Likewise.
+ (convert_to_void): Use error instead of pedwarn.
+ * error.c (cp_cpp_error): Use pedantic_warning_kind.
+ * decl.c (compute_array_index_type): Use constant_expression_error.
+
+2008-03-01 Douglas Gregor <doug.gregor@gmail.com>
+
+ * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Note
+ that auto is either a storage class or a simple type specifier,
+ depending on the dialect.
+ (cp_parser_decl_specifier_seq): Complain about `auto' as a storage
+ specifier in C++98 mode, error in C++0x mode (since we don't
+ support auto as a type specifier, yet).
+ (cp_parser_storage_class_specifier_opt): Don't treat `auto' as a
+ storage specifier in C++0x mode.
+ (cp_parser_simple_type_specifier): Parse `auto' as a
+ simple-type-specifier, but error because we don't support it yet.
+
+2008-02-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * parser.c (cp_parser_nonclass_name): New.
+ (cp_parser_pseudo_destructor_name): Use it instead of
+ cp_parser_type_name.
+ (cp_parser_type_name): Move code to cp_parser_nonclass_name.
+
+2008-02-29 Tom Tromey <tromey@redhat.com>
+
+ * parser.c (struct cp_token) <input_file_stack_index>: Remove.
+ (cp_lexer_get_preprocessor_token): Update.
+ (cp_lexer_set_source_position_from_token): Don't call
+ restore_input_file_stack.
+ * lex.c (cxx_init): Don't use push_srcloc or pop_srcloc.
+
+2008-02-28 Richard Guenther <rguenther@suse.de>
+
+ Revert:
+ 2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (duplicate_decls): Remove decl from global mapping
+ before ggc_freeing it.
+
+2008-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35368
+ * rtti.c: Include c-pragma.h.
+ (push_abi_namespace, pop_abi_namespace): New functions.
+ (build_dynamic_cast_1, tinfo_base_init, get_pseudo_ti_index,
+ create_tinfo_types, emit_support_tinfos): Use them.
+ * Make-lang.in (cp/rtti.o): Depend on $(C_PRAGMA_H).
+
+2008-02-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/35315
+ * decl.c (grokdeclarator): Allow a typedef of an unnamed struct
+ to name the struct for linkage purposes even if it has attributes.
+ (start_decl): In that case, set ATTR_FLAG_TYPE_IN_PLACE.
+
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * parser.c (eof_token): Remove old location code.
+ (check_empty_body): Remove test of USE_MAPPED_LOCATION.
+ * decl2.c (generate_ctor_or_dtor_function): Remove old location
+ code.
+ (cp_write_global_declarations): Likewise.
+ * lex.c (cxx_init): Remove old location code.
+ (handle_pragma_implementation): Remove test of
+ USE_MAPPED_LOCATION.
+ * pt.c (tsubst): Remove old location code.
+ * error.c (cp_print_error_function): Remove test of
+ USE_MAPPED_LOCATION.
+ * decl.c (pop_label): Remove old location code.
+ (finish_function): Likewise.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 26264
+ * call.c (magic_varargs_p): Remove BUILT_IN_STDARG_START.
+
+2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (duplicate_decls): Remove decl from global mapping
+ before ggc_freeing it.
+
2008-02-26 Paolo Carlini <pcarlini@suse.de>
PR c++/35323
@@ -155,7 +251,7 @@
2008-02-12 Jason Merrill <jason@redhat.com>
PR c++/34824
- * call.c (convert_like_real): Pass LOOKUP_ONLYCONVERTING to build_temp
+ * call.c (convert_like_real): Pass LOOKUP_NO_CONVERSION to build_temp
if we're doing conversions to call a user-defined conversion function.
2008-02-12 Steven Bosscher <steven@gcc.gnu.org>
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index d2a69f40384..6207ed13dd6 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -264,7 +264,7 @@ cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \
$(TARGET_H) debug.h $(TREE_FLOW_H)
cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H)
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h convert.h \
- $(TARGET_H) gt-cp-rtti.h
+ $(TARGET_H) $(C_PRAGMA_H) gt-cp-rtti.h
cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) except.h \
toplev.h cp/cfns.h $(EXPR_H) libfuncs.h $(TREE_INLINE_H) $(TARGET_H)
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) $(FLAGS_H) $(EXPR_H) \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 71ac85973d9..2ee82371f68 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3857,10 +3857,10 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
/* Look for an `operator++ (int)'. If they didn't have
one, then we fall back to the old way of doing things. */
if (flags & LOOKUP_COMPLAIN)
- pedwarn ("no %<%D(int)%> declared for postfix %qs, "
- "trying prefix operator instead",
- fnname,
- operator_name_info[code].name);
+ permerror ("no %<%D(int)%> declared for postfix %qs, "
+ "trying prefix operator instead",
+ fnname,
+ operator_name_info[code].name);
if (code == POSTINCREMENT_EXPR)
code = PREINCREMENT_EXPR;
else
@@ -4343,9 +4343,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
else if (t->kind == ck_identity)
break;
}
- pedwarn ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
+ permerror ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
if (fn)
- pedwarn (" initializing argument %P of %qD", argnum, fn);
+ permerror (" initializing argument %P of %qD", argnum, fn);
return cp_convert (totype, expr);
}
@@ -4826,7 +4826,6 @@ magic_varargs_p (tree fn)
case BUILT_IN_CLASSIFY_TYPE:
case BUILT_IN_CONSTANT_P:
case BUILT_IN_NEXT_ARG:
- case BUILT_IN_STDARG_START:
case BUILT_IN_VA_START:
return true;
@@ -4956,7 +4955,7 @@ build_over_call (struct z_candidate *cand, int flags)
tree base_binfo;
if (convs[i]->bad_p)
- pedwarn ("passing %qT as %<this%> argument of %q#D discards qualifiers",
+ permerror ("passing %qT as %<this%> argument of %q#D discards qualifiers",
TREE_TYPE (argtype), fn);
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 1a76816c229..500ddaac635 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2493,27 +2493,27 @@ finish_struct_anon (tree t)
if (TREE_CODE (elt) != FIELD_DECL)
{
if (is_union)
- pedwarn ("%q+#D invalid; an anonymous union can "
- "only have non-static data members", elt);
+ permerror ("%q+#D invalid; an anonymous union can "
+ "only have non-static data members", elt);
else
- pedwarn ("%q+#D invalid; an anonymous struct can "
- "only have non-static data members", elt);
+ permerror ("%q+#D invalid; an anonymous struct can "
+ "only have non-static data members", elt);
continue;
}
if (TREE_PRIVATE (elt))
{
if (is_union)
- pedwarn ("private member %q+#D in anonymous union", elt);
+ permerror ("private member %q+#D in anonymous union", elt);
else
- pedwarn ("private member %q+#D in anonymous struct", elt);
+ permerror ("private member %q+#D in anonymous struct", elt);
}
else if (TREE_PROTECTED (elt))
{
if (is_union)
- pedwarn ("protected member %q+#D in anonymous union", elt);
+ permerror ("protected member %q+#D in anonymous union", elt);
else
- pedwarn ("protected member %q+#D in anonymous struct", elt);
+ permerror ("protected member %q+#D in anonymous struct", elt);
}
TREE_PRIVATE (elt) = TREE_PRIVATE (field);
@@ -3044,7 +3044,7 @@ check_field_decls (tree t, tree *access_decls,
user-defined constructor. */
if (constructor_name_p (DECL_NAME (x), t)
&& TYPE_HAS_USER_CONSTRUCTOR (t))
- pedwarn ("field %q+#D with same name as class", x);
+ permerror ("field %q+#D with same name as class", x);
/* We set DECL_C_BIT_FIELD in grokbitfield.
If the type and width are valid, we'll also set DECL_BIT_FIELD. */
@@ -6072,10 +6072,10 @@ resolve_address_of_overloaded_function (tree target_type,
if (!(flags & tf_error))
return error_mark_node;
- pedwarn ("assuming pointer to member %qD", fn);
+ permerror ("assuming pointer to member %qD", fn);
if (!explained)
{
- pedwarn ("(a pointer to member can only be formed with %<&%E%>)", fn);
+ inform ("(a pointer to member can only be formed with %<&%E%>)", fn);
explained = 1;
}
}
@@ -6435,8 +6435,8 @@ note_name_declared_in_class (tree name, tree decl)
A name N used in a class S shall refer to the same declaration
in its context and when re-evaluated in the completed scope of
S. */
- pedwarn ("declaration of %q#D", decl);
- pedwarn ("changes meaning of %qD from %q+#D",
+ permerror ("declaration of %q#D", decl);
+ permerror ("changes meaning of %qD from %q+#D",
DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
}
}
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index a75036f53c1..ee5759d6b4f 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -379,7 +379,7 @@ warn_ref_binding (tree reftype, tree intype, tree decl)
msg = "conversion to non-const reference type %q#T from"
" rvalue of type %qT";
- pedwarn (msg, reftype, intype);
+ permerror (msg, reftype, intype);
}
}
@@ -449,8 +449,8 @@ convert_to_reference (tree reftype, tree expr, int convtype,
if (! (convtype & CONV_CONST)
&& !at_least_as_qualified_p (ttl, ttr))
- pedwarn ("conversion from %qT to %qT discards qualifiers",
- ttr, reftype);
+ permerror ("conversion from %qT to %qT discards qualifiers",
+ ttr, reftype);
}
return build_up_reference (reftype, expr, flags, decl);
@@ -646,9 +646,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
|| TREE_CODE (intype) == POINTER_TYPE))
{
if (flags & LOOKUP_COMPLAIN)
- pedwarn ("conversion from %q#T to %q#T", intype, type);
+ permerror ("conversion from %q#T to %q#T", intype, type);
- if (flag_pedantic_errors)
+ if (!flag_permissive)
return error_mark_node;
}
if (IS_AGGR_TYPE (intype))
@@ -892,8 +892,8 @@ convert_to_void (tree expr, const char *implicit)
{
/* [over.over] enumerates the places where we can take the address
of an overloaded function, and this is not one of them. */
- pedwarn ("%s cannot resolve address of overloaded function",
- implicit ? implicit : "void cast");
+ error ("%s cannot resolve address of overloaded function",
+ implicit ? implicit : "void cast");
expr = void_zero_node;
}
else if (implicit && probe == expr && is_overloaded_fn (probe))
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 82c55e0ec63..32a0db820ce 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -357,12 +357,7 @@ pop_label (tree label, tree old_value)
location_t location;
error ("label %q+D used but not defined", label);
-#ifdef USE_MAPPED_LOCATION
location = input_location; /* FIXME want (input_filename, (line)0) */
-#else
- location.file = input_filename;
- location.line = 0;
-#endif
/* Avoid crashing later. */
define_label (location, DECL_NAME (label));
}
@@ -3961,6 +3956,7 @@ start_decl (const cp_declarator *declarator,
tree type;
tree context;
bool was_public;
+ int flags;
*pushed_scope_p = NULL_TREE;
@@ -4022,8 +4018,17 @@ start_decl (const cp_declarator *declarator,
TREE_STATIC (decl) = 1;
}
+ /* If this is a typedef that names the class for linkage purposes
+ (7.1.3p8), apply any attributes directly to the type. */
+ if (TREE_CODE (decl) == TYPE_DECL
+ && TAGGED_TYPE_P (TREE_TYPE (decl))
+ && decl == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))))
+ flags = ATTR_FLAG_TYPE_IN_PLACE;
+ else
+ flags = 0;
+
/* Set attributes here so if duplicate decl, will have proper attributes. */
- cplus_decl_attributes (&decl, attributes, 0);
+ cplus_decl_attributes (&decl, attributes, flags);
/* Dllimported symbols cannot be defined. Static data members (which
can be initialized in-class and dllimported) go through grokfield,
@@ -7023,12 +7028,7 @@ compute_array_index_type (tree name, tree size)
{
/* Check to see if the array bound overflowed. Make that an
error, no matter how generous we're being. */
- int old_flag_pedantic_errors = flag_pedantic_errors;
- int old_pedantic = pedantic;
- pedantic = flag_pedantic_errors = 1;
- constant_expression_warning (size);
- pedantic = old_pedantic;
- flag_pedantic_errors = old_flag_pedantic_errors;
+ constant_expression_error (size);
/* An array must have a positive number of elements. */
if (INT_CST_LT (size, integer_zero_node))
@@ -8560,8 +8560,6 @@ grokdeclarator (const cp_declarator *declarator,
&& TYPE_NAME (type)
&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& TYPE_ANONYMOUS_P (type)
- /* Don't do this if there are attributes. */
- && (!attrlist || !*attrlist)
&& cp_type_quals (type) == TYPE_UNQUALIFIED)
{
tree oldname = TYPE_NAME (type);
@@ -11806,14 +11804,10 @@ finish_function (int flags)
/* Hack. We don't want the middle-end to warn that this
return is unreachable, so put the statement on the
special line 0. */
-#ifdef USE_MAPPED_LOCATION
{
location_t linezero = linemap_line_start (line_table, 0, 1);
SET_EXPR_LOCATION (stmt, linezero);
}
-#else
- annotate_with_file_line (stmt, input_filename, 0);
-#endif
}
if (use_eh_spec_block (current_function_decl))
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 695390ce78f..d7e3d766ca7 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1,6 +1,6 @@
/* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
@@ -2995,11 +2995,8 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
size_t i;
input_location = *locus;
-#ifdef USE_MAPPED_LOCATION
/* ??? */
-#else
- locus->line++;
-#endif
+ /* Was: locus->line++; */
/* We use `I' to indicate initialization and `D' to indicate
destruction. */
@@ -3179,13 +3176,7 @@ cp_write_global_declarations (void)
if (pch_file)
c_common_write_pch ();
-#ifdef USE_MAPPED_LOCATION
- /* FIXME - huh? */
-#else
- /* Otherwise, GDB can get confused, because in only knows
- about source for LINENO-1 lines. */
- input_line -= 1;
-#endif
+ /* FIXME - huh? was input_line -= 1;*/
/* We now have to write out all the stuff we put off writing out.
These include:
@@ -3318,11 +3309,7 @@ cp_write_global_declarations (void)
instantiations, etc. */
reconsider = true;
ssdf_count++;
-#ifdef USE_MAPPED_LOCATION
- /* ??? */
-#else
- locus.line++;
-#endif
+ /* ??? was: locus.line++; */
}
/* Go through the set of inline functions whose bodies have not
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 94e43c05f9c..97a17850195 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2436,14 +2436,12 @@ cp_print_error_function (diagnostic_context *context,
pp_base_newline (context->printer);
if (s.file != NULL)
{
-#ifdef USE_MAPPED_LOCATION
if (flag_show_column && s.column != 0)
pp_printf (context->printer,
" inlined from %qs at %s:%d:%d",
cxx_printable_name (fndecl, 2),
s.file, s.line, s.column);
else
-#endif
pp_printf (context->printer,
" inlined from %qs at %s:%d",
cxx_printable_name (fndecl, 2),
@@ -2653,7 +2651,7 @@ cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
dlevel = DK_WARNING;
break;
case CPP_DL_PEDWARN:
- dlevel = pedantic_error_kind ();
+ dlevel = pedantic_warning_kind ();
break;
case CPP_DL_ERROR:
dlevel = DK_ERROR;
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 136260bef49..06c0bc2ffe5 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -1,6 +1,6 @@
/* Separate lexical analyzer for GNU C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@@ -372,6 +372,7 @@ bool statement_code_p[MAX_TREE_CODES];
bool
cxx_init (void)
{
+ location_t saved_loc;
unsigned int i;
static const enum tree_code stmt_codes[] = {
CTOR_INITIALIZER, TRY_BLOCK, HANDLER,
@@ -385,14 +386,8 @@ cxx_init (void)
for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
statement_code_p[stmt_codes[i]] = true;
- /* We cannot just assign to input_filename because it has already
- been initialized and will be used later as an N_BINCL for stabs+
- debugging. */
-#ifdef USE_MAPPED_LOCATION
- push_srcloc (BUILTINS_LOCATION);
-#else
- push_srcloc ("<built-in>", 0);
-#endif
+ saved_loc = input_location;
+ input_location = BUILTINS_LOCATION;
init_reswords ();
init_tree ();
@@ -420,7 +415,7 @@ cxx_init (void)
if (c_common_init () == false)
{
- pop_srcloc();
+ input_location = saved_loc;
return false;
}
@@ -428,7 +423,7 @@ cxx_init (void)
init_repo ();
- pop_srcloc();
+ input_location = saved_loc;
return true;
}
@@ -572,17 +567,9 @@ handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED )
else
{
filename = ggc_strdup (TREE_STRING_POINTER (fname));
-#ifdef USE_MAPPED_LOCATION
- /* We currently cannot give this diagnostic, as we reach this point
- only after cpplib has scanned the entire translation unit, so
- cpp_included always returns true. A plausible fix is to compare
- the current source-location cookie with the first source-location
- cookie (if any) of the filename, but this requires completing the
- --enable-mapped-location project first. See PR 17577. */
if (cpp_included_before (parse_in, filename, input_location))
warning (0, "#pragma implementation for %qs appears after "
"file is included", filename);
-#endif
}
for (; ifiles; ifiles = ifiles->next)
@@ -660,16 +647,16 @@ unqualified_fn_lookup_error (tree name)
Note that we have the exact wording of the following message in
the manual (trouble.texi, node "Name lookup"), so they need to
be kept in synch. */
- pedwarn ("there are no arguments to %qD that depend on a template "
- "parameter, so a declaration of %qD must be available",
- name, name);
+ permerror ("there are no arguments to %qD that depend on a template "
+ "parameter, so a declaration of %qD must be available",
+ name, name);
if (!flag_permissive)
{
static bool hint;
if (!hint)
{
- error ("(if you use %<-fpermissive%>, G++ will accept your "
+ inform ("(if you use %<-fpermissive%>, G++ will accept your "
"code, but allowing the use of an undeclared name is "
"deprecated)");
hint = true;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index cb0059392a7..3ffac730a27 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -79,8 +79,6 @@ typedef struct cp_token GTY (())
KEYWORD is RID_MAX) iff this name was looked up and found to be
ambiguous. An error has already been reported. */
BOOL_BITFIELD ambiguous_p : 1;
- /* The input file stack index at which this token was found. */
- unsigned input_file_stack_index : INPUT_FILE_STACK_BITS;
/* The value associated with this token, if any. */
union cp_token_value {
/* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID. */
@@ -99,12 +97,8 @@ DEF_VEC_ALLOC_P (cp_token_position,heap);
static cp_token eof_token =
{
- CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, 0, false, 0, { NULL },
-#if USE_MAPPED_LOCATION
+ CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, false, 0, { NULL },
0
-#else
- {0, 0}
-#endif
};
/* The cp_lexer structure represents the C++ lexer. It is responsible
@@ -412,7 +406,6 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
token->type
= c_lex_with_flags (&token->u.value, &token->location, &token->flags,
lexer == NULL ? 0 : C_LEX_RAW_STRINGS);
- token->input_file_stack_index = input_file_stack_tick;
token->keyword = RID_MAX;
token->pragma_kind = PRAGMA_NONE;
token->in_system_header = in_system_header;
@@ -494,7 +487,6 @@ cp_lexer_set_source_position_from_token (cp_token *token)
{
input_location = token->location;
in_system_header = token->in_system_header;
- restore_input_file_stack (token->input_file_stack_index);
}
}
@@ -547,8 +539,10 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
token = cp_lexer_peek_token (lexer);
switch (token->keyword)
{
- /* Storage classes. */
+ /* auto specifier: storage-class-specifier in C++,
+ simple-type-specifier in C++0x. */
case RID_AUTO:
+ /* Storage classes. */
case RID_REGISTER:
case RID_STATIC:
case RID_EXTERN:
@@ -1680,6 +1674,8 @@ static tree cp_parser_simple_type_specifier
(cp_parser *, cp_decl_specifier_seq *, cp_parser_flags);
static tree cp_parser_type_name
(cp_parser *);
+static tree cp_parser_nonclass_name
+ (cp_parser* parser);
static tree cp_parser_elaborated_type_specifier
(cp_parser *, bool, bool);
static tree cp_parser_enum_specifier
@@ -5179,8 +5175,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
}
/* Look for the type-name. */
- *scope = TREE_TYPE (cp_parser_type_name (parser));
-
+ *scope = TREE_TYPE (cp_parser_nonclass_name (parser));
if (*scope == error_mark_node)
return;
@@ -5194,7 +5189,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
cp_parser_require (parser, CPP_COMPL, "`~'");
/* Look for the type-name again. We are not responsible for
checking that it matches the first type-name. */
- *type = cp_parser_type_name (parser);
+ *type = cp_parser_nonclass_name (parser);
}
/* Parse a unary-expression.
@@ -7206,10 +7201,7 @@ check_empty_body (cp_parser* parser, const char* type)
semi_loc = expand_location (token->location);
if (close_loc.line == semi_loc.line
-#ifdef USE_MAPPED_LOCATION
- && close_loc.column+1 == semi_loc.column
-#endif
- )
+ && close_loc.column+1 == semi_loc.column)
warning (OPT_Wempty_body,
"suggest a space before %<;%> or explicit braces around empty "
"body in %<%s%> statement",
@@ -8144,13 +8136,33 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
GNU Extension:
thread */
case RID_AUTO:
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ if (cxx_dialect == cxx98)
+ {
+ /* Complain about `auto' as a storage specifier, if
+ we're complaining about C++0x compatibility. */
+ warning
+ (OPT_Wc__0x_compat,
+ "%<auto%> will change meaning in C++0x; please remove it");
+
+ /* Set the storage class anyway. */
+ cp_parser_set_storage_class (parser, decl_specs, RID_AUTO);
+ }
+ else
+ /* We do not yet support the use of `auto' as a
+ type-specifier. */
+ error ("C++0x %<auto%> specifier not supported");
+ break;
+
case RID_REGISTER:
case RID_STATIC:
case RID_EXTERN:
case RID_MUTABLE:
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
- cp_parser_set_storage_class (parser, decl_specs, token->keyword);
+ cp_parser_set_storage_class (parser, decl_specs, token->keyword);
break;
case RID_THREAD:
/* Consume the token. */
@@ -8276,6 +8288,10 @@ cp_parser_storage_class_specifier_opt (cp_parser* parser)
switch (cp_lexer_peek_token (parser->lexer)->keyword)
{
case RID_AUTO:
+ if (cxx_dialect != cxx98)
+ return NULL_TREE;
+ /* Fall through for C++98. */
+
case RID_REGISTER:
case RID_STATIC:
case RID_EXTERN:
@@ -9759,7 +9775,7 @@ cp_parser_template_id (cp_parser *parser,
}
/* Otherwise, emit an error about the invalid digraph, but continue
parsing because we got our argument list. */
- pedwarn ("%<<::%> cannot begin a template-argument list");
+ permerror ("%<<::%> cannot begin a template-argument list");
inform ("%<<:%> is an alternate spelling for %<[%>. Insert whitespace "
"between %<<%> and %<::%>");
if (!flag_permissive)
@@ -10715,6 +10731,7 @@ cp_parser_type_specifier (cp_parser* parser,
C++0x Extension:
simple-type-specifier:
+ auto
decltype ( expression )
GNU Extension:
@@ -10785,6 +10802,17 @@ cp_parser_simple_type_specifier (cp_parser* parser,
case RID_VOID:
type = void_type_node;
break;
+
+ case RID_AUTO:
+ if (cxx_dialect != cxx98)
+ {
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* We do not yet support the use of `auto' as a
+ type-specifier. */
+ error ("C++0x %<auto%> specifier not supported");
+ }
+ break;
case RID_DECLTYPE:
/* Parse the `decltype' type. */
@@ -10958,7 +10986,6 @@ static tree
cp_parser_type_name (cp_parser* parser)
{
tree type_decl;
- tree identifier;
/* We can't know yet whether it is a class-name or not. */
cp_parser_parse_tentatively (parser);
@@ -10974,44 +11001,64 @@ cp_parser_type_name (cp_parser* parser)
if (!cp_parser_parse_definitely (parser))
{
/* It must be a typedef-name or an enum-name. */
- identifier = cp_parser_identifier (parser);
- if (identifier == error_mark_node)
- return error_mark_node;
+ return cp_parser_nonclass_name (parser);
+ }
- /* Look up the type-name. */
- type_decl = cp_parser_lookup_name_simple (parser, identifier);
+ return type_decl;
+}
- if (TREE_CODE (type_decl) != TYPE_DECL
- && (objc_is_id (identifier) || objc_is_class_name (identifier)))
- {
- /* See if this is an Objective-C type. */
- tree protos = cp_parser_objc_protocol_refs_opt (parser);
- tree type = objc_get_protocol_qualified_type (identifier, protos);
- if (type)
- type_decl = TYPE_NAME (type);
- }
+/* Parse a non-class type-name, that is, either an enum-name or a typedef-name.
- /* Issue an error if we did not find a type-name. */
- if (TREE_CODE (type_decl) != TYPE_DECL)
- {
- if (!cp_parser_simulate_error (parser))
- cp_parser_name_lookup_error (parser, identifier, type_decl,
- "is not a type");
- type_decl = error_mark_node;
- }
- /* Remember that the name was used in the definition of the
- current class so that we can check later to see if the
- meaning would have been different after the class was
- entirely defined. */
- else if (type_decl != error_mark_node
- && !parser->scope)
- maybe_note_name_used_in_class (identifier, type_decl);
- }
+ enum-name:
+ identifier
+
+ typedef-name:
+ identifier
+
+ Returns a TYPE_DECL for the type. */
+
+static tree
+cp_parser_nonclass_name (cp_parser* parser)
+{
+ tree type_decl;
+ tree identifier;
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ /* Look up the type-name. */
+ type_decl = cp_parser_lookup_name_simple (parser, identifier);
+
+ if (TREE_CODE (type_decl) != TYPE_DECL
+ && (objc_is_id (identifier) || objc_is_class_name (identifier)))
+ {
+ /* See if this is an Objective-C type. */
+ tree protos = cp_parser_objc_protocol_refs_opt (parser);
+ tree type = objc_get_protocol_qualified_type (identifier, protos);
+ if (type)
+ type_decl = TYPE_NAME (type);
+ }
+
+ /* Issue an error if we did not find a type-name. */
+ if (TREE_CODE (type_decl) != TYPE_DECL)
+ {
+ if (!cp_parser_simulate_error (parser))
+ cp_parser_name_lookup_error (parser, identifier, type_decl,
+ "is not a type");
+ return error_mark_node;
+ }
+ /* Remember that the name was used in the definition of the
+ current class so that we can check later to see if the
+ meaning would have been different after the class was
+ entirely defined. */
+ else if (type_decl != error_mark_node
+ && !parser->scope)
+ maybe_note_name_used_in_class (identifier, type_decl);
+
return type_decl;
}
-
/* Parse an elaborated-type-specifier. Note that the grammar given
here incorporates the resolution to DR68.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2a54986c551..ade17a5cedd 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -9156,13 +9156,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
message to avoid spewing a ton of messages during a
single bad template instantiation. */
if (complain & tf_error
-#ifdef USE_MAPPED_LOCATION
- && last_loc != input_location
-#else
- && (last_loc.line != input_line
- || last_loc.file != input_filename)
-#endif
- )
+ && last_loc != input_location)
{
if (TREE_CODE (type) == VOID_TYPE)
error ("forming reference to void");
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 1925d04fbc5..f2085e4f26a 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1,6 +1,6 @@
/* RunTime Type Identification
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007
+ 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Mostly written by Jason Merrill (jason@cygnus.com).
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "toplev.h"
#include "convert.h"
#include "target.h"
+#include "c-pragma.h"
/* C++ returns type information to the user in struct type_info
objects. We also use type information to implement dynamic_cast and
@@ -124,6 +125,19 @@ static bool typeinfo_in_lib_p (tree);
static int doing_runtime = 0;
+static void
+push_abi_namespace (void)
+{
+ push_nested_namespace (abi_node);
+ push_visibility ("default");
+}
+
+static void
+pop_abi_namespace (void)
+{
+ pop_visibility ();
+ pop_nested_namespace (abi_node);
+}
/* Declare language defined type_info type and a pointer to const
type_info. This is incomplete here, and will be completed when
@@ -669,10 +683,9 @@ build_dynamic_cast_1 (tree type, tree expr)
{
tree tmp;
tree tinfo_ptr;
- tree ns = abi_node;
const char *name;
- push_nested_namespace (ns);
+ push_abi_namespace ();
tinfo_ptr = xref_tag (class_type,
get_identifier ("__class_type_info"),
/*tag_scope=*/ts_current, false);
@@ -689,7 +702,7 @@ build_dynamic_cast_1 (tree type, tree expr)
tmp = build_function_type (ptr_type_node, tmp);
dcast_fn = build_library_fn_ptr (name, tmp);
DECL_IS_PURE (dcast_fn) = 1;
- pop_nested_namespace (ns);
+ pop_abi_namespace ();
dynamic_cast_node = dcast_fn;
}
result = build_cxx_call (dcast_fn, 4, elems);
@@ -848,10 +861,10 @@ tinfo_base_init (tinfo_s *ti, tree target)
if (!vtable_ptr)
{
tree real_type;
- push_nested_namespace (abi_node);
+ push_abi_namespace ();
real_type = xref_tag (class_type, ti->name,
/*tag_scope=*/ts_current, false);
- pop_nested_namespace (abi_node);
+ pop_abi_namespace ();
if (!COMPLETE_TYPE_P (real_type))
{
@@ -1268,14 +1281,14 @@ get_pseudo_ti_index (tree type)
TK_BASE_TYPE)->type,
array_domain);
- push_nested_namespace (abi_node);
+ push_abi_namespace ();
create_pseudo_type_info
(ix, "__vmi_class_type_info",
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, base_array),
NULL);
- pop_nested_namespace (abi_node);
+ pop_abi_namespace ();
break;
}
}
@@ -1298,7 +1311,7 @@ create_tinfo_types (void)
VEC_safe_grow (tinfo_s, gc, tinfo_descs, TK_FIXED);
- push_nested_namespace (abi_node);
+ push_abi_namespace ();
/* Create the internal type_info structure. This is used as a base for
the other structures. */
@@ -1376,7 +1389,7 @@ create_tinfo_types (void)
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
- pop_nested_namespace (abi_node);
+ pop_abi_namespace ();
}
/* Emit the type_info descriptors which are guaranteed to be in the runtime
@@ -1404,11 +1417,11 @@ emit_support_tinfos (void)
int ix;
tree bltn_type, dtor;
- push_nested_namespace (abi_node);
+ push_abi_namespace ();
bltn_type = xref_tag (class_type,
get_identifier ("__fundamental_type_info"),
/*tag_scope=*/ts_current, false);
- pop_nested_namespace (abi_node);
+ pop_abi_namespace ();
if (!COMPLETE_TYPE_P (bltn_type))
return;
dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
index 18ef8a7dc55..b2382f167e3 100644
--- a/gcc/dbgcnt.def
+++ b/gcc/dbgcnt.def
@@ -65,12 +65,26 @@ along with GCC; see the file COPYING3. If not see
/* Debug counter definitions. */
DEBUG_COUNTER (auto_inc_dec)
+DEBUG_COUNTER (cfg_cleanup)
DEBUG_COUNTER (cse2_move2add)
+DEBUG_COUNTER (cprop1)
+DEBUG_COUNTER (cprop2)
DEBUG_COUNTER (dce)
+DEBUG_COUNTER (dce_fast)
+DEBUG_COUNTER (dce_ud)
DEBUG_COUNTER (delete_trivial_dead)
DEBUG_COUNTER (dse)
+DEBUG_COUNTER (dse1)
+DEBUG_COUNTER (dse2)
+DEBUG_COUNTER (gcse)
DEBUG_COUNTER (gcse2_delete)
+DEBUG_COUNTER (global_alloc_at_func)
+DEBUG_COUNTER (global_alloc_at_reg)
DEBUG_COUNTER (ia64_sched2)
+DEBUG_COUNTER (if_conversion)
+DEBUG_COUNTER (if_after_combine)
+DEBUG_COUNTER (if_after_reload)
+DEBUG_COUNTER (jump_bypass)
DEBUG_COUNTER (local_alloc_for_sched)
DEBUG_COUNTER (postreload_cse)
DEBUG_COUNTER (pre_insn)
@@ -79,8 +93,7 @@ DEBUG_COUNTER (sched_block)
DEBUG_COUNTER (sched_func)
DEBUG_COUNTER (sched_insn)
DEBUG_COUNTER (sched_region)
+DEBUG_COUNTER (sms_sched_loop)
DEBUG_COUNTER (split_for_sched2)
DEBUG_COUNTER (tail_call)
-DEBUG_COUNTER (global_alloc_at_func)
-DEBUG_COUNTER (global_alloc_at_reg)
-DEBUG_COUNTER (sms_sched_loop)
+
diff --git a/gcc/dce.c b/gcc/dce.c
index e63a07a9ef4..70b9e226514 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -563,7 +563,8 @@ rest_of_handle_ud_dce (void)
static bool
gate_ud_dce (void)
{
- return optimize > 1 && flag_dce;
+ return optimize > 1 && flag_dce
+ && dbg_cnt (dce_ud);
}
struct tree_opt_pass pass_ud_rtl_dce =
@@ -848,7 +849,8 @@ run_fast_dce (void)
static bool
gate_fast_dce (void)
{
- return optimize > 0 && flag_dce;
+ return optimize > 0 && flag_dce
+ && dbg_cnt (dce_fast);
}
struct tree_opt_pass pass_fast_rtl_dce =
diff --git a/gcc/df-scan.c b/gcc/df-scan.c
index f3a90262f99..3dc759cedb3 100644
--- a/gcc/df-scan.c
+++ b/gcc/df-scan.c
@@ -1,6 +1,6 @@
/* Scanning of rtl for dataflow analysis.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008 Free Software Foundation, Inc.
Originally contributed by Michael P. Hayes
(m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
@@ -1753,14 +1753,10 @@ df_maybe_reorganize_def_refs (enum df_ref_order order)
}
-/* Change the BB of all refs in the ref chain to NEW_BB.
- Assumes that all refs in the chain have the same BB.
- If changed, return the original bb the chain belonged to
- (or .
- If no change, return NEW_BB.
- If something's wrong, it will return NULL. */
+/* Change the BB of all refs in the ref chain from OLD_BB to NEW_BB.
+ Assumes that all refs in the chain have the same BB. */
-static basic_block
+static void
df_ref_chain_change_bb (struct df_ref **ref_rec,
basic_block old_bb,
basic_block new_bb)
@@ -1769,18 +1765,10 @@ df_ref_chain_change_bb (struct df_ref **ref_rec,
{
struct df_ref *ref = *ref_rec;
- if (DF_REF_BB (ref) == new_bb)
- return new_bb;
- else
- {
- gcc_assert (old_bb == NULL || DF_REF_BB (ref) == old_bb);
- old_bb = DF_REF_BB (ref);
- DF_REF_BB (ref) = new_bb;
- }
+ gcc_assert (DF_REF_BB (ref) == old_bb);
+ DF_REF_BB (ref) = new_bb;
ref_rec++;
}
-
- return old_bb;
}
@@ -1789,13 +1777,17 @@ df_ref_chain_change_bb (struct df_ref **ref_rec,
instructions from one block to another. */
void
-df_insn_change_bb (rtx insn)
+df_insn_change_bb (rtx insn, basic_block new_bb)
{
- basic_block new_bb = BLOCK_FOR_INSN (insn);
- basic_block old_bb = NULL;
+ basic_block old_bb = BLOCK_FOR_INSN (insn);
struct df_insn_info *insn_info;
unsigned int uid = INSN_UID (insn);
+ if (old_bb == new_bb)
+ return;
+
+ set_block_for_insn (insn, new_bb);
+
if (!df)
return;
@@ -1814,17 +1806,9 @@ df_insn_change_bb (rtx insn)
if (!INSN_P (insn))
return;
- old_bb = df_ref_chain_change_bb (insn_info->defs, old_bb, new_bb);
- if (old_bb == new_bb)
- return;
-
- old_bb = df_ref_chain_change_bb (insn_info->uses, old_bb, new_bb);
- if (old_bb == new_bb)
- return;
-
- old_bb = df_ref_chain_change_bb (insn_info->eq_uses, old_bb, new_bb);
- if (old_bb == new_bb)
- return;
+ df_ref_chain_change_bb (insn_info->defs, old_bb, new_bb);
+ df_ref_chain_change_bb (insn_info->uses, old_bb, new_bb);
+ df_ref_chain_change_bb (insn_info->eq_uses, old_bb, new_bb);
df_set_bb_dirty (new_bb);
if (old_bb)
diff --git a/gcc/df.h b/gcc/df.h
index 8beadc98d4c..7c14f163dc0 100644
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -1,6 +1,6 @@
/* Form lists of pseudo register references for autoinc optimization
for GNU compiler. This is part of flow optimization.
- Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Originally contributed by Michael P. Hayes
(m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
@@ -871,7 +871,7 @@ extern bool df_insn_rescan (rtx);
extern void df_insn_rescan_all (void);
extern void df_process_deferred_rescans (void);
extern void df_recompute_luids (basic_block);
-extern void df_insn_change_bb (rtx);
+extern void df_insn_change_bb (rtx, basic_block);
extern void df_maybe_reorganize_use_refs (enum df_ref_order);
extern void df_maybe_reorganize_def_refs (enum df_ref_order);
extern void df_ref_change_reg_with_loc (int, int, rtx);
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index c05a8ccc415..bdc5ca5053b 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -1,5 +1,5 @@
/* Language-independent diagnostic subroutines for the GNU Compiler Collection
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
@@ -159,10 +159,8 @@ diagnostic_build_prefix (diagnostic_info *diagnostic)
return
(s.file == NULL
? build_message_string ("%s: %s", progname, text)
-#ifdef USE_MAPPED_LOCATION
: flag_show_column && s.column != 0
? build_message_string ("%s:%d:%d: %s", s.file, s.line, s.column, text)
-#endif
: build_message_string ("%s:%d: %s", s.file, s.line, text));
}
@@ -273,7 +271,7 @@ diagnostic_report_current_function (diagnostic_context *context,
void
diagnostic_report_current_module (diagnostic_context *context)
{
- struct file_stack *p;
+ const struct line_map *map;
if (pp_needs_newline (context->printer))
{
@@ -281,23 +279,29 @@ diagnostic_report_current_module (diagnostic_context *context)
pp_needs_newline (context->printer) = false;
}
- p = input_file_stack;
- if (p && diagnostic_last_module_changed (context))
+ if (input_location <= BUILTINS_LOCATION)
+ return;
+
+ map = linemap_lookup (line_table, input_location);
+ if (map && diagnostic_last_module_changed (context, map))
{
- expanded_location xloc = expand_location (p->location);
- pp_verbatim (context->printer,
- "In file included from %s:%d",
- xloc.file, xloc.line);
- while ((p = p->next) != NULL)
+ diagnostic_set_last_module (context, map);
+ if (! MAIN_FILE_P (map))
{
- xloc = expand_location (p->location);
+ map = INCLUDED_FROM (line_table, map);
pp_verbatim (context->printer,
- ",\n from %s:%d",
- xloc.file, xloc.line);
+ "In file included from %s:%d",
+ map->to_file, LAST_SOURCE_LINE (map));
+ while (! MAIN_FILE_P (map))
+ {
+ map = INCLUDED_FROM (line_table, map);
+ pp_verbatim (context->printer,
+ ",\n from %s:%d",
+ map->to_file, LAST_SOURCE_LINE (map));
+ }
+ pp_verbatim (context->printer, ":");
+ pp_newline (context->printer);
}
- pp_verbatim (context->printer, ":");
- diagnostic_set_last_module (context);
- pp_newline (context->printer);
}
}
@@ -542,11 +546,31 @@ pedwarn (const char *gmsgid, ...)
va_start (ap, gmsgid);
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
- pedantic_error_kind ());
+ pedantic_warning_kind ());
+ report_diagnostic (&diagnostic);
+ va_end (ap);
+}
+
+/* A "permissive" error: issues an error unless -fpermissive was given
+ on the command line, in which case it issues a warning. Use this
+ for things that really should be errors but we want to support
+ legacy code. */
+
+void
+permerror (const char *gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, gmsgid);
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
+ permissive_error_kind ());
+ diagnostic.option_index = OPT_fpermissive;
report_diagnostic (&diagnostic);
va_end (ap);
}
+
/* A hard error: the code is definitely ill-formed, and an object file
will not be produced. */
void
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 02e43bd0f8e..a249574d4aa 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -1,5 +1,5 @@
/* Various declarations for language-independent diagnostics subroutines.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
@@ -50,7 +50,8 @@ typedef struct diagnostic_info
int option_index;
} diagnostic_info;
-#define pedantic_error_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING)
+#define pedantic_warning_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING)
+#define permissive_error_kind() (flag_permissive ? DK_WARNING : DK_ERROR)
/* Forward declarations. */
@@ -110,8 +111,9 @@ struct diagnostic_context
function name. */
tree last_function;
- /* Used to detect when input_file_stack has changed since last described. */
- int last_module;
+ /* Used to detect when the input file stack has changed since last
+ described. */
+ const struct line_map *last_module;
int lock;
};
@@ -152,13 +154,13 @@ struct diagnostic_context
/* True if the last module or file in which a diagnostic was reported is
different from the current one. */
-#define diagnostic_last_module_changed(DC) \
- ((DC)->last_module != input_file_stack_tick)
+#define diagnostic_last_module_changed(DC, MAP) \
+ ((DC)->last_module != MAP)
/* Remember the current module or file as being the last one in which we
report a diagnostic. */
-#define diagnostic_set_last_module(DC) \
- (DC)->last_module = input_file_stack_tick
+#define diagnostic_set_last_module(DC, MAP) \
+ (DC)->last_module = MAP
/* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */
#define diagnostic_abort_on_error(DC) \
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 693f30de694..dbd66eab30c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -241,7 +241,7 @@ Objective-C and Objective-C++ Dialects}.
-Wimplicit -Wimplicit-function-declaration -Wimplicit-int @gol
-Wimport -Wno-import -Winit-self -Winline @gol
-Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
--Winvalid-pch -Wlarger-than-@var{len} -Wunsafe-loop-optimizations @gol
+-Winvalid-pch -Wlarger-than=@var{len} -Wunsafe-loop-optimizations @gol
-Wlogical-op -Wlong-long @gol
-Wmain -Wmissing-braces -Wmissing-field-initializers @gol
-Wmissing-format-attribute -Wmissing-include-dirs @gol
@@ -354,6 +354,7 @@ Objective-C and Objective-C++ Dialects}.
-fstrict-aliasing -fstrict-overflow -fthread-jumps -ftracer -ftree-ccp @gol
-ftree-ch -ftree-copy-prop -ftree-copyrename -ftree-dce @gol
-ftree-dominator-opts -ftree-dse -ftree-fre -ftree-loop-im @gol
+-ftree-loop-distribution @gol
-ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize @gol
-ftree-parallelize-loops=@var{n} -ftree-pre -ftree-reassoc -ftree-salias @gol
-ftree-sink -ftree-sra -ftree-store-ccp -ftree-ter @gol
@@ -2683,6 +2684,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
-Wunused-label @gol
-Wunused-value @gol
-Wunused-variable @gol
+-Wvolatile-register-var @gol
}
Note that some warning flags are not implied by @option{-Wall}. Some of
@@ -3516,7 +3518,8 @@ Do not warn whenever an @samp{#else} or an @samp{#endif} are followed by text.
Warn whenever a local variable shadows another local variable, parameter or
global variable or whenever a built-in function is shadowed.
-@item -Wlarger-than-@var{len}
+@item -Wlarger-than=@var{len}
+@opindex Wlarger-than=@var{len}
@opindex Wlarger-than-@var{len}
Warn whenever an object of larger than @var{len} bytes is defined.
@@ -4016,7 +4019,8 @@ the variable length array.
@opindex Wno-volatile-register-var
Warn if a register variable is declared volatile. The volatile
modifier does not inhibit all optimizations that may eliminate reads
-and/or writes to register variables.
+and/or writes to register variables. This warning is enabled by
+@option{-Wall}.
@item -Wdisabled-optimization
@opindex Wdisabled-optimization
@@ -5925,6 +5929,11 @@ performance and allow further loop optimizations to take place.
Compare the results of several data dependence analyzers. This option
is used for debugging the data dependence analyzers.
+@item -ftree-loop-distribution
+Perform loop distribution. This flag can improve cache performance on
+big loop bodies and allow further loop optimizations, like
+parallelization or vectorization, to take place.
+
@item -ftree-loop-im
@opindex ftree-loop-im
Perform loop invariant motion on trees. This pass moves only invariants that
@@ -12922,11 +12931,12 @@ Supported values for @var{cpu_type} are @samp{401}, @samp{403},
@samp{601}, @samp{602}, @samp{603}, @samp{603e}, @samp{604},
@samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400},
@samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823},
-@samp{860}, @samp{970}, @samp{8540}, @samp{ec603e}, @samp{G3},
-@samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3},
-@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6},
-@samp{power6x}, @samp{common}, @samp{powerpc}, @samp{powerpc64},
-@samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}.
+@samp{860}, @samp{970}, @samp{8540}, @samp{e300c2}, @samp{e300c3},
+@samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5}, @samp{power},
+@samp{power2}, @samp{power3}, @samp{power4}, @samp{power5},
+@samp{power5+}, @samp{power6}, @samp{power6x}, @samp{common},
+@samp{powerpc}, @samp{powerpc64}, @samp{rios}, @samp{rios1},
+@samp{rios2}, @samp{rsc}, and @samp{rs64}.
@option{-mcpu=common} selects a completely generic processor. Code
generated under this option will run on any POWER or PowerPC processor.
diff --git a/gcc/dse.c b/gcc/dse.c
index 2b860187fbe..48df3503b6f 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -540,6 +540,8 @@ static unsigned int current_position;
static bool gate_dse (void);
+static bool gate_dse1 (void);
+static bool gate_dse2 (void);
/*----------------------------------------------------------------------------
@@ -3284,13 +3286,27 @@ rest_of_handle_dse (void)
static bool
gate_dse (void)
{
- return optimize > 0 && flag_dse;
+ return gate_dse1 () || gate_dse2 ();
+}
+
+static bool
+gate_dse1 (void)
+{
+ return optimize > 0 && flag_dse
+ && dbg_cnt (dse1);
+}
+
+static bool
+gate_dse2 (void)
+{
+ return optimize > 0 && flag_dse
+ && dbg_cnt (dse2);
}
struct tree_opt_pass pass_rtl_dse1 =
{
"dse1", /* name */
- gate_dse, /* gate */
+ gate_dse1, /* gate */
rest_of_handle_dse, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -3309,7 +3325,7 @@ struct tree_opt_pass pass_rtl_dse1 =
struct tree_opt_pass pass_rtl_dse2 =
{
"dse2", /* name */
- gate_dse, /* gate */
+ gate_dse2, /* gate */
rest_of_handle_dse, /* execute */
NULL, /* sub */
NULL, /* next */
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 1a9239ab8a5..8628d5238de 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -1,6 +1,6 @@
/* Emit RTL for the GCC expander.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -3737,10 +3737,7 @@ reorder_insns (rtx from, rtx to, rtx after)
for (x = from; x != NEXT_INSN (to); x = NEXT_INSN (x))
if (!BARRIER_P (x))
- {
- set_block_for_insn (x, bb);
- df_insn_change_bb (x);
- }
+ df_insn_change_bb (x, bb);
}
}
@@ -4533,11 +4530,7 @@ emit_note (enum insn_note kind)
void
force_next_line_note (void)
{
-#ifdef USE_MAPPED_LOCATION
last_location = -1;
-#else
- last_location.line = -1;
-#endif
}
/* Place a note of KIND on insn INSN with DATUM as the datum. If a
diff --git a/gcc/expr.c b/gcc/expr.c
index 36741918fb3..79a039a529f 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8898,10 +8898,16 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case BIT_XOR_EXPR:
goto binop;
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
case LROTATE_EXPR:
case RROTATE_EXPR:
+ /* The expansion code only handles expansion of mode precision
+ rotates. */
+ gcc_assert (GET_MODE_PRECISION (TYPE_MODE (type))
+ == TYPE_PRECISION (type));
+
+ /* Falltrough. */
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
/* If this is a fixed-point operation, then we cannot use the code
below because "expand_shift" doesn't support sat/no-sat fixed-point
shifts. */
diff --git a/gcc/final.c b/gcc/final.c
index 8d1cebead41..05d60d5d68d 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1,6 +1,6 @@
/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -2192,12 +2192,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
fputs (ASM_APP_ON, file);
app_on = 1;
}
-#ifdef USE_MAPPED_LOCATION
loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body));
-#else
- loc.file = ASM_INPUT_SOURCE_FILE (body);
- loc.line = ASM_INPUT_SOURCE_LINE (body);
-#endif
if (*loc.file && loc.line)
fprintf (asm_out_file, "%s %i \"%s\" 1\n",
ASM_COMMENT_START, loc.line, loc.file);
diff --git a/gcc/flags.h b/gcc/flags.h
index e2041500c14..686691c21e0 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -197,6 +197,10 @@ extern int flag_dump_unnumbered;
extern int flag_pedantic_errors;
+/* Nonzero means make permerror produce warnings instead of errors. */
+
+extern int flag_permissive;
+
/* Nonzero if we are compiling code for a shared library, zero for
executable. */
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1ecd2255e4a..5af6f0d686a 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -2475,8 +2475,15 @@ fold_convertible_p (const_tree type, const_tree arg)
return (TREE_CODE (orig) == VECTOR_TYPE
&& tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
- default:
+ case REAL_TYPE:
+ case FIXED_POINT_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case VOID_TYPE:
return TREE_CODE (type) == TREE_CODE (orig);
+
+ default:
+ return false;
}
}
@@ -8340,7 +8347,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
if (TREE_CODE (arg0) == INTEGER_CST)
return fold_not_const (arg0, type);
else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
- return TREE_OPERAND (op0, 0);
+ return fold_convert (type, TREE_OPERAND (arg0, 0));
/* Convert ~ (-A) to A - 1. */
else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
return fold_build2 (MINUS_EXPR, type,
@@ -9886,13 +9893,18 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
is a rotate of A by B bits. */
{
enum tree_code code0, code1;
+ tree rtype;
code0 = TREE_CODE (arg0);
code1 = TREE_CODE (arg1);
if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
|| (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
&& operand_equal_p (TREE_OPERAND (arg0, 0),
TREE_OPERAND (arg1, 0), 0)
- && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
+ && (rtype = TREE_TYPE (TREE_OPERAND (arg0, 0)),
+ TYPE_UNSIGNED (rtype))
+ /* Only create rotates in complete modes. Other cases are not
+ expanded properly. */
+ && TYPE_PRECISION (rtype) == GET_MODE_PRECISION (TYPE_MODE (rtype)))
{
tree tree01, tree11;
enum tree_code code01, code11;
@@ -11636,7 +11648,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
{
tree tem = build_int_cst (TREE_TYPE (arg1),
- GET_MODE_BITSIZE (TYPE_MODE (type)));
+ TYPE_PRECISION (type));
tem = const_binop (MINUS_EXPR, tem, arg1, 0);
return fold_build2 (RROTATE_EXPR, type, op0, tem);
}
@@ -11655,8 +11667,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
fold_build2 (code, type,
TREE_OPERAND (arg0, 1), arg1));
- /* Two consecutive rotates adding up to the width of the mode can
- be ignored. */
+ /* Two consecutive rotates adding up to the precision of the
+ type can be ignored. */
if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
&& TREE_CODE (arg0) == RROTATE_EXPR
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
@@ -11664,7 +11676,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
&& ((TREE_INT_CST_LOW (arg1)
+ TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
- == (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type))))
+ == (unsigned int) TYPE_PRECISION (type)))
return TREE_OPERAND (arg0, 0);
/* Fold (X & C2) << C1 into (X << C1) & (C2 << C1)
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 5ba83fb7b87..841c9d4c0d8 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,88 @@
+2008-02-29 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/35059
+ * expr.c (find_array_element): Modify traversing the constructor to
+ avoid trying to access NULL memory pointed to by next for the
+ last element. (find_array_section): Exit while loop if cons->next is
+ NULL.
+ * trans-expr.c (gfc_conv_scalar_char_value): Initialize gfc_typespec.
+ (gfc_conv_function_call): Same.
+ * decl.c (gfc_match_implicit): Same.
+ * trans-intrinsic.c (gfc_conv_intrinsic_sr_kind): Same.
+
+2008-02-28 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/31463
+ PR fortran/33950
+ PR fortran/34296
+ * lang.opt: Added -Wreturn-type.
+ * options.c (gfc_handle_option): Recognize -Wreturn-type.
+ * trans-decl.c (gfc_trans_deferred_vars): Emit warnings for funtions
+ where the result value is not set.
+ (gfc_generate_function_code): Likewise.
+ (generate_local_decl): Emit warnings for funtions whose RESULT
+ variable is not set.
+
+2008-02-28 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/34868
+ * trans-expr.c (gfc_conv_variable): Don't build indirect
+ references when explicit interface is mandated.
+ * resolve.c (resolve_formal_arglist): Set attr.always_explicit
+ on the result symbol as well as the procedure symbol.
+
+2008-02-27 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33387
+ * trans.h: Remove prototypes for gfor_fndecl_math_exponent4,
+ gfor_fndecl_math_exponent8, gfor_fndecl_math_exponent10 and
+ gfor_fndecl_math_exponent16.
+ * f95-lang.c (build_builtin_fntypes): Add new function types.
+ (gfc_init_builtin_functions): Add new builtins for nextafter,
+ frexp, ldexp, fabs, scalbn and inf.
+ * iresolve.c (gfc_resolve_rrspacing): Don't add hidden arguments.
+ (gfc_resolve_scale): Don't convert type of second argument.
+ (gfc_resolve_set_exponent): Likewise.
+ (gfc_resolve_size): Don't add hidden arguments.
+ * trans-decl.c: Remove gfor_fndecl_math_exponent4,
+ gfor_fndecl_math_exponent8, gfor_fndecl_math_exponent10 and
+ gfor_fndecl_math_exponent16.
+ * trans-intrinsic.c (gfc_intrinsic_map): Remove intrinsics
+ for scalbn, fraction, nearest, rrspacing, set_exponent and
+ spacing.
+ (gfc_conv_intrinsic_exponent): Directly call frexp.
+ (gfc_conv_intrinsic_fraction, gfc_conv_intrinsic_nearest,
+ gfc_conv_intrinsic_spacing, gfc_conv_intrinsic_rrspacing,
+ gfc_conv_intrinsic_scale, gfc_conv_intrinsic_set_exponent): New
+ functions.
+ (gfc_conv_intrinsic_function): Use the new functions above.
+
+2008-02-26 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/35033
+ * interface.c (check_operator_interface): Show better line for error
+ messages; fix constrains for user-defined assignment operators.
+ (gfc_extend_assign): Fix constrains for user-defined assignment
+ operators.
+
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * trans-io.c (set_error_locus): Remove old location code.
+ * trans-decl.c (gfc_set_decl_location): Remove old location code.
+ * f95-lang.c (gfc_init): Remove test of USE_MAPPED_LOCATION.
+ * scanner.c (gfc_gobble_whitespace): Remove old location code.
+ (get_file): Likewise.
+ (preprocessor_line): Likewise.
+ (load_file): Likewise.
+ (gfc_new_file): Likewise.
+ * trans.c (gfc_trans_runtime_check): Remove old location code.
+ (gfc_get_backend_locus): Likewise.
+ (gfc_set_backend_locus): Likewise.
+ * data.c (gfc_assign_data_value): Remove old location code.
+ * error.c (show_locus): Remove old location code.
+ * gfortran.h (gfc_linebuf): Remove old location code.
+ (gfc_linebuf_linenum): Remove old-location variant.
+
2008-02-25 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/34729
diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
index 1fe2ee51f9d..13af445dfd4 100644
--- a/gcc/fortran/data.c
+++ b/gcc/fortran/data.c
@@ -424,14 +424,9 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index)
/* Order in which the expressions arrive here depends on whether
they are from data statements or F95 style declarations.
Therefore, check which is the most recent. */
-#ifdef USE_MAPPED_LOCATION
expr = (LOCATION_LINE (init->where.lb->location)
> LOCATION_LINE (rvalue->where.lb->location))
? init : rvalue;
-#else
- expr = (init->where.lb->linenum > rvalue->where.lb->linenum)
- ? init : rvalue;
-#endif
gfc_notify_std (GFC_STD_GNU, "Extension: re-initialization "
"of '%s' at %L", symbol->name, &expr->where);
}
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index d8306879d56..892c80a46d3 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -2506,6 +2506,8 @@ gfc_match_implicit (void)
int c;
match m;
+ gfc_clear_ts (&ts);
+
/* We don't allow empty implicit statements. */
if (gfc_match_eos () == MATCH_YES)
{
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 0718e5af5b5..669c2d47a6b 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -182,11 +182,7 @@ show_locus (locus *loc, int c1, int c2)
error_string (f->filename);
error_char (':');
-#ifdef USE_MAPPED_LOCATION
error_integer (LOCATION_LINE (lb->location));
-#else
- error_integer (lb->linenum);
-#endif
if ((c1 > 0) || (c2 > 0))
error_char ('.');
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 0b0fd0936a3..329bc722dba 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -1051,18 +1051,19 @@ find_array_element (gfc_constructor *cons, gfc_array_ref *ar,
mpz_mul (span, span, tmp);
}
- if (cons)
- {
- for (nelemen = mpz_get_ui (offset); nelemen > 0; nelemen--)
- {
- if (cons->iterator)
- {
- cons = NULL;
- goto depart;
- }
- cons = cons->next;
- }
- }
+ for (nelemen = mpz_get_ui (offset); nelemen > 0; nelemen--)
+ {
+ if (cons)
+ {
+ if (cons->iterator)
+ {
+ cons = NULL;
+
+ goto depart;
+ }
+ cons = cons->next;
+ }
+ }
depart:
mpz_clear (delta);
@@ -1341,7 +1342,7 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
cons = base;
}
- while (mpz_cmp (ptr, index) > 0)
+ while (cons && cons->next && mpz_cmp (ptr, index) > 0)
{
mpz_add_ui (index, index, one);
cons = cons->next;
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index ea795b24f74..7a3e413caf3 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -276,10 +276,8 @@ gfc_be_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
static bool
gfc_init (void)
{
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_ENTER, false, gfc_source_file, 1);
linemap_add (line_table, LC_RENAME, false, "<built-in>", 0);
-#endif
/* First initialize the backend. */
gfc_init_decl_processing ();
@@ -758,6 +756,16 @@ build_builtin_fntypes (tree *fntype, tree type)
tmp = tree_cons (NULL_TREE, integer_type_node, void_list_node);
tmp = tree_cons (NULL_TREE, type, tmp);
fntype[2] = build_function_type (type, tmp);
+ /* type (*) (void) */
+ fntype[3] = build_function_type (type, void_list_node);
+ /* type (*) (type, &int) */
+ tmp = tree_cons (NULL_TREE, type, void_list_node);
+ tmp = tree_cons (NULL_TREE, build_pointer_type (integer_type_node), tmp);
+ fntype[4] = build_function_type (type, tmp);
+ /* type (*) (type, int) */
+ tmp = tree_cons (NULL_TREE, type, void_list_node);
+ tmp = tree_cons (NULL_TREE, integer_type_node, tmp);
+ fntype[5] = build_function_type (type, tmp);
}
@@ -808,12 +816,12 @@ gfc_init_builtin_functions (void)
ATTR_CONST_NOTHROW_LIST
};
- tree mfunc_float[3];
- tree mfunc_double[3];
- tree mfunc_longdouble[3];
- tree mfunc_cfloat[3];
- tree mfunc_cdouble[3];
- tree mfunc_clongdouble[3];
+ tree mfunc_float[6];
+ tree mfunc_double[6];
+ tree mfunc_longdouble[6];
+ tree mfunc_cfloat[6];
+ tree mfunc_cdouble[6];
+ tree mfunc_clongdouble[6];
tree func_cfloat_float, func_float_cfloat;
tree func_cdouble_double, func_double_cdouble;
tree func_clongdouble_longdouble, func_longdouble_clongdouble;
@@ -904,6 +912,34 @@ gfc_init_builtin_functions (void)
gfc_define_builtin ("__builtin_copysignf", mfunc_float[1],
BUILT_IN_COPYSIGNF, "copysignf", true);
+ gfc_define_builtin ("__builtin_nextafterl", mfunc_longdouble[1],
+ BUILT_IN_NEXTAFTERL, "nextafterl", true);
+ gfc_define_builtin ("__builtin_nextafter", mfunc_double[1],
+ BUILT_IN_NEXTAFTER, "nextafter", true);
+ gfc_define_builtin ("__builtin_nextafterf", mfunc_float[1],
+ BUILT_IN_NEXTAFTERF, "nextafterf", true);
+
+ gfc_define_builtin ("__builtin_frexpl", mfunc_longdouble[4],
+ BUILT_IN_FREXPL, "frexpl", false);
+ gfc_define_builtin ("__builtin_frexp", mfunc_double[4],
+ BUILT_IN_FREXP, "frexp", false);
+ gfc_define_builtin ("__builtin_frexpf", mfunc_float[4],
+ BUILT_IN_FREXPF, "frexpf", false);
+
+ gfc_define_builtin ("__builtin_fabsl", mfunc_longdouble[0],
+ BUILT_IN_FABSL, "fabsl", true);
+ gfc_define_builtin ("__builtin_fabs", mfunc_double[0],
+ BUILT_IN_FABS, "fabs", true);
+ gfc_define_builtin ("__builtin_fabsf", mfunc_float[0],
+ BUILT_IN_FABSF, "fabsf", true);
+
+ gfc_define_builtin ("__builtin_scalbnl", mfunc_longdouble[5],
+ BUILT_IN_SCALBNL, "scalbnl", true);
+ gfc_define_builtin ("__builtin_scalbn", mfunc_double[5],
+ BUILT_IN_SCALBN, "scalbn", true);
+ gfc_define_builtin ("__builtin_scalbnf", mfunc_float[5],
+ BUILT_IN_SCALBNF, "scalbnf", true);
+
gfc_define_builtin ("__builtin_fmodl", mfunc_longdouble[1],
BUILT_IN_FMODL, "fmodl", true);
gfc_define_builtin ("__builtin_fmod", mfunc_double[1],
@@ -911,6 +947,13 @@ gfc_init_builtin_functions (void)
gfc_define_builtin ("__builtin_fmodf", mfunc_float[1],
BUILT_IN_FMODF, "fmodf", true);
+ gfc_define_builtin ("__builtin_infl", mfunc_longdouble[3],
+ BUILT_IN_INFL, "__builtin_infl", true);
+ gfc_define_builtin ("__builtin_inf", mfunc_double[3],
+ BUILT_IN_INF, "__builtin_inf", true);
+ gfc_define_builtin ("__builtin_inff", mfunc_float[3],
+ BUILT_IN_INFF, "__builtin_inff", true);
+
/* lround{f,,l} and llround{f,,l} */
type = tree_cons (NULL_TREE, float_type_node, void_list_node);
tmp = build_function_type (long_integer_type_node, type);
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 5aef5bf1158..cc749792604 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -713,11 +713,7 @@ typedef struct gfc_file
typedef struct gfc_linebuf
{
-#ifdef USE_MAPPED_LOCATION
source_location location;
-#else
- int linenum;
-#endif
struct gfc_file *file;
struct gfc_linebuf *next;
@@ -729,11 +725,7 @@ typedef struct gfc_linebuf
#define gfc_linebuf_header_size (offsetof (gfc_linebuf, line))
-#ifdef USE_MAPPED_LOCATION
#define gfc_linebuf_linenum(LBUF) (LOCATION_LINE ((LBUF)->location))
-#else
-#define gfc_linebuf_linenum(LBUF) ((LBUF)->linenum)
-#endif
typedef struct
{
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index e72b97b1dce..4cee386d3d5 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -561,7 +561,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
if (sym == NULL)
{
gfc_error ("Alternate return cannot appear in operator "
- "interface at %L", &intr->where);
+ "interface at %L", &intr->sym->declared_at);
return;
}
if (args == 0)
@@ -591,7 +591,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
|| (args == 2 && operator == INTRINSIC_NOT))
{
gfc_error ("Operator interface at %L has the wrong number of arguments",
- &intr->where);
+ &intr->sym->declared_at);
return;
}
@@ -602,23 +602,28 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
if (!sym->attr.subroutine)
{
gfc_error ("Assignment operator interface at %L must be "
- "a SUBROUTINE", &intr->where);
+ "a SUBROUTINE", &intr->sym->declared_at);
return;
}
if (args != 2)
{
gfc_error ("Assignment operator interface at %L must have "
- "two arguments", &intr->where);
+ "two arguments", &intr->sym->declared_at);
return;
}
+
+ /* Allowed are (per F2003, 12.3.2.1.2 Defined assignments):
+ - First argument an array with different rank than second,
+ - Types and kinds do not conform, and
+ - First argument is of derived type. */
if (sym->formal->sym->ts.type != BT_DERIVED
- && sym->formal->next->sym->ts.type != BT_DERIVED
+ && (r1 == 0 || r1 == r2)
&& (sym->formal->sym->ts.type == sym->formal->next->sym->ts.type
|| (gfc_numeric_ts (&sym->formal->sym->ts)
&& gfc_numeric_ts (&sym->formal->next->sym->ts))))
{
gfc_error ("Assignment operator interface at %L must not redefine "
- "an INTRINSIC type assignment", &intr->where);
+ "an INTRINSIC type assignment", &intr->sym->declared_at);
return;
}
}
@@ -627,7 +632,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
if (!sym->attr.function)
{
gfc_error ("Intrinsic operator interface at %L must be a FUNCTION",
- &intr->where);
+ &intr->sym->declared_at);
return;
}
}
@@ -637,21 +642,21 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
{
if (i1 != INTENT_OUT && i1 != INTENT_INOUT)
gfc_error ("First argument of defined assignment at %L must be "
- "INTENT(IN) or INTENT(INOUT)", &intr->where);
+ "INTENT(OUT) or INTENT(INOUT)", &intr->sym->declared_at);
if (i2 != INTENT_IN)
gfc_error ("Second argument of defined assignment at %L must be "
- "INTENT(IN)", &intr->where);
+ "INTENT(IN)", &intr->sym->declared_at);
}
else
{
if (i1 != INTENT_IN)
gfc_error ("First argument of operator interface at %L must be "
- "INTENT(IN)", &intr->where);
+ "INTENT(IN)", &intr->sym->declared_at);
if (args == 2 && i2 != INTENT_IN)
gfc_error ("Second argument of operator interface at %L must be "
- "INTENT(IN)", &intr->where);
+ "INTENT(IN)", &intr->sym->declared_at);
}
/* From now on, all we have to do is check that the operator definition
@@ -2654,7 +2659,8 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
rhs = c->expr2;
/* Don't allow an intrinsic assignment to be replaced. */
- if (lhs->ts.type != BT_DERIVED && rhs->ts.type != BT_DERIVED
+ if (lhs->ts.type != BT_DERIVED
+ && (rhs->rank == 0 || rhs->rank == lhs->rank)
&& (lhs->ts.type == rhs->ts.type
|| (gfc_numeric_ts (&lhs->ts) && gfc_numeric_ts (&rhs->ts))))
return FAILURE;
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
index 3bc07fe633b..27a0022261f 100644
--- a/gcc/fortran/iresolve.c
+++ b/gcc/fortran/iresolve.c
@@ -1853,47 +1853,15 @@ gfc_resolve_reshape (gfc_expr *f, gfc_expr *source, gfc_expr *shape,
void
gfc_resolve_rrspacing (gfc_expr *f, gfc_expr *x)
{
- int k;
- gfc_actual_arglist *prec;
-
f->ts = x->ts;
f->value.function.name = gfc_get_string ("__rrspacing_%d", x->ts.kind);
-
- /* Create a hidden argument to the library routines for rrspacing. This
- hidden argument is the precision of x. */
- k = gfc_validate_kind (BT_REAL, x->ts.kind, false);
- prec = gfc_get_actual_arglist ();
- prec->name = "p";
- prec->expr = gfc_int_expr (gfc_real_kinds[k].digits);
- /* The library routine expects INTEGER(4). */
- if (prec->expr->ts.kind != gfc_c_int_kind)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_INTEGER;
- ts.kind = gfc_c_int_kind;
- gfc_convert_type (prec->expr, &ts, 2);
- }
- f->value.function.actual->next = prec;
}
void
-gfc_resolve_scale (gfc_expr *f, gfc_expr *x, gfc_expr *i)
+gfc_resolve_scale (gfc_expr *f, gfc_expr *x, gfc_expr *i ATTRIBUTE_UNUSED)
{
f->ts = x->ts;
-
- /* The implementation calls scalbn which takes an int as the
- second argument. */
- if (i->ts.kind != gfc_c_int_kind)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_INTEGER;
- ts.kind = gfc_c_int_kind;
- gfc_convert_type_warn (i, &ts, 2, 0);
- }
-
f->value.function.name = gfc_get_string ("__scale_%d", x->ts.kind);
}
@@ -1921,22 +1889,10 @@ gfc_resolve_secnds (gfc_expr *t1, gfc_expr *t0)
void
-gfc_resolve_set_exponent (gfc_expr *f, gfc_expr *x, gfc_expr *i)
+gfc_resolve_set_exponent (gfc_expr *f, gfc_expr *x,
+ gfc_expr *i ATTRIBUTE_UNUSED)
{
f->ts = x->ts;
-
- /* The library implementation uses GFC_INTEGER_4 unconditionally,
- convert type so we don't have to implement all possible
- permutations. */
- if (i->ts.kind != gfc_c_int_kind)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_INTEGER;
- ts.kind = gfc_c_int_kind;
- gfc_convert_type_warn (i, &ts, 2, 0);
- }
-
f->value.function.name = gfc_get_string ("__set_exponent_%d", x->ts.kind);
}
@@ -2016,59 +1972,8 @@ gfc_resolve_size (gfc_expr *f, gfc_expr *array ATTRIBUTE_UNUSED,
void
gfc_resolve_spacing (gfc_expr *f, gfc_expr *x)
{
- int k;
- gfc_actual_arglist *prec, *tiny, *emin_1;
-
f->ts = x->ts;
f->value.function.name = gfc_get_string ("__spacing_%d", x->ts.kind);
-
- /* Create hidden arguments to the library routine for spacing. These
- hidden arguments are tiny(x), min_exponent - 1, and the precision
- of x. */
-
- k = gfc_validate_kind (BT_REAL, x->ts.kind, false);
-
- tiny = gfc_get_actual_arglist ();
- tiny->name = "tiny";
- tiny->expr = gfc_get_expr ();
- tiny->expr->expr_type = EXPR_CONSTANT;
- tiny->expr->where = gfc_current_locus;
- tiny->expr->ts.type = x->ts.type;
- tiny->expr->ts.kind = x->ts.kind;
- mpfr_init (tiny->expr->value.real);
- mpfr_set (tiny->expr->value.real, gfc_real_kinds[k].tiny, GFC_RND_MODE);
-
- emin_1 = gfc_get_actual_arglist ();
- emin_1->name = "emin";
- emin_1->expr = gfc_int_expr (gfc_real_kinds[k].min_exponent - 1);
-
- /* The library routine expects INTEGER(4). */
- if (emin_1->expr->ts.kind != gfc_c_int_kind)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_INTEGER;
- ts.kind = gfc_c_int_kind;
- gfc_convert_type (emin_1->expr, &ts, 2);
- }
- emin_1->next = tiny;
-
- prec = gfc_get_actual_arglist ();
- prec->name = "prec";
- prec->expr = gfc_int_expr (gfc_real_kinds[k].digits);
-
- /* The library routine expects INTEGER(4). */
- if (prec->expr->ts.kind != gfc_c_int_kind)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_INTEGER;
- ts.kind = gfc_c_int_kind;
- gfc_convert_type (prec->expr, &ts, 2);
- }
- prec->next = emin_1;
-
- f->value.function.actual->next = prec;
}
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 967f634de94..16db1928522 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -65,6 +65,10 @@ Wnonstd-intrinsics
Fortran Warning
Warn about usage of non-standard intrinsics
+Wreturn-type
+Fortran Warning
+; Documented in C
+
Wsurprising
Fortran Warning
Warn about \"suspicious\" constructs
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 7d35fb704ce..ecab0c5850b 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -492,6 +492,10 @@ gfc_handle_option (size_t scode, const char *arg, int value)
gfc_option.warn_line_truncation = value;
break;
+ case OPT_Wreturn_type:
+ warn_return_type = value;
+ break;
+
case OPT_Wsurprising:
gfc_option.warn_surprising = value;
break;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 3df9791c876..ead60f240af 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -106,7 +106,10 @@ resolve_formal_arglist (gfc_symbol *proc)
if (gfc_elemental (proc)
|| sym->attr.pointer || sym->attr.allocatable
|| (sym->as && sym->as->rank > 0))
- proc->attr.always_explicit = 1;
+ {
+ proc->attr.always_explicit = 1;
+ sym->attr.always_explicit = 1;
+ }
formal_arg_flag = 1;
@@ -187,7 +190,11 @@ resolve_formal_arglist (gfc_symbol *proc)
if ((sym->as && sym->as->rank > 0 && sym->as->type == AS_ASSUMED_SHAPE)
|| sym->attr.pointer || sym->attr.allocatable || sym->attr.target
|| sym->attr.optional)
- proc->attr.always_explicit = 1;
+ {
+ proc->attr.always_explicit = 1;
+ if (proc->result)
+ proc->result->attr.always_explicit = 1;
+ }
/* If the flavor is unknown at this point, it has to be a variable.
A procedure specification would have already set the type. */
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index ad3b5158334..b93e1c65478 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -1064,11 +1064,7 @@ gfc_gobble_whitespace (void)
line will be scanned multiple times. */
if (!gfc_option.warn_tabs && c == '\t')
{
-#ifdef USE_MAPPED_LOCATION
int cur_linenum = LOCATION_LINE (gfc_current_locus.lb->location);
-#else
- int cur_linenum = gfc_current_locus.lb->linenum;
-#endif
if (cur_linenum != linenum)
{
linenum = cur_linenum;
@@ -1285,9 +1281,7 @@ get_file (const char *name, enum lc_reason reason ATTRIBUTE_UNUSED)
if (current_file != NULL)
f->inclusion_line = current_file->line;
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, reason, false, f->filename, 1);
-#endif
return f;
}
@@ -1412,10 +1406,8 @@ preprocessor_line (char *c)
add_file_change (NULL, line);
current_file = current_file->up;
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_RENAME, false, current_file->filename,
current_file->line);
-#endif
}
/* The name of the file can be a temporary file produced by
@@ -1645,12 +1637,8 @@ load_file (const char *filename, bool initial)
b = gfc_getmem (gfc_linebuf_header_size + len + 1);
-#ifdef USE_MAPPED_LOCATION
b->location
= linemap_line_start (line_table, current_file->line++, 120);
-#else
- b->linenum = current_file->line++;
-#endif
b->file = current_file;
b->truncated = trunc;
strcpy (b->line, line);
@@ -1674,9 +1662,7 @@ load_file (const char *filename, bool initial)
if (!initial)
add_file_change (NULL, current_file->inclusion_line + 1);
current_file = current_file->up;
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
-#endif
return SUCCESS;
}
@@ -1699,13 +1685,8 @@ gfc_new_file (void)
#if 0 /* Debugging aid. */
for (; line_head; line_head = line_head->next)
gfc_status ("%s:%3d %s\n",
-#ifdef USE_MAPPED_LOCATION
LOCATION_FILE (line_head->location),
LOCATION_LINE (line_head->location),
-#else
- line_head->file->filename,
- line_head->linenum,
-#endif
line_head->line);
exit (0);
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 52393b46bf2..6f430cbc7a6 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -102,10 +102,6 @@ gfc_powdecl_list gfor_fndecl_math_powi[4][3];
tree gfor_fndecl_math_ishftc4;
tree gfor_fndecl_math_ishftc8;
tree gfor_fndecl_math_ishftc16;
-tree gfor_fndecl_math_exponent4;
-tree gfor_fndecl_math_exponent8;
-tree gfor_fndecl_math_exponent10;
-tree gfor_fndecl_math_exponent16;
/* String functions. */
@@ -224,12 +220,7 @@ gfc_get_return_label (void)
void
gfc_set_decl_location (tree decl, locus * loc)
{
-#ifdef USE_MAPPED_LOCATION
DECL_SOURCE_LOCATION (decl) = loc->lb->location;
-#else
- DECL_SOURCE_LINE (decl) = loc->lb->linenum;
- DECL_SOURCE_FILE (decl) = loc->lb->file->filename;
-#endif
}
@@ -2015,10 +2006,6 @@ gfc_build_intrinsic_function_decls (void)
tree gfc_int8_type_node = gfc_get_int_type (8);
tree gfc_int16_type_node = gfc_get_int_type (16);
tree gfc_logical4_type_node = gfc_get_logical_type (4);
- tree gfc_real4_type_node = gfc_get_real_type (4);
- tree gfc_real8_type_node = gfc_get_real_type (8);
- tree gfc_real10_type_node = gfc_get_real_type (10);
- tree gfc_real16_type_node = gfc_get_real_type (16);
/* String functions. */
gfor_fndecl_compare_string =
@@ -2204,25 +2191,6 @@ gfc_build_intrinsic_function_decls (void)
gfc_int4_type_node,
gfc_int4_type_node);
- gfor_fndecl_math_exponent4 =
- gfc_build_library_function_decl (get_identifier (PREFIX("exponent_r4")),
- gfc_int4_type_node,
- 1, gfc_real4_type_node);
- gfor_fndecl_math_exponent8 =
- gfc_build_library_function_decl (get_identifier (PREFIX("exponent_r8")),
- gfc_int4_type_node,
- 1, gfc_real8_type_node);
- if (gfc_real10_type_node)
- gfor_fndecl_math_exponent10 =
- gfc_build_library_function_decl (get_identifier (PREFIX("exponent_r10")),
- gfc_int4_type_node, 1,
- gfc_real10_type_node);
- if (gfc_real16_type_node)
- gfor_fndecl_math_exponent16 =
- gfc_build_library_function_decl (get_identifier (PREFIX("exponent_r16")),
- gfc_int4_type_node, 1,
- gfc_real16_type_node);
-
/* BLAS functions. */
{
tree pint = build_pointer_type (integer_type_node);
@@ -2639,8 +2607,10 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
if (el->sym != el->sym->result)
break;
}
- if (el == NULL)
- warning (0, "Function does not return a value");
+ /* TODO: move to the appropriate place in resolve.c. */
+ if (warn_return_type && el == NULL)
+ gfc_warning ("Return value of function '%s' at %L not set",
+ proc_sym->name, &proc_sym->declared_at);
}
else if (proc_sym->as)
{
@@ -2984,7 +2954,7 @@ generate_local_decl (gfc_symbol * sym)
/* Warn for unused variables, but not if they're inside a common
block or are use-associated. */
else if (warn_unused_variable
- && !(sym->attr.in_common || sym->attr.use_assoc))
+ && !(sym->attr.in_common || sym->attr.use_assoc || sym->mark))
gfc_warning ("Unused variable '%s' declared at %L", sym->name,
&sym->declared_at);
/* For variable length CHARACTER parameters, the PARM_DECL already
@@ -3014,6 +2984,25 @@ generate_local_decl (gfc_symbol * sym)
gfc_warning ("Unused parameter '%s' declared at %L", sym->name,
&sym->declared_at);
}
+ else if (sym->attr.flavor == FL_PROCEDURE)
+ {
+ /* TODO: move to the appropriate place in resolve.c. */
+ if (warn_return_type
+ && sym->attr.function
+ && sym->result
+ && sym != sym->result
+ && !sym->result->attr.referenced
+ && !sym->attr.use_assoc
+ && sym->attr.if_source != IFSRC_IFBODY)
+ {
+ gfc_warning ("Return value '%s' of function '%s' declared at "
+ "%L not set", sym->result->name, sym->name,
+ &sym->result->declared_at);
+
+ /* Prevents "Unused variable" warning for RESULT variables. */
+ sym->mark = sym->result->mark = 1;
+ }
+ }
if (sym->attr.dummy == 1)
{
@@ -3307,10 +3296,17 @@ gfc_generate_function_code (gfc_namespace * ns)
gfc_add_expr_to_block (&block, tmp2);
}
- gfc_add_expr_to_block (&block, tmp);
+ gfc_add_expr_to_block (&block, tmp);
- if (result == NULL_TREE)
- warning (0, "Function return value not set");
+ if (result == NULL_TREE)
+ {
+ /* TODO: move to the appropriate place in resolve.c. */
+ if (warn_return_type && !sym->attr.referenced && sym == sym->result)
+ gfc_warning ("Return value of function '%s' at %L not set",
+ sym->name, &sym->declared_at);
+
+ TREE_NO_WARNING(sym->backend_decl) = 1;
+ }
else
{
/* Set the return value to the dummy result variable. The
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 471f168357a..9b33d378107 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -513,7 +513,8 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
/* Dereference scalar hidden result. */
if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
&& (sym->attr.function || sym->attr.result)
- && !sym->attr.dimension && !sym->attr.pointer)
+ && !sym->attr.dimension && !sym->attr.pointer
+ && !sym->attr.always_explicit)
se->expr = build_fold_indirect_ref (se->expr);
/* Dereference non-character pointer variables.
@@ -1274,6 +1275,7 @@ gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
if ((*expr)->expr_type == EXPR_CONSTANT)
{
gfc_typespec ts;
+ gfc_clear_ts (&ts);
*expr = gfc_int_expr ((int)(*expr)->value.character.string[0]);
if ((*expr)->ts.kind != gfc_c_int_kind)
@@ -2249,6 +2251,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
stringargs = NULL_TREE;
var = NULL_TREE;
len = NULL_TREE;
+ gfc_clear_ts (&ts);
if (sym->from_intmod == INTMOD_ISO_C_BINDING)
{
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 6591b97a316..49f2094561f 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -104,43 +104,19 @@ gfc_intrinsic_map_t;
true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
-#define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
- { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
- END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
- true, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
- NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
-
-#define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
- { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
- END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
- false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
- NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
-
static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
{
/* Functions built into gcc itself. */
#include "mathbuiltins.def"
- /* Functions in libm. */
- /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
- pattern for other mathbuiltins.def entries. At present we have no
- optimizations for this in the common sources. */
- LIBM_FUNCTION (SCALE, "scalbn", false),
-
- /* Functions in libgfortran. */
- LIBF_FUNCTION (FRACTION, "fraction", false),
- LIBF_FUNCTION (NEAREST, "nearest", false),
- LIBF_FUNCTION (RRSPACING, "rrspacing", false),
- LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
- LIBF_FUNCTION (SPACING, "spacing", false),
-
/* End the list. */
- LIBF_FUNCTION (NONE, NULL, false)
+ { GFC_ISYM_NONE, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS,
+ END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS,
+ true, false, true, NULL, NULL_TREE, NULL_TREE, NULL_TREE,
+ NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
};
#undef DEFINE_MATH_BUILTIN
#undef DEFINE_MATH_BUILTIN_C
-#undef LIBM_FUNCTION
-#undef LIBF_FUNCTION
/* Structure for storing components of a floating number to be used by
elemental functions to manipulate reals. */
@@ -727,38 +703,43 @@ gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
se->expr = build_call_array (rettype, fndecl, num_args, args);
}
-/* Generate code for EXPONENT(X) intrinsic function. */
+/* The EXPONENT(s) intrinsic function is translated into
+ int ret;
+ frexp (s, &ret);
+ return ret;
+ */
static void
gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
{
- tree arg, fndecl, type;
- gfc_expr *a1;
-
- gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
+ tree arg, type, res, tmp;
+ int frexp;
- a1 = expr->value.function.actual->expr;
- switch (a1->ts.kind)
+ switch (expr->value.function.actual->expr->ts.kind)
{
case 4:
- fndecl = gfor_fndecl_math_exponent4;
+ frexp = BUILT_IN_FREXPF;
break;
case 8:
- fndecl = gfor_fndecl_math_exponent8;
+ frexp = BUILT_IN_FREXP;
break;
case 10:
- fndecl = gfor_fndecl_math_exponent10;
- break;
case 16:
- fndecl = gfor_fndecl_math_exponent16;
+ frexp = BUILT_IN_FREXPL;
break;
default:
gcc_unreachable ();
}
- /* Convert it to the required type. */
+ gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
+
+ res = gfc_create_var (integer_type_node, NULL);
+ tmp = build_call_expr (built_in_decls[frexp], 2, arg,
+ build_fold_addr_expr (res));
+ gfc_add_expr_to_block (&se->pre, tmp);
+
type = gfc_typenode_for_spec (&expr->ts);
- se->expr = fold_convert (type, build_call_expr (fndecl, 1, arg));
+ se->expr = fold_convert (type, res);
}
/* Evaluate a single upper or lower bound. */
@@ -2823,6 +2804,310 @@ gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
}
+/* FRACTION (s) is translated into frexp (s, &dummy_int). */
+static void
+gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
+{
+ tree arg, type, tmp;
+ int frexp;
+
+ switch (expr->ts.kind)
+ {
+ case 4:
+ frexp = BUILT_IN_FREXPF;
+ break;
+ case 8:
+ frexp = BUILT_IN_FREXP;
+ break;
+ case 10:
+ case 16:
+ frexp = BUILT_IN_FREXPL;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
+ tmp = gfc_create_var (integer_type_node, NULL);
+ se->expr = build_call_expr (built_in_decls[frexp], 2,
+ fold_convert (type, arg),
+ build_fold_addr_expr (tmp));
+ se->expr = fold_convert (type, se->expr);
+}
+
+
+/* NEAREST (s, dir) is translated into
+ tmp = copysign (INF, dir);
+ return nextafter (s, tmp);
+ */
+static void
+gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
+{
+ tree args[2], type, tmp;
+ int nextafter, copysign, inf;
+
+ switch (expr->ts.kind)
+ {
+ case 4:
+ nextafter = BUILT_IN_NEXTAFTERF;
+ copysign = BUILT_IN_COPYSIGNF;
+ inf = BUILT_IN_INFF;
+ break;
+ case 8:
+ nextafter = BUILT_IN_NEXTAFTER;
+ copysign = BUILT_IN_COPYSIGN;
+ inf = BUILT_IN_INF;
+ break;
+ case 10:
+ case 16:
+ nextafter = BUILT_IN_NEXTAFTERL;
+ copysign = BUILT_IN_COPYSIGNL;
+ inf = BUILT_IN_INFL;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ gfc_conv_intrinsic_function_args (se, expr, args, 2);
+ tmp = build_call_expr (built_in_decls[copysign], 2,
+ build_call_expr (built_in_decls[inf], 0),
+ fold_convert (type, args[1]));
+ se->expr = build_call_expr (built_in_decls[nextafter], 2,
+ fold_convert (type, args[0]), tmp);
+ se->expr = fold_convert (type, se->expr);
+}
+
+
+/* SPACING (s) is translated into
+ int e;
+ if (s == 0)
+ res = tiny;
+ else
+ {
+ frexp (s, &e);
+ e = e - prec;
+ e = MAX_EXPR (e, emin);
+ res = scalbn (1., e);
+ }
+ return res;
+
+ where prec is the precision of s, gfc_real_kinds[k].digits,
+ emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
+ and tiny is tiny(s), gfc_real_kinds[k].tiny. */
+
+static void
+gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
+{
+ tree arg, type, prec, emin, tiny, res, e;
+ tree cond, tmp;
+ int frexp, scalbn, k;
+ stmtblock_t block;
+
+ k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
+ prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
+ emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
+ tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind);
+
+ switch (expr->ts.kind)
+ {
+ case 4:
+ frexp = BUILT_IN_FREXPF;
+ scalbn = BUILT_IN_SCALBNF;
+ break;
+ case 8:
+ frexp = BUILT_IN_FREXP;
+ scalbn = BUILT_IN_SCALBN;
+ break;
+ case 10:
+ case 16:
+ frexp = BUILT_IN_FREXPL;
+ scalbn = BUILT_IN_SCALBNL;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
+ arg = gfc_evaluate_now (arg, &se->pre);
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ e = gfc_create_var (integer_type_node, NULL);
+ res = gfc_create_var (type, NULL);
+
+
+ /* Build the block for s /= 0. */
+ gfc_start_block (&block);
+ tmp = build_call_expr (built_in_decls[frexp], 2, arg,
+ build_fold_addr_expr (e));
+ gfc_add_expr_to_block (&block, tmp);
+
+ tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
+ gfc_add_modify_expr (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
+ tmp, emin));
+
+ tmp = build_call_expr (built_in_decls[scalbn], 2,
+ build_real_from_int_cst (type, integer_one_node), e);
+ gfc_add_modify_expr (&block, res, tmp);
+
+ /* Finish by building the IF statement. */
+ cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
+ build_real_from_int_cst (type, integer_zero_node));
+ tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
+ gfc_finish_block (&block));
+
+ gfc_add_expr_to_block (&se->pre, tmp);
+ se->expr = res;
+}
+
+
+/* RRSPACING (s) is translated into
+ int e;
+ real x;
+ x = fabs (s);
+ if (x != 0)
+ {
+ frexp (s, &e);
+ x = scalbn (x, precision - e);
+ }
+ return x;
+
+ where precision is gfc_real_kinds[k].digits. */
+
+static void
+gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
+{
+ tree arg, type, e, x, cond, stmt, tmp;
+ int frexp, scalbn, fabs, prec, k;
+ stmtblock_t block;
+
+ k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
+ prec = gfc_real_kinds[k].digits;
+ switch (expr->ts.kind)
+ {
+ case 4:
+ frexp = BUILT_IN_FREXPF;
+ scalbn = BUILT_IN_SCALBNF;
+ fabs = BUILT_IN_FABSF;
+ break;
+ case 8:
+ frexp = BUILT_IN_FREXP;
+ scalbn = BUILT_IN_SCALBN;
+ fabs = BUILT_IN_FABS;
+ break;
+ case 10:
+ case 16:
+ frexp = BUILT_IN_FREXPL;
+ scalbn = BUILT_IN_SCALBNL;
+ fabs = BUILT_IN_FABSL;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
+ arg = gfc_evaluate_now (arg, &se->pre);
+
+ e = gfc_create_var (integer_type_node, NULL);
+ x = gfc_create_var (type, NULL);
+ gfc_add_modify_expr (&se->pre, x,
+ build_call_expr (built_in_decls[fabs], 1, arg));
+
+
+ gfc_start_block (&block);
+ tmp = build_call_expr (built_in_decls[frexp], 2, arg,
+ build_fold_addr_expr (e));
+ gfc_add_expr_to_block (&block, tmp);
+
+ tmp = fold_build2 (MINUS_EXPR, integer_type_node,
+ build_int_cst (NULL_TREE, prec), e);
+ tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
+ gfc_add_modify_expr (&block, x, tmp);
+ stmt = gfc_finish_block (&block);
+
+ cond = fold_build2 (NE_EXPR, boolean_type_node, x,
+ build_real_from_int_cst (type, integer_zero_node));
+ tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
+ gfc_add_expr_to_block (&se->pre, tmp);
+
+ se->expr = fold_convert (type, x);
+}
+
+
+/* SCALE (s, i) is translated into scalbn (s, i). */
+static void
+gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
+{
+ tree args[2], type;
+ int scalbn;
+
+ switch (expr->ts.kind)
+ {
+ case 4:
+ scalbn = BUILT_IN_SCALBNF;
+ break;
+ case 8:
+ scalbn = BUILT_IN_SCALBN;
+ break;
+ case 10:
+ case 16:
+ scalbn = BUILT_IN_SCALBNL;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ gfc_conv_intrinsic_function_args (se, expr, args, 2);
+ se->expr = build_call_expr (built_in_decls[scalbn], 2,
+ fold_convert (type, args[0]),
+ fold_convert (integer_type_node, args[1]));
+ se->expr = fold_convert (type, se->expr);
+}
+
+
+/* SET_EXPONENT (s, i) is translated into
+ scalbn (frexp (s, &dummy_int), i). */
+static void
+gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
+{
+ tree args[2], type, tmp;
+ int frexp, scalbn;
+
+ switch (expr->ts.kind)
+ {
+ case 4:
+ frexp = BUILT_IN_FREXPF;
+ scalbn = BUILT_IN_SCALBNF;
+ break;
+ case 8:
+ frexp = BUILT_IN_FREXP;
+ scalbn = BUILT_IN_SCALBN;
+ break;
+ case 10:
+ case 16:
+ frexp = BUILT_IN_FREXPL;
+ scalbn = BUILT_IN_SCALBNL;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ gfc_conv_intrinsic_function_args (se, expr, args, 2);
+
+ tmp = gfc_create_var (integer_type_node, NULL);
+ tmp = build_call_expr (built_in_decls[frexp], 2,
+ fold_convert (type, args[0]),
+ build_fold_addr_expr (tmp));
+ se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
+ fold_convert (integer_type_node, args[1]));
+ se->expr = fold_convert (type, se->expr);
+}
+
+
static void
gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
{
@@ -3479,6 +3764,8 @@ gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
else
{
gfc_typespec ts;
+ gfc_clear_ts (&ts);
+
if (actual->expr->ts.kind != gfc_c_int_kind)
{
/* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
@@ -3899,6 +4186,10 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_fdate (se, expr);
break;
+ case GFC_ISYM_FRACTION:
+ gfc_conv_intrinsic_fraction (se, expr);
+ break;
+
case GFC_ISYM_IAND:
gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
break;
@@ -4037,6 +4328,10 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
break;
+ case GFC_ISYM_NEAREST:
+ gfc_conv_intrinsic_nearest (se, expr);
+ break;
+
case GFC_ISYM_NOT:
gfc_conv_intrinsic_not (se, expr);
break;
@@ -4053,6 +4348,18 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
break;
+ case GFC_ISYM_RRSPACING:
+ gfc_conv_intrinsic_rrspacing (se, expr);
+ break;
+
+ case GFC_ISYM_SET_EXPONENT:
+ gfc_conv_intrinsic_set_exponent (se, expr);
+ break;
+
+ case GFC_ISYM_SCALE:
+ gfc_conv_intrinsic_scale (se, expr);
+ break;
+
case GFC_ISYM_SIGN:
gfc_conv_intrinsic_sign (se, expr);
break;
@@ -4065,6 +4372,10 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_sizeof (se, expr);
break;
+ case GFC_ISYM_SPACING:
+ gfc_conv_intrinsic_spacing (se, expr);
+ break;
+
case GFC_ISYM_SUM:
gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
break;
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index d0af3429db4..f5f1df0c7c2 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -851,11 +851,7 @@ set_error_locus (stmtblock_t * block, tree var, locus * where)
str = gfc_build_addr_expr (pchar_type_node, str);
gfc_add_modify_expr (block, locus_file, str);
-#ifdef USE_MAPPED_LOCATION
line = LOCATION_LINE (where->lb->location);
-#else
- line = where->lb->linenum;
-#endif
set_parameter_const (block, var, IOPARM_common_line, line);
}
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 11ef0bf540c..36a7f122c0b 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -382,11 +382,7 @@ gfc_trans_runtime_check (tree cond, stmtblock_t * pblock, locus * where,
if (where)
{
-#ifdef USE_MAPPED_LOCATION
line = LOCATION_LINE (where->lb->location);
-#else
- line = where->lb->linenum;
-#endif
asprintf (&message, "At line %d of file %s", line,
where->lb->file->filename);
}
@@ -940,11 +936,7 @@ void
gfc_get_backend_locus (locus * loc)
{
loc->lb = gfc_getmem (sizeof (gfc_linebuf));
-#ifdef USE_MAPPED_LOCATION
loc->lb->location = input_location;
-#else
- loc->lb->linenum = input_line;
-#endif
loc->lb->file = gfc_current_backend_file;
}
@@ -955,12 +947,7 @@ void
gfc_set_backend_locus (locus * loc)
{
gfc_current_backend_file = loc->lb->file;
-#ifdef USE_MAPPED_LOCATION
input_location = loc->lb->location;
-#else
- input_line = loc->lb->linenum;
- input_filename = loc->lb->file->filename;
-#endif
}
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 72476888e6b..eac320a9e01 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -529,10 +529,6 @@ extern GTY(()) gfc_powdecl_list gfor_fndecl_math_powi[4][3];
extern GTY(()) tree gfor_fndecl_math_ishftc4;
extern GTY(()) tree gfor_fndecl_math_ishftc8;
extern GTY(()) tree gfor_fndecl_math_ishftc16;
-extern GTY(()) tree gfor_fndecl_math_exponent4;
-extern GTY(()) tree gfor_fndecl_math_exponent8;
-extern GTY(()) tree gfor_fndecl_math_exponent10;
-extern GTY(()) tree gfor_fndecl_math_exponent16;
/* BLAS functions. */
extern GTY(()) tree gfor_fndecl_sgemm;
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 8cb5d386702..c9c8b4c32b3 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -718,9 +718,12 @@ gcse_main (rtx f ATTRIBUTE_UNUSED)
/* Don't allow constant propagation to modify jumps
during this pass. */
- timevar_push (TV_CPROP1);
- changed = one_cprop_pass (pass + 1, false, false);
- timevar_pop (TV_CPROP1);
+ if (dbg_cnt (cprop1))
+ {
+ timevar_push (TV_CPROP1);
+ changed = one_cprop_pass (pass + 1, false, false);
+ timevar_pop (TV_CPROP1);
+ }
if (optimize_size)
/* Do nothing. */ ;
@@ -783,13 +786,17 @@ gcse_main (rtx f ATTRIBUTE_UNUSED)
/* Do one last pass of copy propagation, including cprop into
conditional jumps. */
- max_gcse_regno = max_reg_num ();
- alloc_gcse_mem ();
- /* This time, go ahead and allow cprop to alter jumps. */
- timevar_push (TV_CPROP2);
- one_cprop_pass (pass + 1, true, true);
- timevar_pop (TV_CPROP2);
- free_gcse_mem ();
+ if (dbg_cnt (cprop2))
+ {
+ max_gcse_regno = max_reg_num ();
+ alloc_gcse_mem ();
+
+ /* This time, go ahead and allow cprop to alter jumps. */
+ timevar_push (TV_CPROP2);
+ one_cprop_pass (pass + 1, true, true);
+ timevar_pop (TV_CPROP2);
+ free_gcse_mem ();
+ }
if (dump_file)
{
@@ -6666,7 +6673,8 @@ is_too_expensive (const char *pass)
static bool
gate_handle_jump_bypass (void)
{
- return optimize > 0 && flag_gcse;
+ return optimize > 0 && flag_gcse
+ && dbg_cnt (jump_bypass);
}
/* Perform jump bypassing and control flow optimizations. */
@@ -6705,7 +6713,8 @@ struct tree_opt_pass pass_jump_bypass =
static bool
gate_handle_gcse (void)
{
- return optimize > 0 && flag_gcse;
+ return optimize > 0 && flag_gcse
+ && dbg_cnt (gcse);
}
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 7261e71f61f..9109baee4d1 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1,5 +1,5 @@
/* Process source files and output type information.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -521,16 +521,11 @@ do_typedef (const char *s, type_p t, struct fileloc *pos)
{
pair_p p;
- /* temporary kludge - gengtype doesn't handle conditionals or macros.
- Ignore any attempt to typedef CUMULATIVE_ARGS, location_t,
- expanded_location, or source_locus, unless it is coming from
- this file (main() sets them up with safe dummy definitions). */
- if ((!strcmp (s, "CUMULATIVE_ARGS")
- || !strcmp (s, "location_t")
- || !strcmp (s, "source_locus")
- || !strcmp (s, "source_location")
- || !strcmp (s, "expanded_location"))
- && pos->file != this_file)
+ /* temporary kludge - gengtype doesn't handle conditionals or
+ macros. Ignore any attempt to typedef CUMULATIVE_ARGS, unless it
+ is coming from this file (main() sets them up with safe dummy
+ definitions). */
+ if (!strcmp (s, "CUMULATIVE_ARGS") && pos->file != this_file)
return;
for (p = typedefs; p != NULL; p = p->next)
@@ -3480,36 +3475,6 @@ note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
}
-/* Yet more temporary kludge since gengtype doesn't understand conditionals.
- This must be kept in sync with input.h. */
-static void
-define_location_structures (void)
-{
- pair_p fields;
- type_p locs;
- static struct fileloc pos = { this_file, __LINE__ };
- do_scalar_typedef ("source_location", &pos);
-
-#ifdef USE_MAPPED_LOCATION
- fields = create_field (0, &scalar_nonchar, "column");
- fields = create_field (fields, &scalar_nonchar, "line");
- fields = create_field (fields, &string_type, "file");
- locs = new_structure ("anon:expanded_location", 0, &pos, fields, 0);
-
- do_typedef ("expanded_location", locs, &pos);
- do_scalar_typedef ("location_t", &pos);
- do_scalar_typedef ("source_locus", &pos);
-#else
- fields = create_field (0, &scalar_nonchar, "line");
- fields = create_field (fields, &string_type, "file");
- locs = new_structure ("location_s", 0, &pos, fields, 0);
-
- do_typedef ("expanded_location", locs, &pos);
- do_typedef ("location_t", locs, &pos);
- do_typedef ("source_locus", create_pointer (locs), &pos);
-#endif
-}
-
int
main (int argc, char **argv)
@@ -3546,7 +3511,6 @@ main (int argc, char **argv)
do_scalar_typedef ("JCF_u2", &pos); pos.line++;
do_scalar_typedef ("void", &pos); pos.line++;
do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
- define_location_structures ();
for (i = 0; i < num_gt_files; i++)
parse_file (gt_files[i]);
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 302efb55b32..a860dd1caf1 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -1,6 +1,6 @@
/* Tree lowering pass. Lowers GIMPLE into unstructured form.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -108,11 +108,7 @@ lower_function_body (void)
It now fills in for many such returns. Failure to remove this
will result in incorrect results for coverage analysis. */
x = TREE_VALUE (t);
-#ifdef USE_MAPPED_LOCATION
SET_EXPR_LOCATION (x, UNKNOWN_LOCATION);
-#else
- SET_EXPR_LOCUS (x, NULL);
-#endif
tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
}
diff --git a/gcc/graphds.h b/gcc/graphds.h
index 49fe6cd9176..83cf90c2e31 100644
--- a/gcc/graphds.h
+++ b/gcc/graphds.h
@@ -47,6 +47,7 @@ struct graph
int n_vertices; /* Number of vertices. */
struct vertex *vertices;
/* The vertices. */
+ htab_t indices; /* Fast lookup for indices. */
};
struct graph *new_graph (int);
diff --git a/gcc/gthr-dce.h b/gcc/gthr-dce.h
index d876c659e06..e95a4e5c87d 100644
--- a/gcc/gthr-dce.h
+++ b/gcc/gthr-dce.h
@@ -71,6 +71,7 @@ __gthrw(pthread_getspecific)
__gthrw(pthread_setspecific)
__gthrw(pthread_create)
__gthrw(pthread_mutex_init)
+__gthrw(pthread_mutex_destroy)
__gthrw(pthread_mutex_lock)
__gthrw(pthread_mutex_trylock)
__gthrw(pthread_mutex_unlock)
@@ -475,6 +476,15 @@ __gthread_mutex_init_function (__gthread_mutex_t *mutex)
}
static inline int
+__gthread_mutx_destroy (__gthread_mutex_t *mutex)
+{
+ if (__gthread_active_p ())
+ return __gthrw_(pthread_mutex_destroy) (mutex);
+ else
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
if (__gthread_active_p ())
diff --git a/gcc/gthr-mipssde.h b/gcc/gthr-mipssde.h
index 28111e3929e..b8cf24ebc75 100644
--- a/gcc/gthr-mipssde.h
+++ b/gcc/gthr-mipssde.h
@@ -135,6 +135,12 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(mutex))
+{
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
if (__gthread_active_p ())
diff --git a/gcc/gthr-nks.h b/gcc/gthr-nks.h
index 2c2b3e973a5..14027e0871b 100644
--- a/gcc/gthr-nks.h
+++ b/gcc/gthr-nks.h
@@ -342,6 +342,12 @@ __gthread_mutex_init_function (__gthread_mutex_t *mutex)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(mutex))
+{
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
return NXLock (*mutex);
diff --git a/gcc/gthr-posix.h b/gcc/gthr-posix.h
index ad6822e26ad..a6c9ba3b54f 100644
--- a/gcc/gthr-posix.h
+++ b/gcc/gthr-posix.h
@@ -94,6 +94,7 @@ __gthrw3(pthread_mutex_lock)
__gthrw3(pthread_mutex_trylock)
__gthrw3(pthread_mutex_unlock)
__gthrw3(pthread_mutex_init)
+__gthrw3(pthread_mutex_destroy)
__gthrw3(pthread_cond_broadcast)
__gthrw3(pthread_cond_wait)
#else
@@ -106,6 +107,7 @@ __gthrw(pthread_mutex_lock)
__gthrw(pthread_mutex_trylock)
__gthrw(pthread_mutex_unlock)
__gthrw(pthread_mutex_init)
+__gthrw(pthread_mutex_destroy)
__gthrw(pthread_cond_broadcast)
__gthrw(pthread_cond_wait)
#endif
@@ -124,14 +126,12 @@ __gthrw3(pthread_cond_destroy)
__gthrw3(pthread_cond_init)
__gthrw3(pthread_cond_signal)
__gthrw3(pthread_exit)
-__gthrw3(pthread_mutex_destroy)
__gthrw3(pthread_self)
#else
__gthrw(pthread_cond_destroy)
__gthrw(pthread_cond_init)
__gthrw(pthread_cond_signal)
__gthrw(pthread_exit)
-__gthrw(pthread_mutex_destroy)
__gthrw(pthread_self)
#endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
#ifdef _POSIX_PRIORITY_SCHEDULING
@@ -677,6 +677,15 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t *mutex)
+{
+ if (__gthread_active_p ())
+ return __gthrw_(pthread_mutex_destroy) (mutex);
+ else
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
if (__gthread_active_p ())
diff --git a/gcc/gthr-posix95.h b/gcc/gthr-posix95.h
index eb54c925f6f..625f799e8fc 100644
--- a/gcc/gthr-posix95.h
+++ b/gcc/gthr-posix95.h
@@ -80,13 +80,14 @@ __gthrw(pthread_create)
__gthrw(pthread_cancel)
__gthrw(pthread_self)
+__gthrw(pthread_mutex_init)
+__gthrw(pthread_mutex_destroy)
__gthrw(pthread_mutex_lock)
__gthrw(pthread_mutex_trylock)
__gthrw(pthread_mutex_unlock)
__gthrw(pthread_mutexattr_init)
__gthrw(pthread_mutexattr_destroy)
-__gthrw(pthread_mutex_init)
__gthrw(pthread_cond_broadcast)
__gthrw(pthread_cond_wait)
@@ -96,7 +97,6 @@ __gthrw(pthread_cond_destroy)
__gthrw(pthread_cond_init)
__gthrw(pthread_cond_signal)
__gthrw(pthread_exit)
-__gthrw(pthread_mutex_destroy)
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
__gthrw(sched_get_priority_max)
@@ -640,6 +640,15 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t *mutex)
+{
+ if (__gthread_active_p ())
+ return __gthrw_(pthread_mutex_destroy) (mutex);
+ else
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
if (__gthread_active_p ())
diff --git a/gcc/gthr-rtems.h b/gcc/gthr-rtems.h
index f678abac646..425d7dee0e9 100644
--- a/gcc/gthr-rtems.h
+++ b/gcc/gthr-rtems.h
@@ -111,6 +111,12 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(mutex))
+{
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
return rtems_gxx_mutex_lock (mutex);
diff --git a/gcc/gthr-single.h b/gcc/gthr-single.h
index c3a903deb65..7dd1f5471cf 100644
--- a/gcc/gthr-single.h
+++ b/gcc/gthr-single.h
@@ -216,6 +216,12 @@ __gthread_active_p (void)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(mutex))
+{
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t * UNUSED(mutex))
{
return 0;
diff --git a/gcc/gthr-solaris.h b/gcc/gthr-solaris.h
index 5665ecdb4b6..a726bfa1fd9 100644
--- a/gcc/gthr-solaris.h
+++ b/gcc/gthr-solaris.h
@@ -462,6 +462,15 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(mutex))
+{
+ if (__gthread_active_p ())
+ return __gthrw_(mutex_destroy) (mutex);
+ else
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
if (__gthread_active_p ())
diff --git a/gcc/gthr-tpf.h b/gcc/gthr-tpf.h
index b63d527e886..fd80bd49df3 100644
--- a/gcc/gthr-tpf.h
+++ b/gcc/gthr-tpf.h
@@ -92,6 +92,7 @@ __gthrw(pthread_mutexattr_init)
__gthrw(pthread_mutexattr_settype)
__gthrw(pthread_mutexattr_destroy)
__gthrw(pthread_mutex_init)
+__gthrw(pthread_mutex_destroy)
static inline int
__gthread_active_p (void)
@@ -145,6 +146,15 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t *mutex)
+{
+ if (__tpf_pthread_active ())
+ return __gthrw_(pthread_mutex_destroy) (mutex);
+ else
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
if (__tpf_pthread_active ())
diff --git a/gcc/gthr-vxworks.h b/gcc/gthr-vxworks.h
index c11d3a20cab..ba813140d76 100644
--- a/gcc/gthr-vxworks.h
+++ b/gcc/gthr-vxworks.h
@@ -61,6 +61,12 @@ __gthread_mutex_init_function (__gthread_mutex_t *mutex)
}
static inline int
+__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(mutex))
+{
+ return 0;
+}
+
+static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
return semTake (*mutex, WAIT_FOREVER);
diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h
index 6a32c1a134c..b75c8654a08 100644
--- a/gcc/gthr-win32.h
+++ b/gcc/gthr-win32.h
@@ -359,9 +359,6 @@ typedef struct {
__gthread_recursive_mutex_init_function
#define __GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT {-1, 0, 0, 0}
-#define __GTHREAD_MUTEX_DESTROY_FUNCTION \
- __gthread_mutex_destroy_function
-
#if __MINGW32_MAJOR_VERSION >= 1 || \
(__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
#define MINGW32_SUPPORTS_MT_EH 1
@@ -619,7 +616,7 @@ __gthread_mutex_init_function (__gthread_mutex_t *mutex)
}
static inline void
-__gthread_mutex_destroy_function (__gthread_mutex_t *mutex)
+__gthread_mutex_destroy (__gthread_mutex_t *mutex)
{
CloseHandle ((HANDLE) mutex->sema);
}
diff --git a/gcc/gthr.h b/gcc/gthr.h
index a37b9119922..a145ef1a9de 100644
--- a/gcc/gthr.h
+++ b/gcc/gthr.h
@@ -73,6 +73,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
void *__gthread_getspecific (__gthread_key_t key)
int __gthread_setspecific (__gthread_key_t key, const void *ptr)
+ int __gthread_mutex_destroy (__gthread_mutex_t *mutex);
+
int __gthread_mutex_lock (__gthread_mutex_t *mutex);
int __gthread_mutex_trylock (__gthread_mutex_t *mutex);
int __gthread_mutex_unlock (__gthread_mutex_t *mutex);
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 6a53543f5e3..0f12cd04dfa 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -1,6 +1,7 @@
/* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -1835,8 +1836,7 @@ move_insn (rtx insn)
gcc_assert (BB_END (bb) == last);
}
- set_block_for_insn (insn, bb);
- df_insn_change_bb (insn);
+ df_insn_change_bb (insn, bb);
/* Update BB_END, if needed. */
if (BB_END (bb) == last)
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 549c0995768..4fd98d010d3 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -45,6 +45,7 @@
#include "df.h"
#include "vec.h"
#include "vecprim.h"
+#include "dbgcnt.h"
#ifndef HAVE_conditional_execution
#define HAVE_conditional_execution 0
@@ -2244,6 +2245,7 @@ noce_process_if_block (struct noce_if_info *if_info)
|| !NONJUMP_INSN_P (insn_b)
|| (set_b = single_set (insn_b)) == NULL_RTX
|| ! rtx_equal_p (x, SET_DEST (set_b))
+ || ! noce_operand_ok (SET_SRC (set_b))
|| reg_overlap_mentioned_p (x, SET_SRC (set_b))
|| modified_between_p (SET_SRC (set_b),
PREV_INSN (if_info->cond_earliest), jump)
@@ -2289,6 +2291,7 @@ noce_process_if_block (struct noce_if_info *if_info)
if (! noce_operand_ok (a) || ! noce_operand_ok (b))
return FALSE;
+ retry:
/* Set up the info block for our subroutines. */
if_info->insn_a = insn_a;
if_info->insn_b = insn_b;
@@ -2386,6 +2389,13 @@ noce_process_if_block (struct noce_if_info *if_info)
goto success;
}
+ if (!else_bb && set_b)
+ {
+ insn_b = set_b = NULL_RTX;
+ b = orig_x;
+ goto retry;
+ }
+
return FALSE;
success:
@@ -4109,7 +4119,8 @@ if_convert (void)
static bool
gate_handle_if_conversion (void)
{
- return (optimize > 0);
+ return (optimize > 0)
+ && dbg_cnt (if_conversion);
}
/* If-conversion and CFG cleanup. */
@@ -4149,7 +4160,8 @@ struct tree_opt_pass pass_rtl_ifcvt =
static bool
gate_handle_if_after_combine (void)
{
- return (optimize > 0 && flag_if_conversion);
+ return optimize > 0 && flag_if_conversion
+ && dbg_cnt (if_after_combine);
}
@@ -4185,7 +4197,8 @@ struct tree_opt_pass pass_if_after_combine =
static bool
gate_handle_if_after_reload (void)
{
- return (optimize > 0 && flag_if_conversion2);
+ return optimize > 0 && flag_if_conversion2
+ && dbg_cnt (if_after_reload);
}
static unsigned int
diff --git a/gcc/input.h b/gcc/input.h
index c360a1d5312..5d432592315 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -1,6 +1,6 @@
/* Declarations for variables relating to reading the source file.
Used by parsers, lexical analyzers, and error message routines.
- Copyright (C) 1993, 1997, 1998, 2000, 2003, 2004, 2007
+ Copyright (C) 1993, 1997, 1998, 2000, 2003, 2004, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,17 +23,16 @@ along with GCC; see the file COPYING3. If not see
#define GCC_INPUT_H
#include "line-map.h"
+
extern GTY(()) struct line_maps *line_table;
+/* A value which will never be used to represent a real location. */
+#define UNKNOWN_LOCATION ((source_location) 0)
+
/* The location for declarations in "<built-in>" */
#define BUILTINS_LOCATION ((source_location) 2)
-/* Note: if any of the types defined inside this #ifdef are changed,
- gengtype.c:define_location_structures must be updated to match. */
-
-#ifdef USE_MAPPED_LOCATION
-
-typedef struct
+typedef struct GTY (())
{
/* The name of the source file involved. */
const char *file;
@@ -46,67 +45,19 @@ typedef struct
extern expanded_location expand_location (source_location);
-#define UNKNOWN_LOCATION ((source_location) 0)
-typedef source_location location_t; /* deprecated typedef */
-typedef source_location source_locus; /* to be removed */
-
-#define location_from_locus(LOCUS) (LOCUS)
-
-#else /* ! USE_MAPPED_LOCATION */
-
-struct location_s GTY(())
-{
- /* The name of the source file involved. */
- const char *file;
-
- /* The line-location in the source file. */
- int line;
-};
-
-typedef struct location_s expanded_location;
-typedef struct location_s location_t;
-typedef location_t *source_locus;
-
-#define expand_location(FILELINE) (FILELINE)
-extern location_t unknown_location;
-#define UNKNOWN_LOCATION unknown_location
-
-#define location_from_locus(LOCUS) (* (LOCUS))
-
-#endif /* ! USE_MAPPED_LOCATION */
-
-struct file_stack
-{
- struct file_stack *next;
- location_t location;
-};
+/* Historically GCC used location_t, while cpp used source_location.
+ This could be removed but it hardly seems worth the effort. */
+typedef source_location location_t;
/* Top-level source file. */
extern const char *main_input_filename;
extern location_t input_location;
-#ifdef USE_MAPPED_LOCATION
-extern void push_srcloc (location_t);
-#else /* ! USE_MAPPED_LOCATION */
-extern void push_srcloc (const char *name, int line);
-#endif /* ! USE_MAPPED_LOCATION */
-extern void pop_srcloc (void);
-extern void restore_input_file_stack (int);
#define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
#define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
-#define input_line LOCATION_LINE(input_location)
-#define input_filename LOCATION_FILE(input_location)
-
-/* Stack of currently pending input files.
- The line member is not accurate for the innermost file on the stack. */
-extern struct file_stack *input_file_stack;
-
-/* Incremented on each change to input_file_stack. */
-extern int input_file_stack_tick;
-
-/* The number of bits available for input_file_stack_tick. */
-#define INPUT_FILE_STACK_BITS 31
+#define input_line LOCATION_LINE (input_location)
+#define input_filename LOCATION_FILE (input_location)
#endif
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 73a77947a80..eed2fd2c676 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,22 @@
+2008-02-29 Tom Tromey <tromey@redhat.com>
+
+ * expr.c (expand_byte_code): Set DECL_FUNCTION_LAST_LINE on
+ method.
+ * java-tree.h (struct lang_decl_func): Remove obsolete comment.
+
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * lang.c (java_post_options): Remove conditional.
+ * expr.c (expand_byte_code): Remove old location code.
+ * jcf-parse.c (set_source_filename): Remove old location code.
+ (give_name_to_class): Likewise.
+ (jcf_parse): Likewise.
+ (duplicate_class_warning): Likewise.
+ (parse_class_file): Likewise.
+ (java_parse_file): Likewise.
+ * decl.c (finish_method): Remove old location code.
+ * class.c (push_class): Remove old location code.
+
2008-02-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
PR other/35107
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 2aec3a5addf..4eb3360a539 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -1,6 +1,6 @@
/* Functions related to building classes and their related objects.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -479,10 +479,6 @@ push_class (tree class_type, tree class_name)
{
tree decl, signature;
location_t saved_loc = input_location;
-#ifndef USE_MAPPED_LOCATION
- input_filename = "<unknown>";
- input_line = 0;
-#endif
CLASS_P (class_type) = 1;
decl = build_decl (TYPE_DECL, class_name, class_type);
TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 1f0dbf46de6..9f08746154a 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1,7 +1,7 @@
/* Process declarations and variables for the GNU compiler for the
Java(TM) language.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1851,12 +1851,7 @@ finish_method (tree fndecl)
set_cfun (DECL_STRUCT_FUNCTION (fndecl));
else
allocate_struct_function (fndecl, false);
-#ifdef USE_MAPPED_LOCATION
cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl);
-#else
- cfun->function_end_locus.file = DECL_SOURCE_FILE (fndecl);
- cfun->function_end_locus.line = DECL_FUNCTION_LAST_LINE (fndecl);
-#endif
/* Defer inlining and expansion to the cgraph optimizers. */
cgraph_finalize_function (fndecl, false);
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index a482a969235..b113df1de9e 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1,6 +1,6 @@
/* Process expressions for the GNU compiler for the Java(TM) language.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -3132,6 +3132,7 @@ expand_byte_code (JCF *jcf, tree method)
int dead_code_index = -1;
unsigned char* byte_ops;
long length = DECL_CODE_LENGTH (method);
+ location_t max_location = input_location;
stack_pointer = 0;
JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
@@ -3218,11 +3219,9 @@ expand_byte_code (JCF *jcf, tree method)
if (pc == PC)
{
int line = GET_u2 (linenumber_pointer - 2);
-#ifdef USE_MAPPED_LOCATION
input_location = linemap_line_start (line_table, line, 1);
-#else
- input_location.line = line;
-#endif
+ if (input_location > max_location)
+ max_location = input_location;
if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
break;
}
@@ -3242,6 +3241,8 @@ expand_byte_code (JCF *jcf, tree method)
warning (0, "unreachable bytecode from %d to the end of the method",
dead_code_index);
}
+
+ DECL_FUNCTION_LAST_LINE (method) = max_location;
}
static void
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index a19d400d608..494c428db19 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1,7 +1,7 @@
/* Definitions for parsing and type checking for the GNU compiler for
the Java(TM) language.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -793,8 +793,6 @@ struct lang_decl_func GTY(())
int max_locals;
int max_stack;
int arg_slot_count;
- /* A temporary lie for the sake of ggc. Actually, last_line is
- only a source_location if USE_MAPPED_LOCATION. FIXME. */
source_location last_line; /* End line number for a function decl */
tree throws_list; /* Exception specified by `throws' */
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index c3fe5247891..3350191dc34 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -1,6 +1,6 @@
/* Parser for Java(TM) .class files.
Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -327,14 +327,7 @@ set_source_filename (JCF *jcf, int index)
&& strcmp (sfname, old_filename + old_len - new_len) == 0
&& (old_filename[old_len - new_len - 1] == '/'
|| old_filename[old_len - new_len - 1] == '\\'))
- {
-#ifndef USE_MAPPED_LOCATION
- input_filename = find_sourcefile (input_filename);
- DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
- file_start_location = input_location;
-#endif
- return;
- }
+ return;
}
if (strchr (sfname, '/') == NULL && strchr (sfname, '\\') == NULL)
{
@@ -364,13 +357,7 @@ set_source_filename (JCF *jcf, int index)
}
sfname = find_sourcefile (sfname);
-#ifdef USE_MAPPED_LOCATION
line_table->maps[line_table->used-1].to_file = sfname;
-#else
- input_filename = sfname;
- DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
- file_start_location = input_location;
-#endif
if (current_class == main_class) main_input_filename = sfname;
}
@@ -1205,7 +1192,6 @@ give_name_to_class (JCF *jcf, int i)
tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
JPOOL_UTF_LENGTH (jcf, j));
this_class = lookup_class (class_name);
-#ifdef USE_MAPPED_LOCATION
{
tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
const char *sfname = IDENTIFIER_POINTER (source_name);
@@ -1216,14 +1202,6 @@ give_name_to_class (JCF *jcf, int i)
if (main_input_filename == NULL && jcf == main_jcf)
main_input_filename = sfname;
}
-#else
- if (! DECL_ARTIFICIAL (TYPE_NAME (this_class)))
- {
- input_location = DECL_SOURCE_LOCATION (TYPE_NAME (this_class));
- if (main_input_filename == NULL && jcf == main_jcf)
- main_input_filename = input_filename;
- }
-#endif
jcf->cpool.data[i].t = this_class;
JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
@@ -1496,9 +1474,7 @@ jcf_parse (JCF* jcf)
if (TYPE_REFLECTION_DATA (current_class))
annotation_write_byte (JV_DONE_ATTR);
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
-#endif
/* The fields of class_type_node are already in correct order. */
if (current_class != class_type_node && current_class != object_type_node)
@@ -1531,13 +1507,8 @@ static void
duplicate_class_warning (const char *filename)
{
location_t warn_loc;
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_RENAME, 0, filename, 0);
warn_loc = linemap_line_start (line_table, 0, 1);
-#else
- warn_loc.file = filename;
- warn_loc.line = 0;
-#endif
warning (0, "%Hduplicate class will only be compiled once", &warn_loc);
}
@@ -1586,13 +1557,11 @@ parse_class_file (void)
java_layout_seen_class_methods ();
input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
-#ifdef USE_MAPPED_LOCATION
{
/* Re-enter the current file. */
expanded_location loc = expand_location (input_location);
linemap_add (line_table, LC_ENTER, 0, loc.file, loc.line);
}
-#endif
file_start_location = input_location;
(*debug_hooks->start_source_file) (input_line, input_filename);
@@ -1657,13 +1626,8 @@ parse_class_file (void)
if (min_line == 0 || line < min_line)
min_line = line;
}
-#ifdef USE_MAPPED_LOCATION
if (min_line != 0)
input_location = linemap_line_start (line_table, min_line, 1);
-#else
- if (min_line != 0)
- input_line = min_line;
-#endif
}
else
{
@@ -1934,18 +1898,14 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
JCF_ZERO (main_jcf);
main_jcf->read_state = finput;
main_jcf->filbuf = jcf_filbuf_from_stdio;
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_ENTER, false, filename, 0);
input_location = linemap_line_start (line_table, 0, 1);
-#endif
if (open_in_zip (main_jcf, filename, NULL, 0) < 0)
fatal_error ("bad zip/jar file %s", filename);
localToFile = SeenZipFiles;
/* Register all the classes defined there. */
process_zip_dir (main_jcf->read_state);
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
-#endif
parse_zip_file_entries ();
}
else if (magic == (JCF_u4) ZIPEMPTYMAGIC)
@@ -1962,10 +1922,8 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
parse_source_file_1 (real_file, filename, finput);
java_parser_context_restore_global ();
java_pop_parser_context (1);
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
#endif
-#endif
}
}
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index 4dc1f19eda4..76b024ce822 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -1,6 +1,6 @@
/* Java(TM) language-specific utility routines.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -655,10 +655,8 @@ java_post_options (const char **pfilename)
}
}
}
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_ENTER, false, filename, 0);
linemap_add (line_table, LC_RENAME, false, "<built-in>", 0);
-#endif
/* Initialize the compiler back end. */
return false;
diff --git a/gcc/lambda.h b/gcc/lambda.h
index fc28d463e3c..641b3bcaa05 100644
--- a/gcc/lambda.h
+++ b/gcc/lambda.h
@@ -469,5 +469,22 @@ build_linear_expr (tree type, lambda_vector coefs, VEC (tree, heap) *ivs)
return expr;
}
+/* Returns the dependence level for a vector DIST of size LENGTH.
+ LEVEL = 0 means a lexicographic dependence, i.e. a dependence due
+ to the sequence of statements, not carried by any loop. */
+
+
+static inline unsigned
+dependence_level (lambda_vector dist_vect, int length)
+{
+ int i;
+
+ for (i = 0; i < length; i++)
+ if (dist_vect[i] != 0)
+ return i + 1;
+
+ return 0;
+}
+
#endif /* LAMBDA_H */
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index c565daa2d97..2df5c27915d 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -1,5 +1,5 @@
/* Default language-specific hooks.
- Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
@@ -455,14 +455,12 @@ lhd_print_error_function (diagnostic_context *context, const char *file,
pp_newline (context->printer);
if (s.file != NULL)
{
-#ifdef USE_MAPPED_LOCATION
if (flag_show_column && s.column != 0)
pp_printf (context->printer,
_(" inlined from %qs at %s:%d:%d"),
lang_hooks.decl_printable_name (fndecl, 2),
s.file, s.line, s.column);
else
-#endif
pp_printf (context->printer,
_(" inlined from %qs at %s:%d"),
lang_hooks.decl_printable_name (fndecl, 2),
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 792bfe69136..ec1f81008bd 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -84,7 +84,7 @@ __negdi2 (DWtype u)
Wtype
__addvSI3 (Wtype a, Wtype b)
{
- const Wtype w = a + b;
+ const Wtype w = (UWtype) a + (UWtype) b;
if (b >= 0 ? w < a : w > a)
abort ();
@@ -95,7 +95,7 @@ __addvSI3 (Wtype a, Wtype b)
SItype
__addvsi3 (SItype a, SItype b)
{
- const SItype w = a + b;
+ const SItype w = (USItype) a + (USItype) b;
if (b >= 0 ? w < a : w > a)
abort ();
@@ -109,7 +109,7 @@ __addvsi3 (SItype a, SItype b)
DWtype
__addvDI3 (DWtype a, DWtype b)
{
- const DWtype w = a + b;
+ const DWtype w = (UDWtype) a + (UDWtype) b;
if (b >= 0 ? w < a : w > a)
abort ();
@@ -122,7 +122,7 @@ __addvDI3 (DWtype a, DWtype b)
Wtype
__subvSI3 (Wtype a, Wtype b)
{
- const Wtype w = a - b;
+ const Wtype w = (UWtype) a - (UWtype) b;
if (b >= 0 ? w > a : w < a)
abort ();
@@ -133,7 +133,7 @@ __subvSI3 (Wtype a, Wtype b)
SItype
__subvsi3 (SItype a, SItype b)
{
- const SItype w = a - b;
+ const SItype w = (USItype) a - (USItype) b;
if (b >= 0 ? w > a : w < a)
abort ();
@@ -147,7 +147,7 @@ __subvsi3 (SItype a, SItype b)
DWtype
__subvDI3 (DWtype a, DWtype b)
{
- const DWtype w = a - b;
+ const DWtype w = (UDWtype) a - (UDWtype) b;
if (b >= 0 ? w > a : w < a)
abort ();
@@ -187,7 +187,7 @@ __mulvsi3 (SItype a, SItype b)
Wtype
__negvSI2 (Wtype a)
{
- const Wtype w = -a;
+ const Wtype w = -(UWtype) a;
if (a >= 0 ? w > 0 : w < 0)
abort ();
@@ -198,7 +198,7 @@ __negvSI2 (Wtype a)
SItype
__negvsi2 (SItype a)
{
- const SItype w = -a;
+ const SItype w = -(USItype) a;
if (a >= 0 ? w > 0 : w < 0)
abort ();
@@ -212,7 +212,7 @@ __negvsi2 (SItype a)
DWtype
__negvDI2 (DWtype a)
{
- const DWtype w = -a;
+ const DWtype w = -(UDWtype) a;
if (a >= 0 ? w > 0 : w < 0)
abort ();
@@ -231,7 +231,7 @@ __absvSI2 (Wtype a)
#ifdef L_negvsi2
w = __negvSI2 (a);
#else
- w = -a;
+ w = -(UWtype) a;
if (w < 0)
abort ();
@@ -249,7 +249,7 @@ __absvsi2 (SItype a)
#ifdef L_negvsi2
w = __negvsi2 (a);
#else
- w = -a;
+ w = -(USItype) a;
if (w < 0)
abort ();
@@ -270,7 +270,7 @@ __absvDI2 (DWtype a)
#ifdef L_negvdi2
w = __negvDI2 (a);
#else
- w = -a;
+ w = -(UDWtype) a;
if (w < 0)
abort ();
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 3760dcc922d..6a1fc5671b4 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,7 @@
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * objc-act.c (objc_init): Remove old location code.
+
2008-02-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
PR other/35107
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 3d5a83b044e..c8b418ce328 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -1,6 +1,6 @@
/* Implement classes and message passing for Objective C.
Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
Contributed by Steve Naroff.
This file is part of GCC.
@@ -484,13 +484,6 @@ objc_init (void)
#endif
return false;
-#ifndef USE_MAPPED_LOCATION
- /* Force the line number back to 0; check_newline will have
- raised it to 1, which will make the builtin functions appear
- not to be built in. */
- input_line = 0;
-#endif
-
/* If gen_declaration desired, open the output file. */
if (flag_gen_declaration)
{
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index f0bd8e5946c..cd1024406da 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -150,7 +150,7 @@ for (i = 0; i < n_opts; i++) {
len = length (opts[i]);
enum = "OPT_" opts[i]
- if (opts[i] == "finline-limit=")
+ if (opts[i] == "finline-limit=" || opts[i] == "Wlarger-than=")
enum = enum "eq"
gsub ("[^A-Za-z0-9]", "_", enum)
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
index f096112cc90..9aa18a12ad9 100644
--- a/gcc/opth-gen.awk
+++ b/gcc/opth-gen.awk
@@ -160,7 +160,7 @@ for (i = 0; i < n_opts; i++) {
len = length (opts[i]);
enum = "OPT_" opts[i]
- if (opts[i] == "finline-limit=")
+ if (opts[i] == "finline-limit=" || opts[i] == "Wlarger-than=")
enum = enum "eq"
gsub ("[^A-Za-z0-9]", "_", enum)
diff --git a/gcc/opts.c b/gcc/opts.c
index 8bee44b947a..445cec37296 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1540,6 +1540,11 @@ common_handle_option (size_t scode, const char *arg, int value,
break;
case OPT_Wlarger_than_:
+ /* This form corresponds to -Wlarger-than-.
+ Kept for backward compatibility.
+ Don't use it as the first argument of warning(). */
+
+ case OPT_Wlarger_than_eq:
larger_than_size = value;
warn_larger_than = value != -1;
break;
diff --git a/gcc/passes.c b/gcc/passes.c
index af499a80ed2..76fd58ba372 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -629,6 +629,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_empty_loop);
NEXT_PASS (pass_record_bounds);
NEXT_PASS (pass_check_data_deps);
+ NEXT_PASS (pass_loop_distribution);
NEXT_PASS (pass_linear_transform);
NEXT_PASS (pass_iv_canon);
NEXT_PASS (pass_if_conversion);
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 8f2ca7555c8..7df81616d51 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -1,6 +1,6 @@
/* Prints out tree in human readable form - GCC
Copyright (C) 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -442,10 +442,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
xloc = expand_location (DECL_SOURCE_LOCATION (node));
- fprintf (file, " file %s line %d", xloc.file, xloc.line);
-#ifdef USE_MAPPED_LOCATION
- fprintf (file, " col %d", xloc.column);
-#endif
+ fprintf (file, " file %s line %d col %d", xloc.file, xloc.line,
+ xloc.column);
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
@@ -949,10 +947,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
{
expanded_location xloc = expand_location (EXPR_LOCATION (node));
indent_to (file, indent+4);
- fprintf (file, "%s:%d", xloc.file, xloc.line);
-#ifdef USE_MAPPED_LOCATION
- fprintf (file, ":%d", xloc.column);
-#endif
+ fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
}
fprintf (file, ">");
diff --git a/gcc/profile.c b/gcc/profile.c
index 51747cf4314..a4f46b3ad4d 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -1,6 +1,6 @@
/* Calculate branch probabilities, and basic block execution counts.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2007
+ 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
based on some ideas from Dain Samples of UC Berkeley.
@@ -814,15 +814,10 @@ branch_prob (void)
if (last && EXPR_LOCUS (last)
&& e->goto_locus
&& !single_succ_p (bb)
-#ifdef USE_MAPPED_LOCATION
&& (LOCATION_FILE (e->goto_locus)
!= LOCATION_FILE (EXPR_LOCATION (last))
|| (LOCATION_LINE (e->goto_locus)
!= LOCATION_LINE (EXPR_LOCATION (last)))))
-#else
- && (e->goto_locus->file != EXPR_LOCUS (last)->file
- || (e->goto_locus->line != EXPR_LOCUS (last)->line)))
-#endif
{
basic_block new = split_edge (e);
single_succ_edge (new)->goto_locus = e->goto_locus;
@@ -1020,16 +1015,10 @@ branch_prob (void)
CFG. */
if (single_succ_p (bb) && single_succ_edge (bb)->goto_locus)
{
- /* ??? source_locus type is marked deprecated in input.h. */
- source_locus curr_location = single_succ_edge (bb)->goto_locus;
+ location_t curr_location = single_succ_edge (bb)->goto_locus;
/* ??? The FILE/LINE API is inconsistent for these cases. */
-#ifdef USE_MAPPED_LOCATION
output_location (LOCATION_FILE (curr_location),
LOCATION_LINE (curr_location), &offset, bb);
-#else
- output_location (curr_location->file, curr_location->line,
- &offset, bb);
-#endif
}
if (offset)
diff --git a/gcc/recog.c b/gcc/recog.c
index 6a9ae4510c0..2629adc3229 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1,6 +1,6 @@
/* Subroutines used by or related to instruction recognition.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -1490,14 +1490,7 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
}
if (loc)
- {
-#ifdef USE_MAPPED_LOCATION
- *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
-#else
- loc->file = ASM_OPERANDS_SOURCE_FILE (asmop);
- loc->line = ASM_OPERANDS_SOURCE_LINE (asmop);
-#endif
- }
+ *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
return ASM_OPERANDS_TEMPLATE (asmop);
}
diff --git a/gcc/rtl-error.c b/gcc/rtl-error.c
index c1166fdb84b..6f38631b71e 100644
--- a/gcc/rtl-error.c
+++ b/gcc/rtl-error.c
@@ -1,5 +1,5 @@
/* RTL specific diagnostic subroutines for GCC
- Copyright (C) 2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
This file is part of GCC.
@@ -58,14 +58,7 @@ location_for_asm (const_rtx insn)
asmop = NULL;
if (asmop)
-#ifdef USE_MAPPED_LOCATION
loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
-#else
- {
- loc.file = ASM_OPERANDS_SOURCE_FILE (asmop);
- loc.line = ASM_OPERANDS_SOURCE_LINE (asmop);
- }
-#endif
else
loc = input_location;
return loc;
diff --git a/gcc/rtl.def b/gcc/rtl.def
index fa2238c58b7..33bf6bd1879 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -2,7 +2,7 @@
Register Transfer Expressions (rtx's) that make up the
Register Transfer Language (rtl) used in the Back End of the GNU compiler.
Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2004,
- 2005, 2006, 2007
+ 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -159,7 +159,6 @@ DEF_RTL_EXPR(COND_EXEC, "cond_exec", "ee", RTX_EXTRA)
/* Several operations to be done in parallel (perhaps under COND_EXEC). */
DEF_RTL_EXPR(PARALLEL, "parallel", "E", RTX_EXTRA)
-#ifdef USE_MAPPED_LOCATION
/* A string that is passed through to the assembler as input.
One can obviously pass comments through by using the
assembler comment syntax.
@@ -180,29 +179,6 @@ DEF_RTL_EXPR(ASM_INPUT, "asm_input", "si", RTX_EXTRA)
and whose mode indicates the mode of the input operand.
6th is the source line number. */
DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEi", RTX_EXTRA)
-#else
-/* A string that is passed through to the assembler as input.
- One can obviously pass comments through by using the
- assembler comment syntax.
- These occur in an insn all by themselves as the PATTERN.
- They also appear inside an ASM_OPERANDS
- as a convenient way to hold a string. */
-DEF_RTL_EXPR(ASM_INPUT, "asm_input", "ssi", RTX_EXTRA)
-
-/* An assembler instruction with operands.
- 1st operand is the instruction template.
- 2nd operand is the constraint for the output.
- 3rd operand is the number of the output this expression refers to.
- When an insn stores more than one value, a separate ASM_OPERANDS
- is made for each output; this integer distinguishes them.
- 4th is a vector of values of input operands.
- 5th is a vector of modes and constraints for the input operands.
- Each element is an ASM_INPUT containing a constraint string
- and whose mode indicates the mode of the input operand.
- 6th is the name of the containing source file.
- 7th is the source line number. */
-DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEsi", RTX_EXTRA)
-#endif
/* A machine-specific operation.
1st operand is a vector of operands being used by the operation so that
diff --git a/gcc/rtl.h b/gcc/rtl.h
index f4aa35a387b..604d0967895 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1,6 +1,6 @@
/* Register Transfer Language (RTL) definitions for GCC
Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -1114,15 +1114,8 @@ do { \
XSTR (XCVECEXP (RTX, 4, N, ASM_OPERANDS), 0)
#define ASM_OPERANDS_INPUT_MODE(RTX, N) \
GET_MODE (XCVECEXP (RTX, 4, N, ASM_OPERANDS))
-#ifdef USE_MAPPED_LOCATION
#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 5, ASM_OPERANDS)
#define ASM_INPUT_SOURCE_LOCATION(RTX) XCUINT (RTX, 1, ASM_INPUT)
-#else
-#define ASM_OPERANDS_SOURCE_FILE(RTX) XCSTR (RTX, 5, ASM_OPERANDS)
-#define ASM_OPERANDS_SOURCE_LINE(RTX) XCINT (RTX, 6, ASM_OPERANDS)
-#define ASM_INPUT_SOURCE_FILE(RTX) XCSTR (RTX, 1, ASM_INPUT)
-#define ASM_INPUT_SOURCE_LINE(RTX) XCINT (RTX, 2, ASM_INPUT)
-#endif
/* 1 if RTX is a mem that is statically allocated in read-only memory. */
#define MEM_READONLY_P(RTX) \
@@ -1892,20 +1885,10 @@ extern GTY(()) rtx return_address_pointer_rtx;
#ifndef GENERATOR_FILE
#include "genrtl.h"
#undef gen_rtx_ASM_INPUT
-#ifdef USE_MAPPED_LOCATION
#define gen_rtx_ASM_INPUT(MODE, ARG0) \
gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), 0)
#define gen_rtx_ASM_INPUT_loc(MODE, ARG0, LOC) \
gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), (LOC))
-#else
-#define gen_rtx_ASM_INPUT(MODE, ARG0) \
- gen_rtx_fmt_ssi (ASM_INPUT, (MODE), (ARG0), "", 0)
-#define gen_rtx_ASM_INPUT_loc(MODE, ARG0, LOC) \
- gen_rtx_fmt_ssi (ASM_INPUT, (MODE), (ARG0), (LOC).file, (LOC).line)
-#undef gen_rtx_ASM_OPERANDS
-#define gen_rtx_ASM_OPERANDS(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, LOC) \
- gen_rtx_fmt_ssiEEsi (ASM_OPERANDS, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (LOC).file, (LOC).line)
-#endif
#endif
/* There are some RTL codes that require special attention; the
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d9e60d3b1ab..804d6c88e5c 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2989,16 +2989,15 @@ loc_mentioned_in_p (rtx *loc, const_rtx in)
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
- if (loc == &in->u.fld[i].rt_rtx)
- return 1;
if (fmt[i] == 'e')
{
- if (loc_mentioned_in_p (loc, XEXP (in, i)))
+ if (loc == &XEXP (in, i) || loc_mentioned_in_p (loc, XEXP (in, i)))
return 1;
}
else if (fmt[i] == 'E')
for (j = XVECLEN (in, i) - 1; j >= 0; j--)
- if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
+ if (loc == &XVECEXP (in, i, j)
+ || loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
return 1;
}
return 0;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 03fbc750dcf..34392dce48a 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -859,8 +859,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
if (GET_CODE (op) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op)
&& ! SUBREG_PROMOTED_UNSIGNED_P (op)
- && GET_MODE (XEXP (op, 0)) == mode)
- return XEXP (op, 0);
+ && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+ return rtl_hooks.gen_lowpart_no_emit (mode, op);
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
if (! POINTERS_EXTEND_UNSIGNED
@@ -881,8 +881,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
if (GET_CODE (op) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op)
&& SUBREG_PROMOTED_UNSIGNED_P (op) > 0
- && GET_MODE (XEXP (op, 0)) == mode)
- return XEXP (op, 0);
+ && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+ return rtl_hooks.gen_lowpart_no_emit (mode, op);
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
if (POINTERS_EXTEND_UNSIGNED > 0
@@ -5021,7 +5021,22 @@ simplify_subreg (enum machine_mode outermode, rtx op,
return newx;
if (validate_subreg (outermode, innermostmode,
SUBREG_REG (op), final_offset))
- return gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
+ {
+ newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
+ if (SUBREG_PROMOTED_VAR_P (op)
+ && SUBREG_PROMOTED_UNSIGNED_P (op) >= 0
+ && GET_MODE_CLASS (outermode) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (outermode),
+ GET_MODE_SIZE (innermode),
+ GET_MODE_SIZE (innermostmode))
+ && subreg_lowpart_p (newx))
+ {
+ SUBREG_PROMOTED_VAR_P (newx) = 1;
+ SUBREG_PROMOTED_UNSIGNED_SET
+ (newx, SUBREG_PROMOTED_UNSIGNED_P (op));
+ }
+ return newx;
+ }
return NULL_RTX;
}
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index a7bcd054400..67e4c25fbdc 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -464,9 +464,9 @@ layout_decl (tree decl, unsigned int known_align)
int size_as_int = TREE_INT_CST_LOW (size);
if (compare_tree_int (size, size_as_int) == 0)
- warning (OPT_Wlarger_than_, "size of %q+D is %d bytes", decl, size_as_int);
+ warning (OPT_Wlarger_than_eq, "size of %q+D is %d bytes", decl, size_as_int);
else
- warning (OPT_Wlarger_than_, "size of %q+D is larger than %wd bytes",
+ warning (OPT_Wlarger_than_eq, "size of %q+D is larger than %wd bytes",
decl, larger_than_size);
}
}
diff --git a/gcc/struct-equiv.c b/gcc/struct-equiv.c
deleted file mode 100644
index 6675e5bf71b..00000000000
--- a/gcc/struct-equiv.c
+++ /dev/null
@@ -1,1339 +0,0 @@
-/* Control flow optimization code for GNU compiler.
- Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-/* Try to match two basic blocks - or their ends - for structural equivalence.
- We scan the blocks from their ends backwards, and expect that insns are
- identical, except for certain cases involving registers. A mismatch
- We scan the blocks from their ends backwards, hoping to find a match, I.e.
- insns are identical, except for certain cases involving registers. A
- mismatch between register number RX (used in block X) and RY (used in the
- same way in block Y) can be handled in one of the following cases:
- 1. RX and RY are local to their respective blocks; they are set there and
- die there. If so, they can effectively be ignored.
- 2. RX and RY die in their blocks, but live at the start. If any path
- gets redirected through X instead of Y, the caller must emit
- compensation code to move RY to RX. If there are overlapping inputs,
- the function resolve_input_conflict ensures that this can be done.
- Information about these registers are tracked in the X_LOCAL, Y_LOCAL,
- LOCAL_COUNT and LOCAL_RVALUE fields.
- 3. RX and RY live throughout their blocks, including the start and the end.
- Either RX and RY must be identical, or we have to replace all uses in
- block X with a new pseudo, which is stored in the INPUT_REG field. The
- caller can then use block X instead of block Y by copying RY to the new
- pseudo.
-
- The main entry point to this file is struct_equiv_block_eq. This function
- uses a struct equiv_info to accept some of its inputs, to keep track of its
- internal state, to pass down to its helper functions, and to communicate
- some of the results back to the caller.
-
- Most scans will result in a failure to match a sufficient number of insns
- to make any optimization worth while, therefore the process is geared more
- to quick scanning rather than the ability to exactly backtrack when we
- find a mismatch. The information gathered is still meaningful to make a
- preliminary decision if we want to do an optimization, we might only
- slightly overestimate the number of matchable insns, and underestimate
- the number of inputs an miss an input conflict. Sufficient information
- is gathered so that when we make another pass, we won't have to backtrack
- at the same point.
- Another issue is that information in memory attributes and/or REG_NOTES
- might have to be merged or discarded to make a valid match. We don't want
- to discard such information when we are not certain that we want to merge
- the two (partial) blocks.
- For these reasons, struct_equiv_block_eq has to be called first with the
- STRUCT_EQUIV_START bit set in the mode parameter. This will calculate the
- number of matched insns and the number and types of inputs. If the
- need_rerun field is set, the results are only tentative, and the caller
- has to call again with STRUCT_EQUIV_RERUN till need_rerun is false in
- order to get a reliable match.
- To install the changes necessary for the match, the function has to be
- called again with STRUCT_EQUIV_FINAL.
-
- While scanning an insn, we process first all the SET_DESTs, then the
- SET_SRCes, then the REG_NOTES, in order to keep the register liveness
- information consistent.
- If we were to mix up the order for sources / destinations in an insn where
- a source is also a destination, we'd end up being mistaken to think that
- the register is not live in the preceding insn. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "rtl.h"
-#include "regs.h"
-#include "output.h"
-#include "insn-config.h"
-#include "flags.h"
-#include "recog.h"
-#include "tm_p.h"
-#include "target.h"
-#include "emit-rtl.h"
-#include "reload.h"
-#include "df.h"
-
-static void merge_memattrs (rtx, rtx);
-static bool set_dest_equiv_p (rtx x, rtx y, struct equiv_info *info);
-static bool set_dest_addr_equiv_p (rtx x, rtx y, struct equiv_info *info);
-static void find_dying_inputs (struct equiv_info *info);
-static bool resolve_input_conflict (struct equiv_info *info);
-
-/* After reload, some moves, as indicated by SECONDARY_RELOAD_CLASS and
- SECONDARY_MEMORY_NEEDED, cannot be done directly. For our purposes, we
- consider them impossible to generate after reload (even though some
- might be synthesized when you throw enough code at them).
- Since we don't know while processing a cross-jump if a local register
- that is currently live will eventually be live and thus be an input,
- we keep track of potential inputs that would require an impossible move
- by using a prohibitively high cost for them.
- This number, multiplied with the larger of STRUCT_EQUIV_MAX_LOCAL and
- FIRST_PSEUDO_REGISTER, must fit in the input_cost field of
- struct equiv_info. */
-#define IMPOSSIBLE_MOVE_FACTOR 20000
-
-
-
-/* Removes the memory attributes of MEM expression
- if they are not equal. */
-
-void
-merge_memattrs (rtx x, rtx y)
-{
- int i;
- int j;
- enum rtx_code code;
- const char *fmt;
-
- if (x == y)
- return;
- if (x == 0 || y == 0)
- return;
-
- code = GET_CODE (x);
-
- if (code != GET_CODE (y))
- return;
-
- if (GET_MODE (x) != GET_MODE (y))
- return;
-
- if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y))
- {
- if (! MEM_ATTRS (x))
- MEM_ATTRS (y) = 0;
- else if (! MEM_ATTRS (y))
- MEM_ATTRS (x) = 0;
- else
- {
- rtx mem_size;
-
- if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
- {
- set_mem_alias_set (x, 0);
- set_mem_alias_set (y, 0);
- }
-
- if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
- {
- set_mem_expr (x, 0);
- set_mem_expr (y, 0);
- set_mem_offset (x, 0);
- set_mem_offset (y, 0);
- }
- else if (MEM_OFFSET (x) != MEM_OFFSET (y))
- {
- set_mem_offset (x, 0);
- set_mem_offset (y, 0);
- }
-
- if (!MEM_SIZE (x))
- mem_size = NULL_RTX;
- else if (!MEM_SIZE (y))
- mem_size = NULL_RTX;
- else
- mem_size = GEN_INT (MAX (INTVAL (MEM_SIZE (x)),
- INTVAL (MEM_SIZE (y))));
- set_mem_size (x, mem_size);
- set_mem_size (y, mem_size);
-
- set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
- set_mem_align (y, MEM_ALIGN (x));
- }
- }
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- switch (fmt[i])
- {
- case 'E':
- /* Two vectors must have the same length. */
- if (XVECLEN (x, i) != XVECLEN (y, i))
- return;
-
- for (j = 0; j < XVECLEN (x, i); j++)
- merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
-
- break;
-
- case 'e':
- merge_memattrs (XEXP (x, i), XEXP (y, i));
- }
- }
- return;
-}
-
-/* In SET, assign the bit for the register number of REG the value VALUE.
- If REG is a hard register, do so for all its constituent registers.
- Return the number of registers that have become included (as a positive
- number) or excluded (as a negative number). */
-static int
-assign_reg_reg_set (regset set, rtx reg, int value)
-{
- unsigned regno = REGNO (reg);
- int nregs, i, old;
-
- if (regno >= FIRST_PSEUDO_REGISTER)
- {
- gcc_assert (!reload_completed);
- nregs = 1;
- }
- else
- nregs = hard_regno_nregs[regno][GET_MODE (reg)];
- for (old = 0, i = nregs; --i >= 0; regno++)
- {
- if ((value != 0) == REGNO_REG_SET_P (set, regno))
- continue;
- if (value)
- old++, SET_REGNO_REG_SET (set, regno);
- else
- old--, CLEAR_REGNO_REG_SET (set, regno);
- }
- return old;
-}
-
-/* Record state about current inputs / local registers / liveness
- in *P. */
-static inline void
-struct_equiv_make_checkpoint (struct struct_equiv_checkpoint *p,
- struct equiv_info *info)
-{
- *p = info->cur;
-}
-
-/* Call struct_equiv_make_checkpoint (P, INFO) if the current partial block
- is suitable to split off - i.e. there is no dangling cc0 user - and
- if the current cost of the common instructions, minus the cost for
- setting up the inputs, is higher than what has been recorded before
- in CHECKPOINT[N]. Also, if we do so, confirm or cancel any pending
- changes. */
-static void
-struct_equiv_improve_checkpoint (struct struct_equiv_checkpoint *p,
- struct equiv_info *info)
-{
-#ifdef HAVE_cc0
- if (reg_mentioned_p (cc0_rtx, info->cur.x_start)
- && !sets_cc0_p (info->cur.x_start))
- return;
-#endif
- if (info->cur.input_count >= IMPOSSIBLE_MOVE_FACTOR)
- return;
- if (info->input_cost >= 0
- ? (COSTS_N_INSNS(info->cur.ninsns - p->ninsns)
- > info->input_cost * (info->cur.input_count - p->input_count))
- : info->cur.ninsns > p->ninsns && !info->cur.input_count)
- {
- if (info->check_input_conflict && ! resolve_input_conflict (info))
- return;
- /* We have a profitable set of changes. If this is the final pass,
- commit them now. Otherwise, we don't know yet if we can make any
- change, so put the old code back for now. */
- if (info->mode & STRUCT_EQUIV_FINAL)
- confirm_change_group ();
- else
- cancel_changes (0);
- struct_equiv_make_checkpoint (p, info);
- }
-}
-
-/* Restore state about current inputs / local registers / liveness
- from P. */
-static void
-struct_equiv_restore_checkpoint (struct struct_equiv_checkpoint *p,
- struct equiv_info *info)
-{
- info->cur.ninsns = p->ninsns;
- info->cur.x_start = p->x_start;
- info->cur.y_start = p->y_start;
- info->cur.input_count = p->input_count;
- info->cur.input_valid = p->input_valid;
- while (info->cur.local_count > p->local_count)
- {
- info->cur.local_count--;
- info->cur.version--;
- if (REGNO_REG_SET_P (info->x_local_live,
- REGNO (info->x_local[info->cur.local_count])))
- {
- assign_reg_reg_set (info->x_local_live,
- info->x_local[info->cur.local_count], 0);
- assign_reg_reg_set (info->y_local_live,
- info->y_local[info->cur.local_count], 0);
- info->cur.version--;
- }
- }
- if (info->cur.version != p->version)
- info->need_rerun = true;
-}
-
-
-/* Update register liveness to reflect that X is now life (if rvalue is
- nonzero) or dead (if rvalue is zero) in INFO->x_block, and likewise Y
- in INFO->y_block. Return the number of registers the liveness of which
- changed in each block (as a negative number if registers became dead). */
-static int
-note_local_live (struct equiv_info *info, rtx x, rtx y, int rvalue)
-{
- unsigned x_regno = REGNO (x);
- unsigned y_regno = REGNO (y);
- int x_nominal_nregs = (x_regno >= FIRST_PSEUDO_REGISTER
- ? 1 : hard_regno_nregs[x_regno][GET_MODE (x)]);
- int y_nominal_nregs = (y_regno >= FIRST_PSEUDO_REGISTER
- ? 1 : hard_regno_nregs[y_regno][GET_MODE (y)]);
- int x_change = assign_reg_reg_set (info->x_local_live, x, rvalue);
- int y_change = assign_reg_reg_set (info->y_local_live, y, rvalue);
-
- gcc_assert (x_nominal_nregs && y_nominal_nregs);
- gcc_assert (x_change * y_nominal_nregs == y_change * x_nominal_nregs);
- if (y_change)
- {
- if (reload_completed)
- {
- unsigned x_regno ATTRIBUTE_UNUSED = REGNO (x);
- unsigned y_regno ATTRIBUTE_UNUSED = REGNO (y);
- enum machine_mode x_mode = GET_MODE (x);
-
- if (secondary_reload_class (0, REGNO_REG_CLASS (y_regno), x_mode, x)
- != NO_REGS
-#ifdef SECONDARY_MEMORY_NEEDED
- || SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (y_regno),
- REGNO_REG_CLASS (x_regno), x_mode)
-#endif
- )
- y_change *= IMPOSSIBLE_MOVE_FACTOR;
- }
- info->cur.input_count += y_change;
- info->cur.version++;
- }
- return x_change;
-}
-
-/* Check if *XP is equivalent to Y. Until an unreconcilable difference is
- found, use in-group changes with validate_change on *XP to make register
- assignments agree. It is the (not necessarily direct) callers
- responsibility to verify / confirm / cancel these changes, as appropriate.
- RVALUE indicates if the processed piece of rtl is used as a destination, in
- which case we can't have different registers being an input. Returns
- nonzero if the two blocks have been identified as equivalent, zero otherwise.
- RVALUE == 0: destination
- RVALUE == 1: source
- RVALUE == -1: source, ignore SET_DEST of SET / clobber. */
-bool
-rtx_equiv_p (rtx *xp, rtx y, int rvalue, struct equiv_info *info)
-{
- rtx x = *xp;
- enum rtx_code code;
- int length;
- const char *format;
- int i;
-
- if (!y || !x)
- return x == y;
- code = GET_CODE (y);
- if (code != REG && x == y)
- return true;
- if (GET_CODE (x) != code
- || GET_MODE (x) != GET_MODE (y))
- return false;
-
- /* ??? could extend to allow CONST_INT inputs. */
- switch (code)
- {
- case REG:
- {
- unsigned x_regno = REGNO (x);
- unsigned y_regno = REGNO (y);
- int x_common_live, y_common_live;
-
- if (reload_completed
- && (x_regno >= FIRST_PSEUDO_REGISTER
- || y_regno >= FIRST_PSEUDO_REGISTER))
- {
- /* We should only see this in REG_NOTEs. */
- gcc_assert (!info->live_update);
- /* Returning false will cause us to remove the notes. */
- return false;
- }
-#ifdef STACK_REGS
- /* After reg-stack, can only accept literal matches of stack regs. */
- if (info->mode & CLEANUP_POST_REGSTACK
- && (IN_RANGE (x_regno, FIRST_STACK_REG, LAST_STACK_REG)
- || IN_RANGE (y_regno, FIRST_STACK_REG, LAST_STACK_REG)))
- return x_regno == y_regno;
-#endif
-
- /* If the register is a locally live one in one block, the
- corresponding one must be locally live in the other, too, and
- match of identical regnos doesn't apply. */
- if (REGNO_REG_SET_P (info->x_local_live, x_regno))
- {
- if (!REGNO_REG_SET_P (info->y_local_live, y_regno))
- return false;
- }
- else if (REGNO_REG_SET_P (info->y_local_live, y_regno))
- return false;
- else if (x_regno == y_regno)
- {
- if (!rvalue && info->cur.input_valid
- && (reg_overlap_mentioned_p (x, info->x_input)
- || reg_overlap_mentioned_p (x, info->y_input)))
- return false;
-
- /* Update liveness information. */
- if (info->live_update
- && assign_reg_reg_set (info->common_live, x, rvalue))
- info->cur.version++;
-
- return true;
- }
-
- x_common_live = REGNO_REG_SET_P (info->common_live, x_regno);
- y_common_live = REGNO_REG_SET_P (info->common_live, y_regno);
- if (x_common_live != y_common_live)
- return false;
- else if (x_common_live)
- {
- if (! rvalue || info->input_cost < 0 || reload_completed)
- return false;
- /* If info->live_update is not set, we are processing notes.
- We then allow a match with x_input / y_input found in a
- previous pass. */
- if (info->live_update && !info->cur.input_valid)
- {
- info->cur.input_valid = true;
- info->x_input = x;
- info->y_input = y;
- info->cur.input_count += optimize_size ? 2 : 1;
- if (info->input_reg
- && GET_MODE (info->input_reg) != GET_MODE (info->x_input))
- info->input_reg = NULL_RTX;
- if (!info->input_reg)
- info->input_reg = gen_reg_rtx (GET_MODE (info->x_input));
- }
- else if ((info->live_update
- ? ! info->cur.input_valid : ! info->x_input)
- || ! rtx_equal_p (x, info->x_input)
- || ! rtx_equal_p (y, info->y_input))
- return false;
- validate_change (info->cur.x_start, xp, info->input_reg, 1);
- }
- else
- {
- int x_nregs = (x_regno >= FIRST_PSEUDO_REGISTER
- ? 1 : hard_regno_nregs[x_regno][GET_MODE (x)]);
- int y_nregs = (y_regno >= FIRST_PSEUDO_REGISTER
- ? 1 : hard_regno_nregs[y_regno][GET_MODE (y)]);
- int size = GET_MODE_SIZE (GET_MODE (x));
- enum machine_mode x_mode = GET_MODE (x);
- unsigned x_regno_i, y_regno_i;
- int x_nregs_i, y_nregs_i, size_i;
- int local_count = info->cur.local_count;
-
- /* This might be a register local to each block. See if we have
- it already registered. */
- for (i = local_count - 1; i >= 0; i--)
- {
- x_regno_i = REGNO (info->x_local[i]);
- x_nregs_i = (x_regno_i >= FIRST_PSEUDO_REGISTER
- ? 1 : hard_regno_nregs[x_regno_i][GET_MODE (x)]);
- y_regno_i = REGNO (info->y_local[i]);
- y_nregs_i = (y_regno_i >= FIRST_PSEUDO_REGISTER
- ? 1 : hard_regno_nregs[y_regno_i][GET_MODE (y)]);
- size_i = GET_MODE_SIZE (GET_MODE (info->x_local[i]));
-
- /* If we have a new pair of registers that is wider than an
- old pair and enclosing it with matching offsets,
- remove the old pair. If we find a matching, wider, old
- pair, use the old one. If the width is the same, use the
- old one if the modes match, but the new if they don't.
- We don't want to get too fancy with subreg_regno_offset
- here, so we just test two straightforward cases each. */
- if (info->live_update
- && (x_mode != GET_MODE (info->x_local[i])
- ? size >= size_i : size > size_i))
- {
- /* If the new pair is fully enclosing a matching
- existing pair, remove the old one. N.B. because
- we are removing one entry here, the check below
- if we have space for a new entry will succeed. */
- if ((x_regno <= x_regno_i
- && x_regno + x_nregs >= x_regno_i + x_nregs_i
- && x_nregs == y_nregs && x_nregs_i == y_nregs_i
- && x_regno - x_regno_i == y_regno - y_regno_i)
- || (x_regno == x_regno_i && y_regno == y_regno_i
- && x_nregs >= x_nregs_i && y_nregs >= y_nregs_i))
- {
- info->cur.local_count = --local_count;
- info->x_local[i] = info->x_local[local_count];
- info->y_local[i] = info->y_local[local_count];
- continue;
- }
- }
- else
- {
-
- /* If the new pair is fully enclosed within a matching
- existing pair, succeed. */
- if (x_regno >= x_regno_i
- && x_regno + x_nregs <= x_regno_i + x_nregs_i
- && x_nregs == y_nregs && x_nregs_i == y_nregs_i
- && x_regno - x_regno_i == y_regno - y_regno_i)
- break;
- if (x_regno == x_regno_i && y_regno == y_regno_i
- && x_nregs <= x_nregs_i && y_nregs <= y_nregs_i)
- break;
- }
-
- /* Any other overlap causes a match failure. */
- if (x_regno + x_nregs > x_regno_i
- && x_regno_i + x_nregs_i > x_regno)
- return false;
- if (y_regno + y_nregs > y_regno_i
- && y_regno_i + y_nregs_i > y_regno)
- return false;
- }
- if (i < 0)
- {
- /* Not found. Create a new entry if possible. */
- if (!info->live_update
- || info->cur.local_count >= STRUCT_EQUIV_MAX_LOCAL)
- return false;
- info->x_local[info->cur.local_count] = x;
- info->y_local[info->cur.local_count] = y;
- info->cur.local_count++;
- info->cur.version++;
- }
- note_local_live (info, x, y, rvalue);
- }
- return true;
- }
- case SET:
- gcc_assert (rvalue < 0);
- /* Ignore the destinations role as a destination. Still, we have
- to consider input registers embedded in the addresses of a MEM.
- N.B., we process the rvalue aspect of STRICT_LOW_PART /
- ZERO_EXTEND / SIGN_EXTEND along with their lvalue aspect. */
- if(!set_dest_addr_equiv_p (SET_DEST (x), SET_DEST (y), info))
- return false;
- /* Process source. */
- return rtx_equiv_p (&SET_SRC (x), SET_SRC (y), 1, info);
- case PRE_MODIFY:
- /* Process destination. */
- if (!rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), 0, info))
- return false;
- /* Process source. */
- return rtx_equiv_p (&XEXP (x, 1), XEXP (y, 1), 1, info);
- case POST_MODIFY:
- {
- rtx x_dest0, x_dest1;
-
- /* Process destination. */
- x_dest0 = XEXP (x, 0);
- gcc_assert (REG_P (x_dest0));
- if (!rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), 0, info))
- return false;
- x_dest1 = XEXP (x, 0);
- /* validate_change might have changed the destination. Put it back
- so that we can do a proper match for its role as an input. */
- XEXP (x, 0) = x_dest0;
- if (!rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), 1, info))
- return false;
- gcc_assert (x_dest1 == XEXP (x, 0));
- /* Process source. */
- return rtx_equiv_p (&XEXP (x, 1), XEXP (y, 1), 1, info);
- }
- case CLOBBER:
- gcc_assert (rvalue < 0);
- return true;
- /* Some special forms are also rvalues when they appear in lvalue
- positions. However, we must ont try to match a register after we
- have already altered it with validate_change, consider the rvalue
- aspect while we process the lvalue. */
- case STRICT_LOW_PART:
- case ZERO_EXTEND:
- case SIGN_EXTEND:
- {
- rtx x_inner, y_inner;
- enum rtx_code code;
- int change;
-
- if (rvalue)
- break;
- x_inner = XEXP (x, 0);
- y_inner = XEXP (y, 0);
- if (GET_MODE (x_inner) != GET_MODE (y_inner))
- return false;
- code = GET_CODE (x_inner);
- if (code != GET_CODE (y_inner))
- return false;
- /* The address of a MEM is an input that will be processed during
- rvalue == -1 processing. */
- if (code == SUBREG)
- {
- if (SUBREG_BYTE (x_inner) != SUBREG_BYTE (y_inner))
- return false;
- x = x_inner;
- x_inner = SUBREG_REG (x_inner);
- y_inner = SUBREG_REG (y_inner);
- if (GET_MODE (x_inner) != GET_MODE (y_inner))
- return false;
- code = GET_CODE (x_inner);
- if (code != GET_CODE (y_inner))
- return false;
- }
- if (code == MEM)
- return true;
- gcc_assert (code == REG);
- if (! rtx_equiv_p (&XEXP (x, 0), y_inner, rvalue, info))
- return false;
- if (REGNO (x_inner) == REGNO (y_inner))
- {
- change = assign_reg_reg_set (info->common_live, x_inner, 1);
- info->cur.version++;
- }
- else
- change = note_local_live (info, x_inner, y_inner, 1);
- gcc_assert (change);
- return true;
- }
- /* The AUTO_INC / POST_MODIFY / PRE_MODIFY sets are modelled to take
- place during input processing, however, that is benign, since they
- are paired with reads. */
- case MEM:
- return !rvalue || rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), rvalue, info);
- case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
- return (rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), 0, info)
- && rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), 1, info));
- case PARALLEL:
- /* If this is a top-level PATTERN PARALLEL, we expect the caller to
- have handled the SET_DESTs. A complex or vector PARALLEL can be
- identified by having a mode. */
- gcc_assert (rvalue < 0 || GET_MODE (x) != VOIDmode);
- break;
- case LABEL_REF:
- /* Check special tablejump match case. */
- if (XEXP (y, 0) == info->y_label)
- return (XEXP (x, 0) == info->x_label);
- /* We can't assume nonlocal labels have their following insns yet. */
- if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
- return XEXP (x, 0) == XEXP (y, 0);
-
- /* Two label-refs are equivalent if they point at labels
- in the same position in the instruction stream. */
- return (next_real_insn (XEXP (x, 0))
- == next_real_insn (XEXP (y, 0)));
- case SYMBOL_REF:
- return XSTR (x, 0) == XSTR (y, 0);
- /* Some rtl is guaranteed to be shared, or unique; If we didn't match
- EQ equality above, they aren't the same. */
- case CONST_INT:
- case CODE_LABEL:
- return false;
- default:
- break;
- }
-
- /* For commutative operations, the RTX match if the operands match in any
- order. */
- if (targetm.commutative_p (x, UNKNOWN))
- return ((rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), rvalue, info)
- && rtx_equiv_p (&XEXP (x, 1), XEXP (y, 1), rvalue, info))
- || (rtx_equiv_p (&XEXP (x, 0), XEXP (y, 1), rvalue, info)
- && rtx_equiv_p (&XEXP (x, 1), XEXP (y, 0), rvalue, info)));
-
- /* Process subexpressions - this is similar to rtx_equal_p. */
- length = GET_RTX_LENGTH (code);
- format = GET_RTX_FORMAT (code);
-
- for (i = 0; i < length; ++i)
- {
- switch (format[i])
- {
- case 'w':
- if (XWINT (x, i) != XWINT (y, i))
- return false;
- break;
- case 'n':
- case 'i':
- if (XINT (x, i) != XINT (y, i))
- return false;
- break;
- case 'V':
- case 'E':
- if (XVECLEN (x, i) != XVECLEN (y, i))
- return false;
- if (XVEC (x, i) != 0)
- {
- int j;
- for (j = 0; j < XVECLEN (x, i); ++j)
- {
- if (! rtx_equiv_p (&XVECEXP (x, i, j), XVECEXP (y, i, j),
- rvalue, info))
- return false;
- }
- }
- break;
- case 'e':
- if (! rtx_equiv_p (&XEXP (x, i), XEXP (y, i), rvalue, info))
- return false;
- break;
- case 'S':
- case 's':
- if ((XSTR (x, i) || XSTR (y, i))
- && (! XSTR (x, i) || ! XSTR (y, i)
- || strcmp (XSTR (x, i), XSTR (y, i))))
- return false;
- break;
- case 'u':
- /* These are just backpointers, so they don't matter. */
- break;
- case '0':
- case 't':
- break;
- /* It is believed that rtx's at this level will never
- contain anything but integers and other rtx's,
- except for within LABEL_REFs and SYMBOL_REFs. */
- default:
- gcc_unreachable ();
- }
- }
- return true;
-}
-
-/* Do only the rtx_equiv_p SET_DEST processing for SETs and CLOBBERs.
- Since we are scanning backwards, this the first step in processing each
- insn. Return true for success. */
-static bool
-set_dest_equiv_p (rtx x, rtx y, struct equiv_info *info)
-{
- if (!x || !y)
- return x == y;
- if (GET_CODE (x) != GET_CODE (y))
- return false;
- else if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
- return rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), 0, info);
- else if (GET_CODE (x) == PARALLEL)
- {
- int j;
-
- if (XVECLEN (x, 0) != XVECLEN (y, 0))
- return false;
- for (j = 0; j < XVECLEN (x, 0); ++j)
- {
- rtx xe = XVECEXP (x, 0, j);
- rtx ye = XVECEXP (y, 0, j);
-
- if (GET_CODE (xe) != GET_CODE (ye))
- return false;
- if ((GET_CODE (xe) == SET || GET_CODE (xe) == CLOBBER)
- && ! rtx_equiv_p (&XEXP (xe, 0), XEXP (ye, 0), 0, info))
- return false;
- }
- }
- return true;
-}
-
-/* Process MEMs in SET_DEST destinations. We must not process this together
- with REG SET_DESTs, but must do it separately, lest when we see
- [(set (reg:SI foo) (bar))
- (set (mem:SI (reg:SI foo) (baz)))]
- struct_equiv_block_eq could get confused to assume that (reg:SI foo)
- is not live before this instruction. */
-static bool
-set_dest_addr_equiv_p (rtx x, rtx y, struct equiv_info *info)
-{
- enum rtx_code code = GET_CODE (x);
- int length;
- const char *format;
- int i;
-
- if (code != GET_CODE (y))
- return false;
- if (code == MEM)
- return rtx_equiv_p (&XEXP (x, 0), XEXP (y, 0), 1, info);
-
- /* Process subexpressions. */
- length = GET_RTX_LENGTH (code);
- format = GET_RTX_FORMAT (code);
-
- for (i = 0; i < length; ++i)
- {
- switch (format[i])
- {
- case 'V':
- case 'E':
- if (XVECLEN (x, i) != XVECLEN (y, i))
- return false;
- if (XVEC (x, i) != 0)
- {
- int j;
- for (j = 0; j < XVECLEN (x, i); ++j)
- {
- if (! set_dest_addr_equiv_p (XVECEXP (x, i, j),
- XVECEXP (y, i, j), info))
- return false;
- }
- }
- break;
- case 'e':
- if (! set_dest_addr_equiv_p (XEXP (x, i), XEXP (y, i), info))
- return false;
- break;
- default:
- break;
- }
- }
- return true;
-}
-
-/* Check if the set of REG_DEAD notes attached to I1 and I2 allows us to
- go ahead with merging I1 and I2, which otherwise look fine.
- Inputs / local registers for the inputs of I1 and I2 have already been
- set up. */
-static bool
-death_notes_match_p (rtx i1 ATTRIBUTE_UNUSED, rtx i2 ATTRIBUTE_UNUSED,
- struct equiv_info *info ATTRIBUTE_UNUSED)
-{
-#ifdef STACK_REGS
- /* If cross_jump_death_matters is not 0, the insn's mode
- indicates whether or not the insn contains any stack-like regs. */
-
- if ((info->mode & CLEANUP_POST_REGSTACK) && stack_regs_mentioned (i1))
- {
- /* If register stack conversion has already been done, then
- death notes must also be compared before it is certain that
- the two instruction streams match. */
-
- rtx note;
- HARD_REG_SET i1_regset, i2_regset;
-
- CLEAR_HARD_REG_SET (i1_regset);
- CLEAR_HARD_REG_SET (i2_regset);
-
- for (note = REG_NOTES (i1); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
- SET_HARD_REG_BIT (i1_regset, REGNO (XEXP (note, 0)));
-
- for (note = REG_NOTES (i2); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
- {
- unsigned regno = REGNO (XEXP (note, 0));
- int i;
-
- for (i = info->cur.local_count - 1; i >= 0; i--)
- if (regno == REGNO (info->y_local[i]))
- {
- regno = REGNO (info->x_local[i]);
- break;
- }
- SET_HARD_REG_BIT (i2_regset, regno);
- }
-
- if (!hard_reg_set_equal_p (i1_regset, i2_regset))
- return false;
- }
-#endif
- return true;
-}
-
-/* Return true if I1 and I2 are equivalent and thus can be crossjumped. */
-
-bool
-insns_match_p (rtx i1, rtx i2, struct equiv_info *info)
-{
- int rvalue_change_start;
- struct struct_equiv_checkpoint before_rvalue_change;
-
- /* Verify that I1 and I2 are equivalent. */
- if (GET_CODE (i1) != GET_CODE (i2))
- return false;
-
- info->cur.x_start = i1;
- info->cur.y_start = i2;
-
- /* If this is a CALL_INSN, compare register usage information.
- If we don't check this on stack register machines, the two
- CALL_INSNs might be merged leaving reg-stack.c with mismatching
- numbers of stack registers in the same basic block.
- If we don't check this on machines with delay slots, a delay slot may
- be filled that clobbers a parameter expected by the subroutine.
-
- ??? We take the simple route for now and assume that if they're
- equal, they were constructed identically. */
-
- if (CALL_P (i1))
- {
- if (SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)
- || ! set_dest_equiv_p (PATTERN (i1), PATTERN (i2), info)
- || ! set_dest_equiv_p (CALL_INSN_FUNCTION_USAGE (i1),
- CALL_INSN_FUNCTION_USAGE (i2), info)
- || ! rtx_equiv_p (&CALL_INSN_FUNCTION_USAGE (i1),
- CALL_INSN_FUNCTION_USAGE (i2), -1, info))
- {
- cancel_changes (0);
- return false;
- }
- }
- else if (INSN_P (i1))
- {
- if (! set_dest_equiv_p (PATTERN (i1), PATTERN (i2), info))
- {
- cancel_changes (0);
- return false;
- }
- }
- rvalue_change_start = num_validated_changes ();
- struct_equiv_make_checkpoint (&before_rvalue_change, info);
- /* Check death_notes_match_p *after* the inputs have been processed,
- so that local inputs will already have been set up. */
- if (! INSN_P (i1)
- || (!bitmap_bit_p (info->equiv_used, info->cur.ninsns)
- && rtx_equiv_p (&PATTERN (i1), PATTERN (i2), -1, info)
- && death_notes_match_p (i1, i2, info)
- && verify_changes (0)))
- return true;
-
- /* Do not do EQUIV substitution after reload. First, we're undoing the
- work of reload_cse. Second, we may be undoing the work of the post-
- reload splitting pass. */
- /* ??? Possibly add a new phase switch variable that can be used by
- targets to disallow the troublesome insns after splitting. */
- if (!reload_completed)
- {
- rtx equiv1, equiv2;
-
- cancel_changes (rvalue_change_start);
- struct_equiv_restore_checkpoint (&before_rvalue_change, info);
-
- /* The following code helps take care of G++ cleanups. */
- equiv1 = find_reg_equal_equiv_note (i1);
- equiv2 = find_reg_equal_equiv_note (i2);
- if (equiv1 && equiv2
- /* If the equivalences are not to a constant, they may
- reference pseudos that no longer exist, so we can't
- use them. */
- && (! reload_completed
- || (CONSTANT_P (XEXP (equiv1, 0))
- && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))))
- {
- rtx s1 = single_set (i1);
- rtx s2 = single_set (i2);
-
- if (s1 != 0 && s2 != 0)
- {
- validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1);
- validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1);
- /* Only inspecting the new SET_SRC is not good enough,
- because there may also be bare USEs in a single_set
- PARALLEL. */
- if (rtx_equiv_p (&PATTERN (i1), PATTERN (i2), -1, info)
- && death_notes_match_p (i1, i2, info)
- && verify_changes (0))
- {
- /* Mark this insn so that we'll use the equivalence in
- all subsequent passes. */
- bitmap_set_bit (info->equiv_used, info->cur.ninsns);
- return true;
- }
- }
- }
- }
-
- cancel_changes (0);
- return false;
-}
-
-/* Set up mode and register information in INFO. Return true for success. */
-bool
-struct_equiv_init (int mode, struct equiv_info *info)
-{
- if (!REG_SET_EQUAL_P (DF_LR_OUT (info->x_block),
- DF_LR_OUT (info->y_block)))
- {
-#ifdef STACK_REGS
- unsigned rn;
-
- if (!(mode & CLEANUP_POST_REGSTACK))
- return false;
- /* After reg-stack. Remove bogus live info about stack regs. N.B.
- these regs are not necessarily all dead - we swap random bogosity
- against constant bogosity. However, clearing these bits at
- least makes the regsets comparable. */
- for (rn = FIRST_STACK_REG; rn <= LAST_STACK_REG; rn++)
- {
- CLEAR_REGNO_REG_SET (DF_LR_OUT (info->x_block), rn);
- CLEAR_REGNO_REG_SET (DF_LR_OUT (info->y_block), rn);
- }
- if (!REG_SET_EQUAL_P (DF_LR_OUT (info->x_block),
- DF_LR_OUT (info->y_block)))
-#endif
- return false;
- }
- info->mode = mode;
- if (mode & STRUCT_EQUIV_START)
- {
- info->x_input = info->y_input = info->input_reg = NULL_RTX;
- info->equiv_used = ALLOC_REG_SET (&reg_obstack);
- info->check_input_conflict = false;
- }
- info->had_input_conflict = false;
- info->cur.ninsns = info->cur.version = 0;
- info->cur.local_count = info->cur.input_count = 0;
- info->cur.x_start = info->cur.y_start = NULL_RTX;
- info->x_label = info->y_label = NULL_RTX;
- info->need_rerun = false;
- info->live_update = true;
- info->cur.input_valid = false;
- info->common_live = ALLOC_REG_SET (&reg_obstack);
- info->x_local_live = ALLOC_REG_SET (&reg_obstack);
- info->y_local_live = ALLOC_REG_SET (&reg_obstack);
- COPY_REG_SET (info->common_live, DF_LR_OUT (info->x_block));
- struct_equiv_make_checkpoint (&info->best_match, info);
- return true;
-}
-
-/* Insns XI and YI have been matched. Merge memory attributes and reg
- notes. */
-static void
-struct_equiv_merge (rtx xi, rtx yi, struct equiv_info *info)
-{
- rtx equiv1, equiv2;
-
- merge_memattrs (xi, yi);
-
- /* If the merged insns have different REG_EQUAL notes, then
- remove them. */
- info->live_update = false;
- equiv1 = find_reg_equal_equiv_note (xi);
- equiv2 = find_reg_equal_equiv_note (yi);
- if (equiv1 && !equiv2)
- remove_note (xi, equiv1);
- else if (!equiv1 && equiv2)
- remove_note (yi, equiv2);
- else if (equiv1 && equiv2
- && !rtx_equiv_p (&XEXP (equiv1, 0), XEXP (equiv2, 0),
- 1, info))
- {
- remove_note (xi, equiv1);
- remove_note (yi, equiv2);
- }
- info->live_update = true;
-}
-
-/* Return number of matched insns.
- This function must be called up to three times for a successful cross-jump
- match:
- first to find out which instructions do match. While trying to match
- another instruction that doesn't match, we destroy information in info
- about the actual inputs. So if there have been any before the last
- match attempt, we need to call this function again to recompute the
- actual inputs up to the actual start of the matching sequence.
- When we are then satisfied that the cross-jump is worthwhile, we
- call this function a third time to make any changes needed to make the
- sequences match: apply equivalences, remove non-matching
- notes and merge memory attributes. */
-int
-struct_equiv_block_eq (int mode, struct equiv_info *info)
-{
- rtx x_stop, y_stop;
- rtx xi, yi;
- int i;
-
- if (mode & STRUCT_EQUIV_START)
- {
- x_stop = BB_HEAD (info->x_block);
- y_stop = BB_HEAD (info->y_block);
- if (!x_stop || !y_stop)
- return 0;
- }
- else
- {
- x_stop = info->cur.x_start;
- y_stop = info->cur.y_start;
- }
- if (!struct_equiv_init (mode, info))
- gcc_unreachable ();
-
- /* Skip simple jumps at the end of the blocks. Complex jumps still
- need to be compared for equivalence, which we'll do below. */
-
- xi = BB_END (info->x_block);
- if (onlyjump_p (xi)
- || (returnjump_p (xi) && !side_effects_p (PATTERN (xi))))
- {
- info->cur.x_start = xi;
- xi = PREV_INSN (xi);
- }
-
- yi = BB_END (info->y_block);
- if (onlyjump_p (yi)
- || (returnjump_p (yi) && !side_effects_p (PATTERN (yi))))
- {
- info->cur.y_start = yi;
- /* Count everything except for unconditional jump as insn. */
- /* ??? Is it right to count unconditional jumps with a clobber?
- Should we count conditional returns? */
- if (!simplejump_p (yi) && !returnjump_p (yi) && info->cur.x_start)
- info->cur.ninsns++;
- yi = PREV_INSN (yi);
- }
-
- if (mode & STRUCT_EQUIV_MATCH_JUMPS)
- {
- /* The caller is expected to have compared the jumps already, but we
- need to match them again to get any local registers and inputs. */
- gcc_assert (!info->cur.x_start == !info->cur.y_start);
- if (info->cur.x_start)
- {
- if (any_condjump_p (info->cur.x_start)
- ? !condjump_equiv_p (info, false)
- : !insns_match_p (info->cur.x_start, info->cur.y_start, info))
- gcc_unreachable ();
- }
- else if (any_condjump_p (xi) && any_condjump_p (yi))
- {
- info->cur.x_start = xi;
- info->cur.y_start = yi;
- xi = PREV_INSN (xi);
- yi = PREV_INSN (yi);
- info->cur.ninsns++;
- if (!condjump_equiv_p (info, false))
- gcc_unreachable ();
- }
- if (info->cur.x_start && info->mode & STRUCT_EQUIV_FINAL)
- struct_equiv_merge (info->cur.x_start, info->cur.y_start, info);
- }
-
- struct_equiv_improve_checkpoint (&info->best_match, info);
- info->x_end = xi;
- info->y_end = yi;
- if (info->cur.x_start != x_stop)
- for (;;)
- {
- /* Ignore notes. */
- while (!INSN_P (xi) && xi != x_stop)
- xi = PREV_INSN (xi);
-
- while (!INSN_P (yi) && yi != y_stop)
- yi = PREV_INSN (yi);
-
- if (!insns_match_p (xi, yi, info))
- break;
- if (INSN_P (xi))
- {
- if (info->mode & STRUCT_EQUIV_FINAL)
- struct_equiv_merge (xi, yi, info);
- info->cur.ninsns++;
- struct_equiv_improve_checkpoint (&info->best_match, info);
- }
- if (xi == x_stop || yi == y_stop)
- {
- /* If we reached the start of at least one of the blocks, but
- best_match hasn't been advanced back to the first valid insn
- yet, represent the increased benefit of completing the block
- as an increased instruction count. */
- if (info->best_match.x_start != info->cur.x_start
- && (xi == BB_HEAD (info->x_block)
- || yi == BB_HEAD (info->y_block)))
- {
- info->cur.ninsns++;
- struct_equiv_improve_checkpoint (&info->best_match, info);
- info->cur.ninsns--;
- if (info->best_match.ninsns > info->cur.ninsns)
- info->best_match.ninsns = info->cur.ninsns;
- }
- break;
- }
- xi = PREV_INSN (xi);
- yi = PREV_INSN (yi);
- }
-
- /* If we failed to match an insn, but had some changes registered from
- trying to make the insns match, we need to cancel these changes now. */
- cancel_changes (0);
- /* Restore to best_match to get the sequence with the best known-so-far
- cost-benefit difference. */
- struct_equiv_restore_checkpoint (&info->best_match, info);
-
- /* Include preceding notes and labels in the cross-jump / if-conversion.
- One, this may bring us to the head of the blocks.
- Two, it keeps line number notes as matched as may be. */
- if (info->cur.ninsns)
- {
- xi = info->cur.x_start;
- yi = info->cur.y_start;
- while (xi != x_stop && !INSN_P (PREV_INSN (xi)))
- xi = PREV_INSN (xi);
-
- while (yi != y_stop && !INSN_P (PREV_INSN (yi)))
- yi = PREV_INSN (yi);
-
- info->cur.x_start = xi;
- info->cur.y_start = yi;
- }
-
- if (!info->cur.input_valid)
- info->x_input = info->y_input = info->input_reg = NULL_RTX;
- if (!info->need_rerun)
- {
- find_dying_inputs (info);
- if (info->mode & STRUCT_EQUIV_FINAL)
- {
- if (info->check_input_conflict && ! resolve_input_conflict (info))
- gcc_unreachable ();
- }
- else
- {
- bool input_conflict = info->had_input_conflict;
-
- if (!input_conflict
- && info->dying_inputs > 1
- && bitmap_intersect_p (info->x_local_live, info->y_local_live))
- {
- regset_head clobbered_regs;
-
- INIT_REG_SET (&clobbered_regs);
- for (i = 0; i < info->cur.local_count; i++)
- {
- if (assign_reg_reg_set (&clobbered_regs, info->y_local[i], 0))
- {
- input_conflict = true;
- break;
- }
- assign_reg_reg_set (&clobbered_regs, info->x_local[i], 1);
- }
- CLEAR_REG_SET (&clobbered_regs);
- }
- if (input_conflict && !info->check_input_conflict)
- info->need_rerun = true;
- info->check_input_conflict = input_conflict;
- }
- }
-
- if (info->mode & STRUCT_EQUIV_NEED_FULL_BLOCK
- && (info->cur.x_start != x_stop || info->cur.y_start != y_stop))
- return 0;
- return info->cur.ninsns;
-}
-
-/* For each local register, set info->local_rvalue to true iff the register
- is a dying input. Store the total number of these in info->dying_inputs. */
-static void
-find_dying_inputs (struct equiv_info *info)
-{
- int i;
-
- info->dying_inputs = 0;
- for (i = info->cur.local_count-1; i >=0; i--)
- {
- rtx x = info->x_local[i];
- unsigned regno = REGNO (x);
- int nregs = (regno >= FIRST_PSEUDO_REGISTER
- ? 1 : hard_regno_nregs[regno][GET_MODE (x)]);
-
- for (info->local_rvalue[i] = false; nregs > 0; regno++, --nregs)
- if (REGNO_REG_SET_P (info->x_local_live, regno))
- {
- info->dying_inputs++;
- info->local_rvalue[i] = true;
- break;
- }
- }
-}
-
-/* For each local register that is a dying input, y_local[i] will be
- copied to x_local[i]. We'll do this in ascending order. Try to
- re-order the locals to avoid conflicts like r3 = r2; r4 = r3; .
- Return true iff the re-ordering is successful, or not necessary. */
-static bool
-resolve_input_conflict (struct equiv_info *info)
-{
- int i, j, end;
- int nswaps = 0;
- rtx save_x_local[STRUCT_EQUIV_MAX_LOCAL];
- rtx save_y_local[STRUCT_EQUIV_MAX_LOCAL];
-
- find_dying_inputs (info);
- if (info->dying_inputs <= 1)
- return true;
- memcpy (save_x_local, info->x_local, sizeof save_x_local);
- memcpy (save_y_local, info->y_local, sizeof save_y_local);
- end = info->cur.local_count - 1;
- for (i = 0; i <= end; i++)
- {
- /* Cycle detection with regsets is expensive, so we just check that
- we don't exceed the maximum number of swaps needed in the acyclic
- case. */
- int max_swaps = end - i;
-
- /* Check if x_local[i] will be clobbered. */
- if (!info->local_rvalue[i])
- continue;
- /* Check if any later value needs to be copied earlier. */
- for (j = i + 1; j <= end; j++)
- {
- rtx tmp;
-
- if (!info->local_rvalue[j])
- continue;
- if (!reg_overlap_mentioned_p (info->x_local[i], info->y_local[j]))
- continue;
- if (--max_swaps < 0)
- {
- memcpy (info->x_local, save_x_local, sizeof save_x_local);
- memcpy (info->y_local, save_y_local, sizeof save_y_local);
- return false;
- }
- nswaps++;
- tmp = info->x_local[i];
- info->x_local[i] = info->x_local[j];
- info->x_local[j] = tmp;
- tmp = info->y_local[i];
- info->y_local[i] = info->y_local[j];
- info->y_local[j] = tmp;
- j = i;
- }
- }
- info->had_input_conflict = true;
- if (dump_file && nswaps)
- fprintf (dump_file, "Resolved input conflict, %d %s.\n",
- nswaps, nswaps == 1 ? "swap" : "swaps");
- return true;
-}
diff --git a/gcc/system.h b/gcc/system.h
index 8131d28aebd..682d4541257 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1,6 +1,6 @@
/* Get common system includes and various definitions and declarations based
on autoconf macros.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -753,6 +753,9 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
LANG_HOOKS_MAYBE_BUILD_CLEANUP LANG_HOOKS_UPDATE_DECL_AFTER_SAVING \
LANG_HOOKS_POPLEVEL LANG_HOOKS_TRUTHVALUE_CONVERSION
+/* Miscellaneous macros that are no longer used. */
+ #pragma GCC poison USE_MAPPED_LOCATION
+
/* Libiberty macros that are no longer used in GCC. */
#undef ANSI_PROTOTYPES
#undef PTR_CONST
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b627135f100..b8c03ce38ef 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,7 +1,171 @@
+2008-03-02 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 24924
+ * g++.dg/cpp/string-2.C: This is a warning now.
+ * g++.dg/cpp/pedantic-errors.C: -pedantic-errors is not enabled by
+ default, so add it.
+
+2008-03-01 Douglas Gregor <doug.gregor@gmail.com>
+
+ * g++.dg/cpp0x/auto1.C: New.
+
+2008-03-01 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/34770
+ * gfortran.dg/pointer_1.f90: New test.
+
+2008-02-29 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/35315
+ * g++.dg/ext/attrib32.C: Add another test case.
+
+2008-02-29 Tom Tromey <tromey@redhat.com>
+
+ * g++.dg/warn/pragma-system_header2.C: Ignore "included from"
+ line.
+
+2008-02-29 Sebastian Pop <sebastian.pop@amd.com>
+
+ * testsuite/gcc.dg/tree-ssa/ltrans-8.c: Increase the size of strides
+ to make the interchange profitable.
+
+2008-02-28 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/31463
+ PR fortran/33950
+ PR fortran/34296
+ * gfortran.dg/arrayio_11.f90: Fixed test.
+ * gfortran.dg/arrayio_12.f90: Likewise.
+ * gfortran.dg/module_read_1.f90: Added warning-directives.
+ * gfortran.dg/pr32242.f90: Likewise.
+ * gfortran.dg/result_in_spec_3.f90: Likewise.
+ * gfortran.dg/use_12.f90: Likewise.
+ * gfortran.dg/warn_function_without_result.f90 : New test.
+
+2008-02-28 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/34868
+ * gfortran.dg/f2c_9.f90: New test.
+
+2008-02-28 Sebastian Pop <sebastian.pop@amd.com>
+
+ * testsuite/gcc.dg/tree-ssa/ldist-1.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-1a.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-2.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-3.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-4.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-5.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-6.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-7.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-8.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-9.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-10.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-11.c: New.
+ * testsuite/gcc.dg/tree-ssa/ldist-12.c: New.
+ * testsuite/gfortran.dg/ldist-1.f90: New.
+
+2008-02-28 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/pr34351.c: Compile for x86 targets only. Use %ebx register.
+
+2008-02-27 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ * gfortran.dg/large_real_kind_3.F90: Reverse previous commit.
+
+2008-02-27 Jan Beulich <jbeulich@novell.com>
+
+ * gcc.target/i386/mmx-1.c: Add
+ -Werror-implicit-function-declaration to dg-options.
+ * gcc.target/i386/mmx-2.c: Likewise.
+ * gcc.target/i386/sse-13.c: Likewise.
+ * gcc.target/i386/sse-14.c: Likewise.
+
+2008-02-27 Revital Eres <eres@il.ibm.com>
+
+ PR rtl-optimization/34999
+ * gcc.dg/tree-prof/pr34999.c: New.
+
+2008-02-27 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/25290
+ * gcc.c-torture/execute/pr35390.c: New testcase.
+
+2008-02-27 Samuel Tardieu <sam@rfc1149.net>
+
+ PR ada/22255
+ * gnat.dg/test_direct_io.adb: New file.
+
+2008-02-27 Samuel Tardieu <sam@rfc1149.net>
+
+ PR ada/34799
+ * gnat.dg/specs/pr34799.ads: New test.
+
+2008-02-27 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34971
+ * gcc.c-torture/execute/pr34971.c: New testcase.
+
+2008-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/gomp/preprocess-1.c: New test.
+
+ PR c++/35368
+ * g++.dg/ext/visibility/typeinfo2.C: New test.
+ * g++.dg/ext/visibility/typeinfo3.C: New test.
+
+2008-02-26 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/bf-ms-attrib.c (main): Return 0.
+
+2008-02-26 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.target/i386/mmx-4.c (dump64_64): Use printf %I64 on MinGW.
+ * gcc.target/i386/sse-6.c (dump128_64): Likewise.
+
+2008-02-26 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR c/28800
+ * gcc.dg/empty-source-2.c: Adjust for warning message.
+ * gcc.dg/empty-source-3.c: Likewise.
+ * gcc.dg/pack-test-2.c: Adjust comment.
+ * gcc.dg/pragma-ep-2.c: Likewise.
+ * gcc.dg/pragma-re-2.c: Likewise.
+ * gcc.dg/va-arg-2.c: Likewise.
+
+2008-02-26 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/35033
+ * gfortran.dg/assignment_2.f90: New.
+
+2008-02-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/35315
+ * g++.dg/ext/attrib32.C: New.
+
+2008-02-26 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * gcc.c-torture/execute/nest-align-1.x: Delete.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 26264
+ * 20021023-1.c: Use __builtin_va_start instead of
+ __builtin_stdarg_start.
+ * pr17301-1.c: Likewise.
+ * pr17301-2.c: Likewise.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * gcc.dg/pr34351.c: New.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * gcc.dg/Wlarger-than2.c: New.
+
2008-02-26 Paolo Carlini <pcarlini@suse.de>
- PR c++/35323
- * g++.dg/lookup/crash7.C: New.
+ PR c++/35323
+ * g++.dg/lookup/crash7.C: New.
2008-02-26 Kaz Kojima <kkojima@gcc.gnu.org>
@@ -48,13 +212,13 @@
2008-02-25 Paolo Carlini <pcarlini@suse.de>
- PR c++/35333
- * g++.dg/other/error26.C: New.
+ PR c++/35333
+ * g++.dg/other/error26.C: New.
2008-02-25 Paolo Carlini <pcarlini@suse.de>
- PR c++/35338
- * g++.dg/other/error25.C: New.
+ PR c++/35338
+ * g++.dg/other/error25.C: New.
2008-02-25 Andreas Krebbel <krebbel1@de.ibm.com>
@@ -86,6 +250,11 @@
* gcc.dg/vect/vect-117.c: Call check_vect.
* gcc.dg/vect/no-vfa-pr29145.c: Ditto.
+2008-02-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/33486
+ * g++.dg/lookup/strong-using-5.C: New.
+
2008-02-25 Kaz Kojima <kkojima@gcc.gnu.org>
* gcc.dg/tree-ssa/ssa-pre-10.c: Use -fno-finite-math-only on
@@ -176,9 +345,9 @@
Revert:
2008-02-14 Paolo Carlini <pcarlini@suse.de>
- PR c++/28743
+ PR c++/28743
* g++.dg/template/nontype17.C: New.
- * g++.dg/template/nontype16.C: Add error.
+ * g++.dg/template/nontype16.C: Add error.
2008-02-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
@@ -393,6 +562,13 @@
PR c++/34050
* g++.dg/cpp0x/vt-34050.C: New.
+2008-02-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/5645
+ PR c++/11159
+ * g++.dg/warn/pr11159.C: New.
+ * g++.dg/warn/pr5645.C: Likewise.
+
2008-02-14 Danny Smith <dannysmith@users.sourceforge.net>
PR preprocessor/35061
@@ -413,6 +589,11 @@
* gcc.dg/pr35065.c: Fix testcase warnings.
+2008-02-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/34962, c++/34937, c++/34939
+ * g++.dg/ext/tmplattr9.C: New.
+
2008-02-13 Michael Matz <matz@suse.de>
PR debug/35065
diff --git a/gcc/testsuite/g++.dg/cpp/pedantic-errors.C b/gcc/testsuite/g++.dg/cpp/pedantic-errors.C
new file mode 100644
index 00000000000..1684749b282
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp/pedantic-errors.C
@@ -0,0 +1,5 @@
+/* { dg-do preprocess } */
+/* { dg-options "-std=c++98 -pedantic-errors" } */
+
+#if 1
+#endif 1 /* { dg-error "error: extra tokens at end of #endif directive" } */
diff --git a/gcc/testsuite/g++.dg/cpp/string-2.C b/gcc/testsuite/g++.dg/cpp/string-2.C
index b947c73eea4..137c3de1931 100644
--- a/gcc/testsuite/g++.dg/cpp/string-2.C
+++ b/gcc/testsuite/g++.dg/cpp/string-2.C
@@ -1,7 +1,6 @@
-// Test diagnostics for interpreting strings: should be an error by
-// default.
+// Test diagnostics for interpreting strings: This is a pedwarn.
// Origin: Joseph Myers <joseph@codesourcery.com>
// { dg-do compile }
// { dg-options "" }
-const char *s = "\q"; // { dg-error "error: unknown escape sequence" }
+const char *s = "\q"; // { dg-warning "warning: unknown escape sequence" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto1.C b/gcc/testsuite/g++.dg/cpp0x/auto1.C
new file mode 100644
index 00000000000..9e274b62239
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto1.C
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++98 -Wc++0x-compat" }
+
+// Test warning for use of auto in C++98 mode with C++0x
+// compatibility warnings
+void f()
+{
+ auto int x = 5; // { dg-warning "will change meaning" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/attrib32.C b/gcc/testsuite/g++.dg/ext/attrib32.C
new file mode 100644
index 00000000000..39363bb49d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attrib32.C
@@ -0,0 +1,22 @@
+// PR c++/35315
+
+typedef union { int i; } U __attribute__((transparent_union));
+
+static void foo(U) {}
+static void foo(int) {}
+
+void bar()
+{
+ foo(0);
+}
+
+typedef union U1 { int i; } U2 __attribute__((transparent_union));
+
+static void foo2(U1) {}
+static void foo2(U2) {}
+
+void bar2(U1 u1, U2 u2)
+{
+ foo2(u1);
+ foo2(u2);
+}
diff --git a/gcc/testsuite/g++.dg/ext/visibility/typeinfo2.C b/gcc/testsuite/g++.dg/ext/visibility/typeinfo2.C
new file mode 100644
index 00000000000..54f541d8500
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/typeinfo2.C
@@ -0,0 +1,23 @@
+// PR c++/35368
+// { dg-require-visibility "" }
+
+#pragma GCC visibility push (hidden)
+
+struct A
+{
+ A();
+ virtual ~A() { }
+};
+
+A::A()
+{
+}
+
+void foo(A *a)
+{
+ delete a;
+}
+
+// { dg-final { scan-not-hidden "_ZTVN10__cxxabiv117__class_type_infoE" } }
+// { dg-final { scan-hidden "_ZTI1A" } }
+// { dg-final { scan-hidden "_ZTV1A" } }
diff --git a/gcc/testsuite/g++.dg/ext/visibility/typeinfo3.C b/gcc/testsuite/g++.dg/ext/visibility/typeinfo3.C
new file mode 100644
index 00000000000..5102b649216
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/typeinfo3.C
@@ -0,0 +1,24 @@
+// PR c++/35368
+// { dg-require-visibility "" }
+
+#pragma GCC visibility push (hidden)
+
+#include <typeinfo>
+
+const std::type_info& info1 = typeid(int []);
+const std::type_info& info2 = typeid(int);
+enum E { e = 0 };
+const std::type_info& info3 = typeid(E);
+struct S { S (); };
+const std::type_info& info4 = typeid(S);
+const std::type_info& info5 = typeid(int *);
+
+// { dg-final { scan-not-hidden "_ZTVN10__cxxabiv117__array_type_infoE" } }
+// { dg-final { scan-not-hidden "_ZTVN10__cxxabiv116__enum_type_infoE" } }
+// { dg-final { scan-hidden "_ZTI1S" } }
+// { dg-final { scan-hidden "_ZTS1S" } }
+// { dg-final { scan-hidden "info1" } }
+// { dg-final { scan-hidden "info2" } }
+// { dg-final { scan-hidden "info3" } }
+// { dg-final { scan-hidden "info4" } }
+// { dg-final { scan-hidden "info5" } }
diff --git a/gcc/testsuite/g++.dg/warn/pragma-system_header2.C b/gcc/testsuite/g++.dg/warn/pragma-system_header2.C
index be29474084a..a39bea72143 100644
--- a/gcc/testsuite/g++.dg/warn/pragma-system_header2.C
+++ b/gcc/testsuite/g++.dg/warn/pragma-system_header2.C
@@ -3,6 +3,7 @@
#include "pragma-system_header2.h"
+
void f()
{
g<int>();
@@ -11,3 +12,6 @@ void f()
// { dg-warning "conversion" "" { target *-*-* } 2 }
// { dg-warning "conversion" "" { target *-*-* } 5 }
+
+// I couldn't find another way to make this work.
+// { dg-prune-output "In file included from" }
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34971.c b/gcc/testsuite/gcc.c-torture/execute/pr34971.c
new file mode 100644
index 00000000000..3299aee22c9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr34971.c
@@ -0,0 +1,22 @@
+struct foo
+{
+ unsigned long long b:40;
+} x;
+
+extern void abort (void);
+
+void test1(unsigned long long res)
+{
+ /* Build a rotate expression on a 40 bit argument. */
+ if ((x.b<<8) + (x.b>>32) != res)
+ abort ();
+}
+
+int main()
+{
+ x.b = 0x0100000001;
+ test1(0x0000000101);
+ x.b = 0x0100000000;
+ test1(0x0000000001);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr35390.c b/gcc/testsuite/gcc.c-torture/execute/pr35390.c
new file mode 100644
index 00000000000..7103a9b5414
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr35390.c
@@ -0,0 +1,13 @@
+extern void abort (void);
+
+unsigned int foo (int n)
+{
+ return ~((unsigned int)~n);
+}
+
+int main()
+{
+ if (foo(0) != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/20021023-1.c b/gcc/testsuite/gcc.dg/20021023-1.c
index 3e16a84fe0c..855b2cc1ed0 100644
--- a/gcc/testsuite/gcc.dg/20021023-1.c
+++ b/gcc/testsuite/gcc.dg/20021023-1.c
@@ -17,7 +17,7 @@ bar (void *a, float b, const char *c, ...)
va_list args;
unsigned int d;
- __builtin_stdarg_start (args, c);
+ __builtin_va_start (args, c);
d = foo (a, b, c, args, a);
__builtin_va_end (args);
return d;
diff --git a/gcc/testsuite/gcc.dg/Wlarger-than2.c b/gcc/testsuite/gcc.dg/Wlarger-than2.c
new file mode 100644
index 00000000000..eac67f48b5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wlarger-than2.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Wlarger-than=8" } */
+static void foo (void)
+{
+ char buf[9]; /* { dg-warning "size of.*9 bytes" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/bf-ms-attrib.c b/gcc/testsuite/gcc.dg/bf-ms-attrib.c
index e3832d4b404..da4eb08d2da 100644
--- a/gcc/testsuite/gcc.dg/bf-ms-attrib.c
+++ b/gcc/testsuite/gcc.dg/bf-ms-attrib.c
@@ -36,4 +36,5 @@ main()
abort();
if (sizeof(struct one_gcc) != 8)
abort();
+ return 0;
}
diff --git a/gcc/testsuite/gcc.dg/empty-source-2.c b/gcc/testsuite/gcc.dg/empty-source-2.c
index 4d9cc25ff7e..8ce201c13cd 100644
--- a/gcc/testsuite/gcc.dg/empty-source-2.c
+++ b/gcc/testsuite/gcc.dg/empty-source-2.c
@@ -3,4 +3,4 @@
/* { dg-do compile } */
/* { dg-options "-pedantic" } */
-/* { dg-warning "ISO C forbids an empty source file" "empty" { target *-*-* } 6 } */
+/* { dg-warning "ISO C forbids an empty translation unit" "empty" { target *-*-* } 6 } */
diff --git a/gcc/testsuite/gcc.dg/empty-source-3.c b/gcc/testsuite/gcc.dg/empty-source-3.c
index 4facdab3e7e..0fd7be77754 100644
--- a/gcc/testsuite/gcc.dg/empty-source-3.c
+++ b/gcc/testsuite/gcc.dg/empty-source-3.c
@@ -4,4 +4,4 @@
/* { dg-do compile } */
/* { dg-options "-pedantic-errors" } */
-/* { dg-error "ISO C forbids an empty source file" "empty" { target *-*-* } 7 } */
+/* { dg-error "ISO C forbids an empty translation unit" "empty" { target *-*-* } 7 } */
diff --git a/gcc/testsuite/gcc.dg/gomp/preprocess-1.c b/gcc/testsuite/gcc.dg/gomp/preprocess-1.c
new file mode 100644
index 00000000000..714c8404d83
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/preprocess-1.c
@@ -0,0 +1,16 @@
+/* { dg-do preprocess } */
+
+void foo (void)
+{
+ int i1, j1, k1;
+#define p parallel
+#define P(x) private (x##1)
+#define S(x) shared (x##1)
+#define F(x) firstprivate (x##1)
+#pragma omp p P(i) \
+ S(j) \
+ F(k)
+ ;
+}
+
+/* { dg-final { scan-file preprocess-1.i "(^|\n)#pragma omp parallel private \\(i1\\) shared \\(j1\\) firstprivate \\(k1\\)($|\n)" } } */
diff --git a/gcc/testsuite/gcc.dg/pack-test-2.c b/gcc/testsuite/gcc.dg/pack-test-2.c
index 8cb89f488e3..86e4d8df4ac 100644
--- a/gcc/testsuite/gcc.dg/pack-test-2.c
+++ b/gcc/testsuite/gcc.dg/pack-test-2.c
@@ -22,4 +22,4 @@
#pragma pack(push, foo, 3) /* { dg-warning "small power of two" } */
-extern int blah; /* prevent "ISO C forbids an empty source file" */
+extern int blah; /* prevent "ISO C forbids an empty translation unit" */
diff --git a/gcc/testsuite/gcc.dg/pr17301-1.c b/gcc/testsuite/gcc.dg/pr17301-1.c
index 5fd22588cd5..28968fbb2b3 100644
--- a/gcc/testsuite/gcc.dg/pr17301-1.c
+++ b/gcc/testsuite/gcc.dg/pr17301-1.c
@@ -1,4 +1,4 @@
-/* Invalid use of __builtin_stdarg_start should not cause an ICE. Bug
+/* Invalid use of __builtin_va_start should not cause an ICE. Bug
17301. */
/* { dg-do compile } */
/* { dg-options "" } */
@@ -7,5 +7,5 @@ int
write_format (char *format, ...)
{
__builtin_va_list p;
- __builtin_stdarg_start (p); /* { dg-error "too few arguments to function 'va_start'" } */
+ __builtin_va_start (p); /* { dg-error "too few arguments to function 'va_start'" } */
}
diff --git a/gcc/testsuite/gcc.dg/pr17301-2.c b/gcc/testsuite/gcc.dg/pr17301-2.c
index 64b9c9883c2..b91a2314b64 100644
--- a/gcc/testsuite/gcc.dg/pr17301-2.c
+++ b/gcc/testsuite/gcc.dg/pr17301-2.c
@@ -1,9 +1,9 @@
-/* Invalid use of __builtin_stdarg_start should not cause an ICE. Bug
+/* Invalid use of __builtin_va_start should not cause an ICE. Bug
17301. Case with no arguments. */
/* { dg-do compile } */
/* { dg-options "" } */
void foo (char *format, ...)
{
- __builtin_stdarg_start (); /* { dg-error "too few arguments to function '__builtin_stdarg_start'" } */
+ __builtin_va_start (); /* { dg-error "too few arguments to function '__builtin_va_start'" } */
}
diff --git a/gcc/testsuite/gcc.dg/pr34351.c b/gcc/testsuite/gcc.dg/pr34351.c
new file mode 100644
index 00000000000..f407170821c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr34351.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-Wall" } */
+
+register int * volatile x asm ("ebx"); /* { dg-warning "optimization may eliminate reads and/or writes to register variables" } */
diff --git a/gcc/testsuite/gcc.dg/pragma-ep-2.c b/gcc/testsuite/gcc.dg/pragma-ep-2.c
index 6e5c46704c9..1151d9b4bf1 100644
--- a/gcc/testsuite/gcc.dg/pragma-ep-2.c
+++ b/gcc/testsuite/gcc.dg/pragma-ep-2.c
@@ -4,4 +4,4 @@
#pragma extern_prefix foo /* { dg-warning "malformed" } */
#pragma extern_prefix "foo" 1 /* { dg-warning "junk" } */
-int bar; /* silence `ISO C forbids an empty source file' warning */
+int bar; /* silence `ISO C forbids an empty translation unit' warning */
diff --git a/gcc/testsuite/gcc.dg/pragma-re-2.c b/gcc/testsuite/gcc.dg/pragma-re-2.c
index 40b9148dcc8..e86bb87c818 100644
--- a/gcc/testsuite/gcc.dg/pragma-re-2.c
+++ b/gcc/testsuite/gcc.dg/pragma-re-2.c
@@ -5,4 +5,4 @@
#pragma redefine_extname foo 1 /* { dg-warning "malformed" } */
#pragma redefine_extname foo bar 2 /* { dg-warning "junk" } */
-int bar; /* silence `ISO C forbids an empty source file' warning */
+int bar; /* silence `ISO C forbids an empty translation unit' warning */
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr34999.c b/gcc/testsuite/gcc.dg/tree-prof/pr34999.c
new file mode 100644
index 00000000000..4ec42790e57
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr34999.c
@@ -0,0 +1,45 @@
+/* Same test as built-in-setjmp.c. Includes the case where
+ the source block of a crossing fallthru edge ends with a call. */
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -freorder-blocks-and-partition" } */
+
+extern int strcmp(const char *, const char *);
+extern char *strcpy(char *, const char *);
+extern void abort(void);
+extern void exit(int);
+
+void *buf[20];
+
+void __attribute__((noinline))
+sub2 (void)
+{
+ __builtin_longjmp (buf, 1);
+}
+
+int
+main ()
+{
+ char *p = (char *) __builtin_alloca (20);
+
+ strcpy (p, "test");
+
+ if (__builtin_setjmp (buf))
+ {
+ if (strcmp (p, "test") != 0)
+ abort ();
+
+ exit (0);
+ }
+
+ {
+ int *q = (int *) __builtin_alloca (p[2] * sizeof (int));
+ int i;
+
+ for (i = 0; i < p[2]; i++)
+ q[i] = 0;
+
+ while (1)
+ sub2 ();
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-1.c
new file mode 100644
index 00000000000..43c10466525
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-1.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+void foo (int * __restrict__ ia,
+ int * __restrict__ ib,
+ int * __restrict__ oxa,
+ int * __restrict__ oxb,
+ int * __restrict__ oya,
+ int * __restrict__ oyb)
+{
+ int i;
+ long int mya[52];
+ long int myb[52];
+
+ for (i=0; i < 52; i++)
+ {
+ mya[i] = ia[i] * oxa[i] + ib[i] * oxb[i];
+ myb[i] = -ia[i] * oxb[i] + ib[i] * oxa[i];
+ oya[i] = mya[i] >> 10;
+ oyb[i] = myb[i] >> 10;
+ }
+
+ /* This loop was distributed, but it is not anymore due to the cost
+ model changes: the result of a distribution would look like this:
+
+ | for (i=0; i < 52; i++)
+ | oya[i] = ia[i] * oxa[i] + ib[i] * oxb[i] >> 10;
+ |
+ | for (i=0; i < 52; i++)
+ | oyb[i] = -ia[i] * oxb[i] + ib[i] * oxa[i] >> 10;
+
+ and in this the array IA is read in both tasks. For maximizing
+ the cache reuse, ldist does not distributes this loop anymore.
+ */
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-10.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-10.c
new file mode 100644
index 00000000000..0790c18a9da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-10.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i;
+ int a[1000], b[1000], c[1000];
+
+ for (i = 1; i < 1000; i ++)
+ {
+ a[i] = c[i]; /* S1 */
+ b[i] = a[i-1]+1; /* S2 */
+ }
+ /* Dependences:
+ S1->S2 (flow, level 1)
+
+ One partition as A is used in both S1 and S2.
+ */
+
+ return a[1000-2] + b[1000-1] + c[1000-2];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-11.c
new file mode 100644
index 00000000000..88651e7b72d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-11.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+void foo (int * __restrict__ ia,
+ int * __restrict__ ib,
+ int * __restrict__ oxa,
+ int * __restrict__ oxb,
+ int * __restrict__ oya,
+ int * __restrict__ oyb)
+{
+ int i;
+ long int mya[52];
+ long int myb[52];
+
+ for (i=0; i < 52; i++)
+ {
+ mya[i] = ia[i] * oxa[i] + ib[i] * oxb[i];
+ myb[i] = -ia[i] * oxb[i] + ib[i] * oxa[i];
+ oya[i] = 0;
+ oyb[i] = myb[i] >> 10;
+ }
+
+ /* This loop should be distributed, and the result should look like
+ this:
+ | memset (oya, 0, 208);
+ | for (i=0; i < 52; i++)
+ | oyb[i] = -ia[i] * oxb[i] + ib[i] * oxa[i] >> 10;
+ */
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 1 "ldist" } } */
+/* { dg-final { scan-tree-dump-times "generated memset zero" 1 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-12.c
new file mode 100644
index 00000000000..1e555fe26ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-12.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int foo (int * __restrict__ ia,
+ int * __restrict__ ib,
+ int * __restrict__ oxa,
+ int * __restrict__ oxb)
+{
+ int i;
+ int oya[52], oyb[52];
+
+ for (i=0; i < 52; i++)
+ {
+ oya[i] = (ia[i] * oxa[i]) >> 10;
+ oyb[i] = (ib[i] * oxb[i]) >> 10;
+ }
+
+ return oya[22] + oyb[21];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 1 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-1a.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-1a.c
new file mode 100644
index 00000000000..623aacfdbf5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-1a.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int foo (int * __restrict__ ia,
+ int * __restrict__ ib,
+ int * __restrict__ oxa,
+ int * __restrict__ oxb)
+{
+ int i;
+ int oya[52], oyb[52];
+
+ for (i=0; i < 52; i++)
+ {
+ oya[i] = (ia[i] * oxa[i] + ib[i] * oxb[i]) >> 10;
+ oyb[i] = (-ia[i] * oxb[i] + ib[i] * oxa[i]) >> 10;
+ }
+
+ return oya[22] + oyb[21];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-2.c
new file mode 100644
index 00000000000..de98ccc4c30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+void foo (int * __restrict__ a,
+ int * __restrict__ b,
+ int * __restrict__ c)
+{
+ int i;
+
+ for (i=1; i < 10; i++)
+ {
+ a[i] += c[i];
+ b[i] = a[i - 1] + 1;
+ }
+
+ /* This loop is not distributed because the cost of spliting it:
+
+ | for (i=1; i < N; i++)
+ | a[i] += c[i];
+ |
+ | for (i=1; i < N; i++)
+ | b[i] = a[i - 1] + 1;
+
+ is higher due to data in array A that is written and then read in
+ another task. The cost model should forbid the transformation in
+ this case.
+ */
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-3.c
new file mode 100644
index 00000000000..524fb4542b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-3.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i;
+ int a[10000], b[10000], c[10000], d[10000];
+
+ a[0] = k; a[3] = k*2;
+ c[1] = k+1;
+ for (i = 2; i < (10000-1); i ++)
+ {
+ a[i] = k * i; /* S1 */
+ b[i] = a[i-2] + k; /* S2 */
+ c[i] = b[i] + a[i+1]; /* S3 */
+ d[i] = c[i-1] + k + i; /* S4 */
+ }
+ /*
+ Dependences:
+ S1 -> S2 (flow, level 1)
+ S1 -> S3 (anti, level 1)
+ S2 -> S3 (flow, level 0)
+ S3 -> S4 (flow, level 1)
+
+ There are three partitions: {S1, S3}, {S2} and {S4}.
+
+ The cost model should fuse together all the partitions, as they
+ are reusing the same data, ending on a single partition.
+ */
+ return a[10000-2] + b[10000-1] + c[10000-2] + d[10000-2];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 3 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c
new file mode 100644
index 00000000000..c9b1293f0f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i;
+ unsigned int j;
+ int a[100], b[100][100];
+
+ a[0] = k;
+ for (i = 1; i < 100; i ++)
+ {
+ for (j = 0; j < 100; j++)
+ {
+ a[j] = k * i;
+ b[i][j] = a[j-1] + k;
+ }
+ }
+
+ return b[100-1][0];
+}
+
+/* We used to distribute also innermost loops, but these could produce
+ too much code in the outer loop, degrading performance of scalar
+ code. So this test is XFAILed because the cost model of the stand
+ alone distribution pass has evolved. */
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-5.c
new file mode 100644
index 00000000000..af74557024e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-5.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i;
+ unsigned int j;
+ int a[100][100], b[100][100], c[100][100], d[100][100];
+
+ a[0][0] = k;
+ for (i = 1; i < 100; i ++)
+ for (j = 1; j < (100-1); j++)
+ {
+ a[i][j] = k * i; /* S1 */
+ b[i][j] = a[i][j-1] + k; /* S2 */
+ c[i][j] = b[i][j] + a[i][j+1]; /* S3 */
+ d[i][j] = c[i][j] + k + i; /* S4 */
+ }
+ /* Dependences:
+ S1->S2 (flow, level 2)
+ S1->S3 (anti, level 2)
+ S2->S3 (flow, level 0)
+ S3->S4 (flow, level 0)
+ */
+
+ return a[100-1][100-1] + b[100-1][100-1] + c[100-1][100-1] + d[100-1][100-1];
+}
+
+/* FIXME: This is XFAILed because of a data dependence analysis
+ problem: the dependence test fails with a "don't know" relation. */
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 1 "ldist" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-6.c
new file mode 100644
index 00000000000..7a38c86832b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-6.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i;
+ int a[1000], b[1000], c[1000], d[1000];
+
+ for (i = 2; i < (1000-1); i ++) {
+ a[i] = k * i; /* S1 */
+ b[i] = a[i-2] + k; /* S2 */
+ c[i] = b[i-1] + a[i+1]; /* S3 */
+ d[i] = c[i-1] + k + i; /* S4 */
+ }
+ /* Dependences:
+ S1->S2 (flow, level 1)
+ S2->S3 (flow, level 1)
+ S3->S1 (anti, level 1)
+ S3->S4 (flow, level 1)
+
+ There are two partitions: {S1, S2, S3} and {S4}.
+
+ {S1, S2, S3} have to be in the same partition because:
+ - S1 (i) has to be executed before S2 (i+2), as S1 produces a[i] that is then consumed 2 iterations later by S2.
+ - S2 (i) has to be executed before S3 (i+1), as S2 produces b[i] that is then consumed one iteration later by S3,
+ - S3 (i) has to be executed before S1 (i+1), as a[i+1] has to execute before the update to a[i],
+
+ {S4} is the consumer partition: it consumes the values from array "c" produced in S3.
+
+ The cost model should fuse all the tasks together as the cost of
+ fetching data from caches is too high.
+ */
+
+ return a[1000-2] + b[1000-1] + c[1000-2] + d[1000-2];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-7.c
new file mode 100644
index 00000000000..124fcdedd03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-7.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i, z;
+ int a[1000], b[1000], c[1000], d[1000];
+
+ for (i = 2; i < (1000-1); i ++) {
+ z = a[i+1]; /* S1 */
+ a[i] = k * i; /* S2 */
+ b[i] = a[i-2] + k; /* S3 */
+ c[i] = b[i-1] + z; /* S4 */
+ d[i] = c[i-1] + b[i+1] + k + i; /* S5 */
+ }
+ /* Dependences:
+ S1->S2 (anti, level 1)
+ S1->S4 (flow, level 1, scalar)
+ S2->S3 (flow, level 1)
+ S3->S4 (flow, level 1)
+ S4->S5 (flow, level 1)
+ S5->S3 (anti, level 1)
+
+ There is a single partition: {S1, S2, S3, S4, S5}, because of the
+ scalar dependence z between the two partitions {S1, S2} and {S3, S4, S5}.
+ */
+
+ return a[1000-2] + b[1000-1] + c[1000-2] + d[1000-2];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-8.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-8.c
new file mode 100644
index 00000000000..4a8e0660061
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-8.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i;
+ int a[1000], b[1000], c[1000], d[1000];
+
+ for (i = 2; i < (1000-1); i ++)
+ {
+ a[i] = k * i; /* S1 */
+ b[i] = a[i+1] + k; /* S2 */
+ c[i] = a[i-1] + b[i-1] + d[i-1]; /* S3 */
+ d[i] = a[i-1] + b[i+1] + k + i; /* S4 */
+ }
+ /* Dependences:
+ S1->S2 (anti, level 1)
+ S1->S3 (flow, level 1)
+ S1->S4 (flow, level 1)
+ S2->S3 (flow, level 1)
+ S2->S4 (anti, level 1)
+ S4->S3 (flow, level 1)
+
+ Two partitions: {S1, S2, S4} produce information that is consumed in {S3}.
+
+ So that means that the current cost model will also fuse these
+ two partitions into a single one for avoiding cache misses.
+ */
+
+ return a[1000-2] + b[1000-1] + c[1000-2] + d[1000-2];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-9.c
new file mode 100644
index 00000000000..ee8d023dee3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-9.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" } */
+
+int loop1 (int k)
+{
+ unsigned int i;
+ int a[1000], b[1000];
+
+ for (i = 1; i < (1000-1); i ++) {
+ a[i] = a[i+1] + a[i-1]; /* S1 */
+ b[i] = a[i-1] + k; /* S2 */
+ }
+ /*
+ Dependences:
+ S1->S2 (flow, level 1)
+ S1->S1 (anti, level 1)
+ S1->S1 (flow, level 1)
+
+ One partition, because of the cost of cache misses.
+ */
+
+ return a[1000-2] + b[1000-1];
+}
+
+/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c b/gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c
index 1b22e961c62..21f8ffafce6 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ltrans-8.c
@@ -4,9 +4,9 @@ double foo(double *a)
{
int i,j;
double r = 0.0;
- for (i=0; i<8; ++i)
- for (j=0; j<8; ++j)
- r += a[j*8+i];
+ for (i=0; i<100; ++i)
+ for (j=0; j<1000; ++j)
+ r += a[j*100+i];
return r;
}
diff --git a/gcc/testsuite/gcc.dg/va-arg-2.c b/gcc/testsuite/gcc.dg/va-arg-2.c
index 597bf98d540..2fd0ed97e3f 100644
--- a/gcc/testsuite/gcc.dg/va-arg-2.c
+++ b/gcc/testsuite/gcc.dg/va-arg-2.c
@@ -9,4 +9,4 @@
/* { dg-error "no longer implements" "#error 1" { target *-*-* } 4 } */
/* { dg-error "Revise your code" "#error 2" { target *-*-* } 5 } */
-int x; /* prevent empty-source-file warning */
+int x; /* prevent empty-translation-unit warning */
diff --git a/gcc/testsuite/gcc.target/i386/mmx-1.c b/gcc/testsuite/gcc.target/i386/mmx-1.c
index 63d81885d78..c310c5d70fb 100644
--- a/gcc/testsuite/gcc.target/i386/mmx-1.c
+++ b/gcc/testsuite/gcc.target/i386/mmx-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mmmx" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -mmmx" } */
/* Test that the intrinsics compile with optimization. All of them are
defined as inline functions in mmintrin.h that reference the proper
diff --git a/gcc/testsuite/gcc.target/i386/mmx-2.c b/gcc/testsuite/gcc.target/i386/mmx-2.c
index 6f6f89b8d29..f2bfac1b80d 100644
--- a/gcc/testsuite/gcc.target/i386/mmx-2.c
+++ b/gcc/testsuite/gcc.target/i386/mmx-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O0 -mmmx" } */
+/* { dg-options "-O0 -Werror-implicit-function-declaration -mmmx" } */
/* Test that the intrinsics compile without optimization. All of them are
defined as inline functions in mmintrin.h that reference the proper
diff --git a/gcc/testsuite/gcc.target/i386/mmx-4.c b/gcc/testsuite/gcc.target/i386/mmx-4.c
index 42c71f632d9..05d2b553b56 100644
--- a/gcc/testsuite/gcc.target/i386/mmx-4.c
+++ b/gcc/testsuite/gcc.target/i386/mmx-4.c
@@ -184,7 +184,11 @@ dump64_64 (char *buf, char *name, vecInWord x)
sprintf (p, "%s ", name);
p += strlen (p);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ sprintf (p, "%16.16I64x\n", x.t);
+#else
sprintf (p, "%16.16llx\n", x.t);
+#endif
}
int
diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c
index 05e9a9eea24..d71fea48782 100644
--- a/gcc/testsuite/gcc.target/i386/sse-13.c
+++ b/gcc/testsuite/gcc.target/i386/sse-13.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -march=k8 -m3dnow -msse4 -msse5" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -m3dnow -msse4 -msse5" } */
/* Test that the intrinsics compile with optimization. All of them are
defined as inline functions in {,x,e,p,t,s,a,b}mmintrin.h and mm3dnow.h
diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c
index ff8a9ffa488..8e011e598cc 100644
--- a/gcc/testsuite/gcc.target/i386/sse-14.c
+++ b/gcc/testsuite/gcc.target/i386/sse-14.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O0 -march=k8 -m3dnow -msse4 -msse5" } */
+/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -m3dnow -msse4 -msse5" } */
/* Test that the intrinsics compile without optimization. All of them are
defined as inline functions in {,x,e,p,t,s,a,b}mmintrin.h and mm3dnow.h
diff --git a/gcc/testsuite/gcc.target/i386/sse-6.c b/gcc/testsuite/gcc.target/i386/sse-6.c
index f07a8cbc99b..930b23f1f73 100644
--- a/gcc/testsuite/gcc.target/i386/sse-6.c
+++ b/gcc/testsuite/gcc.target/i386/sse-6.c
@@ -229,7 +229,11 @@ dump128_64 (char *buf, char *name, vecInLong x)
for (i=0; i<2; i++)
{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ sprintf (p, "%16.16I64x ", x.u[i]);
+#else
sprintf (p, "%16.16llx ", x.u[i]);
+#endif
p += strlen (p);
}
strcat (p, "\n");
diff --git a/gcc/testsuite/gfortran.dg/arrayio_11.f90 b/gcc/testsuite/gfortran.dg/arrayio_11.f90
index 39255dbcdae..04735d11bec 100644
--- a/gcc/testsuite/gfortran.dg/arrayio_11.f90
+++ b/gcc/testsuite/gfortran.dg/arrayio_11.f90
@@ -21,7 +21,7 @@ program gfcbug51
FILE%date = (/'200612231200', '200712231200', &
'200812231200'/)
- time = date_to_year (FILE)
+ call date_to_year (FILE)
if (any (time%year .ne. (/2006, 2007, 2008/))) call abort ()
call month_to_date ((/8, 9, 10/), FILE)
@@ -30,11 +30,10 @@ program gfcbug51
contains
- function date_to_year (d) result (y)
+ subroutine date_to_year (d)
type(date_t) :: d(3)
- type(year_t) :: y(size (d, 1))
- read (d%date(1:4),'(i4)') time% year
- end function date_to_year
+ read (d%date(1:4),'(i4)') time%year
+ end subroutine
subroutine month_to_date (m, d)
type(date_t) :: d(3)
diff --git a/gcc/testsuite/gfortran.dg/arrayio_12.f90 b/gcc/testsuite/gfortran.dg/arrayio_12.f90
index ca010479bd2..09fa6c8a15e 100644
--- a/gcc/testsuite/gfortran.dg/arrayio_12.f90
+++ b/gcc/testsuite/gfortran.dg/arrayio_12.f90
@@ -18,7 +18,7 @@ program gfcbug51
cdate = (/'200612231200', '200712231200', &
'200812231200'/)
- time = date_to_year (cdate)
+ call date_to_year (cdate)
if (any (time%year .ne. (/2006, 2007, 2008/))) call abort ()
call month_to_date ((/8, 9, 10/), cdate)
@@ -27,11 +27,10 @@ program gfcbug51
contains
- function date_to_year (d) result (y)
+ subroutine date_to_year (d)
character(len=12) :: d(3)
- type(year_t) :: y(size (d, 1))
- read (cdate(:)(1:4),'(i4)') time% year
- end function date_to_year
+ read (cdate(:)(1:4),'(i4)') time%year
+ end subroutine
subroutine month_to_date (m, d)
character(len=12) :: d(3)
diff --git a/gcc/testsuite/gfortran.dg/assignment_2.f90 b/gcc/testsuite/gfortran.dg/assignment_2.f90
new file mode 100644
index 00000000000..3549fbea983
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assignment_2.f90
@@ -0,0 +1,49 @@
+! { dg-do compile }
+!
+! PR fortran/35033
+!
+! The checks for assignments were too strict.
+!
+MODULE m1
+ INTERFACE ASSIGNMENT(=)
+ SUBROUTINE s(a,b)
+ REAL,INTENT(OUT) :: a(1,*)
+ REAL,INTENT(IN) :: b(:)
+ END SUBROUTINE
+ END Interface
+contains
+ subroutine test1()
+ REAL,POINTER :: p(:,:),q(:)
+ CALL s(p,q)
+ p = q
+ end subroutine test1
+end module m1
+
+MODULE m2
+ INTERFACE ASSIGNMENT(=)
+ SUBROUTINE s(a,b)
+ REAL,INTENT(OUT),VOLATILE :: a(1,*)
+ REAL,INTENT(IN) :: b(:)
+ END SUBROUTINE
+ END Interface
+contains
+ subroutine test1()
+ REAL,POINTER :: p(:,:),q(:)
+ CALL s(p,q) ! { dg-error "requires an assumed-shape or pointer-array dummy" }
+!TODO: The following is rightly rejected but the error message is misleading.
+! The actual reason is the mismatch between pointer array and VOLATILE
+ p = q ! { dg-error "Incompatible ranks" }
+ end subroutine test1
+end module m2
+
+MODULE m3
+ INTERFACE ASSIGNMENT(=)
+ module procedure s ! { dg-error "must not redefine an INTRINSIC type" }
+ END Interface
+contains
+ SUBROUTINE s(a,b)
+ REAL,INTENT(OUT),VOLATILE :: a(1,*)
+ REAL,INTENT(IN) :: b(:,:)
+ END SUBROUTINE
+end module m3
+
diff --git a/gcc/testsuite/gfortran.dg/f2c_9.f90 b/gcc/testsuite/gfortran.dg/f2c_9.f90
new file mode 100644
index 00000000000..59c3fbe8b47
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/f2c_9.f90
@@ -0,0 +1,52 @@
+! { dg-do run }
+! { dg-options "-ff2c" }
+! PR 34868
+
+function f(a) result(res)
+ implicit none
+ real(8), intent(in) :: a(:)
+ complex(8) :: res
+
+ res = cmplx(sum(a),product(a),8)
+end function f
+
+function g(a)
+ implicit none
+ real(8), intent(in) :: a(:)
+ complex(8) :: g
+
+ g = cmplx(sum(a),product(a),8)
+end function g
+
+program test
+ real(8) :: a(1,5)
+ complex(8) :: c
+ integer :: i
+
+ interface
+ complex(8) function f(a)
+ real(8), intent(in) :: a(:)
+ end function f
+ function g(a) result(res)
+ real(8), intent(in) :: a(:)
+ complex(8) :: res
+ end function g
+ end interface
+
+ do i = 1, 5
+ a(1,i) = sqrt(real(i,kind(a)))
+ end do
+
+ c = f(a(1,:))
+ call check (real(c), sum(a))
+ call check (imag(c), product(a))
+
+ c = g(a(1,:))
+ call check (real(c), sum(a))
+ call check (imag(c), product(a))
+contains
+ subroutine check (a, b)
+ real(8), intent(in) :: a, b
+ if (abs(a - b) > 1.e-10_8) call abort
+ end subroutine check
+end program test
diff --git a/gcc/testsuite/gfortran.dg/ldist-1.f90 b/gcc/testsuite/gfortran.dg/ldist-1.f90
new file mode 100644
index 00000000000..dd1f02a176b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ldist-1.f90
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-all" }
+
+Subroutine PADEC(DKS,DKDS,HVAR,WM,WG,FN,NS,AN,BN,CN,IT)
+ IMPLICIT REAL*8 (A-H, O-Z)
+ DIMENSION DKS(*),DKDS(*),HVAR(*)
+ COMPLEX*16 WM(*),WG(*),FN(*),AN(*),BN(*),CN(*)
+ COMPLEX*16 H2,CONST
+ COMMON/STRCH/ALP,BET,DH,ZH,UG,VG,T1,T2,DT,TOL,ALPHA ,HAMP,BUMP
+ Parameter (F1 = .8333333333333333D0, F2 = .0833333333333333D0)
+
+ SS=DT/(2.0D0)
+
+ do J=2,NS
+ BS=SS*DKS(J)*HVAR(J)*HVAR(J)
+ AN(J)=F1+2.*BS
+ BN(J)=F2-BS
+ CN(J)=F2-BS
+ H2=WM(J+1)
+
+ if(J.EQ.NS) then
+ CONST=CN(J)*H2
+ else
+ CONST=(0.D0,0.D0)
+ endif
+ FN(J)=(BS+F2)*(H2)+(F1-2.D0*BS)-CONST
+ end do
+
+ return
+end Subroutine PADEC
+
+! { dg-final { scan-tree-dump-times "distributed: split to 4 loops" 1 "ldist" } }
+! { dg-final { cleanup-tree-dump "ldist" } }
diff --git a/gcc/testsuite/gfortran.dg/module_read_1.f90 b/gcc/testsuite/gfortran.dg/module_read_1.f90
index 9a680a62f3e..226c7366cd2 100644
--- a/gcc/testsuite/gfortran.dg/module_read_1.f90
+++ b/gcc/testsuite/gfortran.dg/module_read_1.f90
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options "-Wreturn-type" }
! PR fortran/33941
! The problem was that the intrinsic operators
! were written to the module file as '/=' etc.
@@ -9,11 +10,11 @@
module foo
contains
- function pop(n) result(item)
+ function pop(n) result(item) ! { dg-warning "not set" }
integer :: n
character(len=merge(1, 0, n > 0)) :: item
end function pop
- function push(n) result(item)
+ function push(n) result(item) ! { dg-warning "not set" }
integer :: n
character(len=merge(1, 0, n /= 0)) :: item
end function push
diff --git a/gcc/testsuite/gfortran.dg/pointer_1.f90 b/gcc/testsuite/gfortran.dg/pointer_1.f90
new file mode 100644
index 00000000000..01ad8b951ca
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_1.f90
@@ -0,0 +1,14 @@
+! Testcase for PR34770
+! { dg-do run }
+ implicit none
+ integer, target :: x(0:12)
+ integer, pointer :: z(:)
+ integer i
+ do i = 0,12
+ x(i) = i
+ enddo
+ z => x
+ do i = 0,12
+ if (x(i) /= i .or. z(i) /= i) call abort
+ enddo
+end
diff --git a/gcc/testsuite/gfortran.dg/pr32242.f90 b/gcc/testsuite/gfortran.dg/pr32242.f90
index 6928f4f52d4..21ecdd1786c 100644
--- a/gcc/testsuite/gfortran.dg/pr32242.f90
+++ b/gcc/testsuite/gfortran.dg/pr32242.f90
@@ -1,5 +1,6 @@
!PR fortran/32242
! { dg-do compile }
+! { dg-options "-Wreturn-type" }
! { dg-final { cleanup-modules "kahan_sum" } }
MODULE kahan_sum
@@ -16,13 +17,13 @@ MODULE kahan_sum
TYPE ( pw_grid_type ), POINTER :: pw_grid
END TYPE pw_type
CONTAINS
- FUNCTION kahan_sum_d1(array,mask) RESULT(ks)
+ FUNCTION kahan_sum_d1(array,mask) RESULT(ks) ! { dg-warning "not set" }
REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: array
LOGICAL, DIMENSION(:), INTENT(IN), &
OPTIONAL :: mask
REAL(KIND=dp) :: ks
END FUNCTION kahan_sum_d1
- FUNCTION kahan_sum_z1(array,mask) RESULT(ks)
+ FUNCTION kahan_sum_z1(array,mask) RESULT(ks) ! { dg-warning "not set" }
COMPLEX(KIND=dp), DIMENSION(:), &
INTENT(IN) :: array
LOGICAL, DIMENSION(:), INTENT(IN), &
@@ -34,6 +35,6 @@ FUNCTION pw_integral_a2b ( pw1, pw2 ) RESULT ( integral_value )
TYPE(pw_type), INTENT(IN) :: pw1, pw2
REAL(KIND=dp) :: integral_value
integral_value = accurate_sum ( REAL ( CONJG ( pw1 % cc ( : ) ) &
- * pw2 % cc ( : ) ,KIND=dp) * pw1 % pw_grid % gsq ( : ) ) ! { dg-warning "Function return value not set" }
+ * pw2 % cc ( : ) ,KIND=dp) * pw1 % pw_grid % gsq ( : ) )
END FUNCTION pw_integral_a2b
END MODULE
diff --git a/gcc/testsuite/gfortran.dg/result_in_spec_3.f90 b/gcc/testsuite/gfortran.dg/result_in_spec_3.f90
index ffdf8da4251..32743c32ced 100644
--- a/gcc/testsuite/gfortran.dg/result_in_spec_3.f90
+++ b/gcc/testsuite/gfortran.dg/result_in_spec_3.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-std=gnu" }
+! { dg-options "-std=gnu -Wreturn-type" }
! PR fortran/34248
!
! There was an ICE for assumed-length functions
@@ -10,6 +10,6 @@ character(*) FUNCTION test() RESULT(ctab)
ctab = "Hello"
END function test
-FUNCTION test2() RESULT(res)
+FUNCTION test2() RESULT(res) ! { dg-warning "not set" }
character(*) :: res
END function test2
diff --git a/gcc/testsuite/gfortran.dg/use_12.f90 b/gcc/testsuite/gfortran.dg/use_12.f90
index 82614b5142e..7406dc43388 100644
--- a/gcc/testsuite/gfortran.dg/use_12.f90
+++ b/gcc/testsuite/gfortran.dg/use_12.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options "-Wreturn-type" }
! Tests the fix of PR34545, in which the 'numclusters' that determines the size
! of fnres was not properly associated.
!
@@ -10,7 +11,7 @@ end module m1
module m2
contains
- function get_nfirst( ) result(fnres)
+ function get_nfirst( ) result(fnres) ! { dg-warning "not set" }
use m1, only: numclusters
real :: fnres(numclusters) ! change to REAL and it works!!
end function get_nfirst
diff --git a/gcc/testsuite/gfortran.dg/warn_function_without_result.f90 b/gcc/testsuite/gfortran.dg/warn_function_without_result.f90
new file mode 100644
index 00000000000..43af9c9ca10
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_function_without_result.f90
@@ -0,0 +1,57 @@
+! { dg-do compile }
+! { dg-options "-Wreturn-type" }
+!
+! PR fortran/31463 - inconsistent warnings if function return value is not set
+! PR fortran/33950 - Warning missing for function result not set
+! PR fortran/34296 - Intent(out) and character functions with RESULT: Value-not-set warning
+!
+FUNCTION f1() ! { dg-warning "not set" }
+REAL :: f1
+END FUNCTION
+
+FUNCTION f2() ! { dg-warning "not set" }
+REAL, DIMENSION(1) :: f2
+END FUNCTION
+
+FUNCTION f3() ! { dg-warning "not set" }
+REAL, POINTER :: f3
+END FUNCTION
+
+FUNCTION f4() ! { dg-warning "not set" }
+REAL, DIMENSION(:), POINTER :: f4
+END FUNCTION
+
+FUNCTION f5() ! { dg-warning "not set" }
+REAL, DIMENSION(:), ALLOCATABLE :: f5
+END FUNCTION
+
+FUNCTION f6() ! { dg-warning "not set" }
+CHARACTER(2) :: f6
+END FUNCTION
+
+
+
+FUNCTION g1() RESULT(h) ! { dg-warning "not set" }
+REAL :: h
+END FUNCTION
+
+FUNCTION g2() RESULT(h) ! { dg-warning "not set" }
+REAL, DIMENSION(1) :: h
+END FUNCTION
+
+FUNCTION g3() RESULT(h) ! { dg-warning "not set" }
+REAL, POINTER :: h
+END FUNCTION
+
+FUNCTION g4() RESULT(h) ! { dg-warning "not set" }
+REAL, DIMENSION(:), POINTER :: h
+END FUNCTION
+
+FUNCTION g5() RESULT(h) ! { dg-warning "not set" }
+REAL, DIMENSION(:), ALLOCATABLE :: h
+END FUNCTION
+
+FUNCTION g6() RESULT(h) ! { dg-warning "not set" }
+CHARACTER(2) :: h
+END FUNCTION
+
diff --git a/gcc/testsuite/gnat.dg/specs/pr34799.ads b/gcc/testsuite/gnat.dg/specs/pr34799.ads
new file mode 100644
index 00000000000..7d06049d07f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/pr34799.ads
@@ -0,0 +1,19 @@
+-- { dg-do compile }
+-- { dg-options "-gnatwa" }
+
+package PR34799 is
+ generic
+ type Custom_T is private;
+ package Handler is
+ type Storage_T is record
+ A : Boolean;
+ B : Boolean;
+ C : Custom_T;
+ end record;
+
+ for Storage_T use record
+ A at 0 range 0..0;
+ B at 1 range 0..0;
+ end record;
+ end Handler;
+end PR34799;
diff --git a/gcc/testsuite/gnat.dg/test_direct_io.adb b/gcc/testsuite/gnat.dg/test_direct_io.adb
new file mode 100644
index 00000000000..0eb8aa20808
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/test_direct_io.adb
@@ -0,0 +1,15 @@
+-- { dg-do run }
+with Ada.Direct_IO;
+
+procedure Test_Direct_IO is
+
+ package BDIO is new Ada.Direct_IO (Boolean);
+ use BDIO;
+
+ FD : File_Type;
+
+begin
+ Create (FD, Form => "shared=yes");
+ Reset (FD);
+ Close (FD);
+end Test_Direct_IO;
diff --git a/gcc/timevar.def b/gcc/timevar.def
index 6d9888b2425..66cc70df6bc 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -123,6 +123,7 @@ DEFTIMEVAR (TV_COMPLETE_UNROLL , "complete unrolling")
DEFTIMEVAR (TV_TREE_PARALLELIZE_LOOPS, "tree parallelize loops")
DEFTIMEVAR (TV_TREE_VECTORIZATION , "tree vectorization")
DEFTIMEVAR (TV_TREE_LINEAR_TRANSFORM , "tree loop linear")
+DEFTIMEVAR (TV_TREE_LOOP_DISTRIBUTION, "tree loop distribution")
DEFTIMEVAR (TV_CHECK_DATA_DEPS , "tree check data dependences")
DEFTIMEVAR (TV_TREE_PREFETCH , "tree prefetching")
DEFTIMEVAR (TV_TREE_LOOP_IVOPTS , "tree iv optimization")
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e189914ce41..22e1af7bb87 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1,6 +1,6 @@
/* Top level of GCC compilers (cc1, cc1plus, etc.)
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -149,10 +149,6 @@ static const char **save_argv;
const char *main_input_filename;
-#ifndef USE_MAPPED_LOCATION
-location_t unknown_location = { NULL, 0 };
-#endif
-
/* Used to enable -fvar-tracking, -fweb and -frename-registers according
to optimize and default_debug_hooks in process_options (). */
#define AUTODETECT_VALUE 2
@@ -163,23 +159,6 @@ location_t input_location;
struct line_maps *line_table;
-/* Stack of currently pending input files. */
-
-struct file_stack *input_file_stack;
-
-/* Incremented on each change to input_file_stack. */
-int input_file_stack_tick;
-
-/* Record of input_file_stack at each tick. */
-typedef struct file_stack *fs_p;
-DEF_VEC_P(fs_p);
-DEF_VEC_ALLOC_P(fs_p,heap);
-static VEC(fs_p,heap) *input_file_stack_history;
-
-/* Whether input_file_stack has been restored to a previous state (in
- which case there should be no more pushing). */
-static bool input_file_stack_restored;
-
/* Name to use as base of names for dump output files. */
const char *dump_base_name;
@@ -317,6 +296,10 @@ enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
int flag_pedantic_errors = 0;
+/* Nonzero means make permerror produce warnings instead of errors. */
+
+int flag_permissive = 0;
+
/* -dA causes debug commentary information to be produced in
the generated assembly code (to make it more readable). This option
is generally only of use to those who actually need to read the
@@ -972,72 +955,6 @@ warn_deprecated_use (tree node)
}
}
-/* Save the current INPUT_LOCATION on the top entry in the
- INPUT_FILE_STACK. Push a new entry for FILE and LINE, and set the
- INPUT_LOCATION accordingly. */
-
-void
-#ifdef USE_MAPPED_LOCATION
-push_srcloc (location_t fline)
-#else
-push_srcloc (const char *file, int line)
-#endif
-{
- struct file_stack *fs;
-
- gcc_assert (!input_file_stack_restored);
- if (input_file_stack_tick == (int) ((1U << INPUT_FILE_STACK_BITS) - 1))
- sorry ("GCC supports only %d input file changes", input_file_stack_tick);
-
- fs = XNEW (struct file_stack);
- fs->location = input_location;
- fs->next = input_file_stack;
-#ifdef USE_MAPPED_LOCATION
- input_location = fline;
-#else
- input_filename = file;
- input_line = line;
-#endif
- input_file_stack = fs;
- input_file_stack_tick++;
- VEC_safe_push (fs_p, heap, input_file_stack_history, input_file_stack);
-}
-
-/* Pop the top entry off the stack of presently open source files.
- Restore the INPUT_LOCATION from the new topmost entry on the
- stack. */
-
-void
-pop_srcloc (void)
-{
- struct file_stack *fs;
-
- gcc_assert (!input_file_stack_restored);
- if (input_file_stack_tick == (int) ((1U << INPUT_FILE_STACK_BITS) - 1))
- sorry ("GCC supports only %d input file changes", input_file_stack_tick);
-
- fs = input_file_stack;
- input_location = fs->location;
- input_file_stack = fs->next;
- input_file_stack_tick++;
- VEC_safe_push (fs_p, heap, input_file_stack_history, input_file_stack);
-}
-
-/* Restore the input file stack to its state as of TICK, for the sake
- of diagnostics after processing the whole input. Once this has
- been called, push_srcloc and pop_srcloc may no longer be
- called. */
-void
-restore_input_file_stack (int tick)
-{
- if (tick == 0)
- input_file_stack = NULL;
- else
- input_file_stack = VEC_index (fs_p, input_file_stack_history, tick - 1);
- input_file_stack_tick = tick;
- input_file_stack_restored = true;
-}
-
/* Compile an entire translation unit. Write a file of assembly
output and various debugging dumps. */
@@ -1760,9 +1677,6 @@ process_options (void)
sets the original filename if appropriate (e.g. foo.i -> foo.c)
so we can correctly initialize debug output. */
no_backend = lang_hooks.post_options (&main_input_filename);
-#ifndef USE_MAPPED_LOCATION
- input_filename = main_input_filename;
-#endif
#ifdef OVERRIDE_OPTIONS
/* Some machines may reject certain combinations of options. */
@@ -2153,12 +2067,7 @@ lang_dependent_init (const char *name)
dump_base_name = name && name[0] ? name : "gccdump";
/* Other front-end initialization. */
-#ifdef USE_MAPPED_LOCATION
input_location = BUILTINS_LOCATION;
-#else
- input_filename = "<built-in>";
- input_line = 0;
-#endif
if (lang_hooks.init () == 0)
return 0;
input_location = save_loc;
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 26a085d0c84..45e464680ff 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -62,6 +62,7 @@ extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
ATTRIBUTE_NORETURN;
extern void pedwarn (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+extern void permerror (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void inform (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index ffb4983744e..844e7c14a0e 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -628,20 +628,10 @@ make_cond_expr_edges (basic_block bb)
else_bb = label_to_block (else_label);
e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
-#ifdef USE_MAPPED_LOCATION
e->goto_locus = EXPR_LOCATION (COND_EXPR_THEN (entry));
-#else
- e->goto_locus = EXPR_LOCUS (COND_EXPR_THEN (entry));
-#endif
e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
if (e)
- {
-#ifdef USE_MAPPED_LOCATION
- e->goto_locus = EXPR_LOCATION (COND_EXPR_ELSE (entry));
-#else
- e->goto_locus = EXPR_LOCUS (COND_EXPR_ELSE (entry));
-#endif
- }
+ e->goto_locus = EXPR_LOCATION (COND_EXPR_ELSE (entry));
/* We do not need the gotos anymore. */
COND_EXPR_THEN (entry) = NULL_TREE;
@@ -835,11 +825,7 @@ make_goto_expr_edges (basic_block bb)
{
tree dest = GOTO_DESTINATION (goto_t);
edge e = make_edge (bb, label_to_block (dest), EDGE_FALLTHRU);
-#ifdef USE_MAPPED_LOCATION
e->goto_locus = EXPR_LOCATION (goto_t);
-#else
- e->goto_locus = EXPR_LOCUS (goto_t);
-#endif
bsi_remove (&last, true);
return;
}
@@ -1993,11 +1979,7 @@ static void
remove_bb (basic_block bb)
{
block_stmt_iterator i;
-#ifdef USE_MAPPED_LOCATION
source_location loc = UNKNOWN_LOCATION;
-#else
- source_locus loc = 0;
-#endif
if (dump_file)
{
@@ -2065,15 +2047,8 @@ remove_bb (basic_block bb)
program that are indeed unreachable. */
if (TREE_CODE (stmt) != GOTO_EXPR && EXPR_HAS_LOCATION (stmt) && !loc)
{
-#ifdef USE_MAPPED_LOCATION
if (EXPR_HAS_LOCATION (stmt))
loc = EXPR_LOCATION (stmt);
-#else
- source_locus t;
- t = EXPR_LOCUS (stmt);
- if (t && LOCATION_LINE (*t) > 0)
- loc = t;
-#endif
}
}
}
@@ -2082,13 +2057,8 @@ remove_bb (basic_block bb)
block is unreachable. We walk statements backwards in the
loop above, so the last statement we process is the first statement
in the block. */
-#ifdef USE_MAPPED_LOCATION
if (loc > BUILTINS_LOCATION && LOCATION_LINE (loc) > 0)
warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc);
-#else
- if (loc)
- warning (OPT_Wunreachable_code, "%Hwill never be executed", loc);
-#endif
remove_phi_nodes_and_edges_for_unreachable_block (bb);
bb->il.tree = NULL;
@@ -5676,22 +5646,30 @@ move_stmt_r (tree *tp, int *walk_subtrees, void *data)
/* Marks virtual operands of all statements in basic blocks BBS for
renaming. */
-static void
-mark_virtual_ops_in_region (VEC (basic_block,heap) *bbs)
+void
+mark_virtual_ops_in_bb (basic_block bb)
{
tree phi;
block_stmt_iterator bsi;
+
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ mark_virtual_ops_for_renaming (phi);
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ mark_virtual_ops_for_renaming (bsi_stmt (bsi));
+}
+
+/* Marks virtual operands of all statements in basic blocks BBS for
+ renaming. */
+
+static void
+mark_virtual_ops_in_region (VEC (basic_block,heap) *bbs)
+{
basic_block bb;
unsigned i;
for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
- {
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- mark_virtual_ops_for_renaming (phi);
-
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- mark_virtual_ops_for_renaming (bsi_stmt (bsi));
- }
+ mark_virtual_ops_in_bb (bb);
}
/* Move basic block BB from function CFUN to function DEST_FN. The
@@ -6990,11 +6968,7 @@ gimplify_build1 (block_stmt_iterator *bsi, enum tree_code code, tree type,
static unsigned int
execute_warn_function_return (void)
{
-#ifdef USE_MAPPED_LOCATION
source_location location;
-#else
- location_t *locus;
-#endif
tree last;
edge e;
edge_iterator ei;
@@ -7003,31 +6977,17 @@ execute_warn_function_return (void)
if (TREE_THIS_VOLATILE (cfun->decl)
&& EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0)
{
-#ifdef USE_MAPPED_LOCATION
location = UNKNOWN_LOCATION;
-#else
- locus = NULL;
-#endif
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
{
last = last_stmt (e->src);
if (TREE_CODE (last) == RETURN_EXPR
-#ifdef USE_MAPPED_LOCATION
&& (location = EXPR_LOCATION (last)) != UNKNOWN_LOCATION)
-#else
- && (locus = EXPR_LOCUS (last)) != NULL)
-#endif
break;
}
-#ifdef USE_MAPPED_LOCATION
if (location == UNKNOWN_LOCATION)
location = cfun->function_end_locus;
warning (0, "%H%<noreturn%> function does return", &location);
-#else
- if (!locus)
- locus = &cfun->function_end_locus;
- warning (0, "%H%<noreturn%> function does return", locus);
-#endif
}
/* If we see "return;" in some basic block, then we do reach the end
@@ -7044,17 +7004,10 @@ execute_warn_function_return (void)
&& TREE_OPERAND (last, 0) == NULL
&& !TREE_NO_WARNING (last))
{
-#ifdef USE_MAPPED_LOCATION
location = EXPR_LOCATION (last);
if (location == UNKNOWN_LOCATION)
location = cfun->function_end_locus;
warning (OPT_Wreturn_type, "%Hcontrol reaches end of non-void function", &location);
-#else
- locus = EXPR_LOCUS (last);
- if (!locus)
- locus = &cfun->function_end_locus;
- warning (OPT_Wreturn_type, "%Hcontrol reaches end of non-void function", locus);
-#endif
TREE_NO_WARNING (cfun->decl) = 1;
break;
}
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 2f17ed1deb4..70266034aab 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -88,7 +88,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-dump.h"
#include "timevar.h"
#include "cfgloop.h"
-#include "tree-chrec.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-pass.h"
@@ -157,6 +156,14 @@ dump_data_references (FILE *file, VEC (data_reference_p, heap) *datarefs)
dump_data_reference (file, dr);
}
+/* Dump to STDERR all the dependence relations from DDRS. */
+
+void
+debug_data_dependence_relations (VEC (ddr_p, heap) *ddrs)
+{
+ dump_data_dependence_relations (stderr, ddrs);
+}
+
/* Dump into FILE all the dependence relations from DDRS. */
void
@@ -354,6 +361,10 @@ dump_data_dependence_relation (FILE *outf,
dra = DDR_A (ddr);
drb = DDR_B (ddr);
fprintf (outf, "(Data Dep: \n");
+
+ dump_data_reference (outf, dra);
+ dump_data_reference (outf, drb);
+
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
fprintf (outf, " (don't know)\n");
@@ -808,7 +819,7 @@ dr_address_invariant_p (struct data_reference *dr)
/* Frees data reference DR. */
-static void
+void
free_data_ref (data_reference_p dr)
{
BITMAP_FREE (DR_VOPS (dr));
@@ -2787,22 +2798,6 @@ build_classic_dist_vector_1 (struct data_dependence_relation *ddr,
return true;
}
-/* Return true when the DDR contains two data references that have the
- same access functions. */
-
-static bool
-same_access_functions (const struct data_dependence_relation *ddr)
-{
- unsigned i;
-
- for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
- if (!eq_evolutions_p (DR_ACCESS_FN (DDR_A (ddr), i),
- DR_ACCESS_FN (DDR_B (ddr), i)))
- return false;
-
- return true;
-}
-
/* Return true when the DDR contains only constant access functions. */
static bool
@@ -4371,48 +4366,219 @@ free_data_refs (VEC (data_reference_p, heap) *datarefs)
-/* Returns the index of STMT in RDG. */
+/* Dump vertex I in RDG to FILE. */
-static int
-find_vertex_for_stmt (const struct graph *rdg, const_tree stmt)
+void
+dump_rdg_vertex (FILE *file, struct graph *rdg, int i)
+{
+ struct vertex *v = &(rdg->vertices[i]);
+ struct graph_edge *e;
+
+ fprintf (file, "(vertex %d: (%s%s) (in:", i,
+ RDG_MEM_WRITE_STMT (rdg, i) ? "w" : "",
+ RDG_MEM_READS_STMT (rdg, i) ? "r" : "");
+
+ if (v->pred)
+ for (e = v->pred; e; e = e->pred_next)
+ fprintf (file, " %d", e->src);
+
+ fprintf (file, ") (out:");
+
+ if (v->succ)
+ for (e = v->succ; e; e = e->succ_next)
+ fprintf (file, " %d", e->dest);
+
+ fprintf (file, ") \n");
+ print_generic_stmt (file, RDGV_STMT (v), TDF_VOPS|TDF_MEMSYMS);
+ fprintf (file, ")\n");
+}
+
+/* Call dump_rdg_vertex on stderr. */
+
+void
+debug_rdg_vertex (struct graph *rdg, int i)
+{
+ dump_rdg_vertex (stderr, rdg, i);
+}
+
+/* Dump component C of RDG to FILE. If DUMPED is non-null, set the
+ dumped vertices to that bitmap. */
+
+void dump_rdg_component (FILE *file, struct graph *rdg, int c, bitmap dumped)
+{
+ int i;
+
+ fprintf (file, "(%d\n", c);
+
+ for (i = 0; i < rdg->n_vertices; i++)
+ if (rdg->vertices[i].component == c)
+ {
+ if (dumped)
+ bitmap_set_bit (dumped, i);
+
+ dump_rdg_vertex (file, rdg, i);
+ }
+
+ fprintf (file, ")\n");
+}
+
+/* Call dump_rdg_vertex on stderr. */
+
+void
+debug_rdg_component (struct graph *rdg, int c)
+{
+ dump_rdg_component (stderr, rdg, c, NULL);
+}
+
+/* Dump the reduced dependence graph RDG to FILE. */
+
+void
+dump_rdg (FILE *file, struct graph *rdg)
{
int i;
+ bitmap dumped = BITMAP_ALLOC (NULL);
+
+ fprintf (file, "(rdg\n");
for (i = 0; i < rdg->n_vertices; i++)
- if (RDGV_STMT (&(rdg->vertices[i])) == stmt)
- return i;
+ if (!bitmap_bit_p (dumped, i))
+ dump_rdg_component (file, rdg, rdg->vertices[i].component, dumped);
- gcc_unreachable ();
- return 0;
+ fprintf (file, ")\n");
+ BITMAP_FREE (dumped);
}
-/* Creates an edge in RDG for each distance vector from DDR. */
+/* Call dump_rdg on stderr. */
+
+void
+debug_rdg (struct graph *rdg)
+{
+ dump_rdg (stderr, rdg);
+}
static void
-create_rdg_edge_for_ddr (struct graph *rdg, ddr_p ddr)
+dot_rdg_1 (FILE *file, struct graph *rdg)
{
- int va, vb;
- data_reference_p dra;
- data_reference_p drb;
- struct graph_edge *e;
+ int i;
+
+ fprintf (file, "digraph RDG {\n");
- if (DDR_REVERSED_P (ddr))
+ for (i = 0; i < rdg->n_vertices; i++)
{
- dra = DDR_B (ddr);
- drb = DDR_A (ddr);
+ struct vertex *v = &(rdg->vertices[i]);
+ struct graph_edge *e;
+
+ /* Highlight reads from memory. */
+ if (RDG_MEM_READS_STMT (rdg, i))
+ fprintf (file, "%d [style=filled, fillcolor=green]\n", i);
+
+ /* Highlight stores to memory. */
+ if (RDG_MEM_WRITE_STMT (rdg, i))
+ fprintf (file, "%d [style=filled, fillcolor=red]\n", i);
+
+ if (v->succ)
+ for (e = v->succ; e; e = e->succ_next)
+ switch (RDGE_TYPE (e))
+ {
+ case input_dd:
+ fprintf (file, "%d -> %d [label=input] \n", i, e->dest);
+ break;
+
+ case output_dd:
+ fprintf (file, "%d -> %d [label=output] \n", i, e->dest);
+ break;
+
+ case flow_dd:
+ /* These are the most common dependences: don't print these. */
+ fprintf (file, "%d -> %d \n", i, e->dest);
+ break;
+
+ case anti_dd:
+ fprintf (file, "%d -> %d [label=anti] \n", i, e->dest);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
}
- else
+
+ fprintf (file, "}\n\n");
+}
+
+/* Display SCOP using dotty. */
+
+void
+dot_rdg (struct graph *rdg)
+{
+ FILE *file = fopen ("/tmp/rdg.dot", "w");
+ gcc_assert (file != NULL);
+
+ dot_rdg_1 (file, rdg);
+ fclose (file);
+
+ system ("dotty /tmp/rdg.dot");
+}
+
+
+/* This structure is used for recording the mapping statement index in
+ the RDG. */
+
+struct rdg_vertex_info GTY(())
+{
+ tree stmt;
+ int index;
+};
+
+/* Returns the index of STMT in RDG. */
+
+int
+rdg_vertex_for_stmt (struct graph *rdg, tree stmt)
+{
+ struct rdg_vertex_info rvi, *slot;
+
+ rvi.stmt = stmt;
+ slot = (struct rdg_vertex_info *) htab_find (rdg->indices, &rvi);
+
+ if (!slot)
+ return -1;
+
+ return slot->index;
+}
+
+/* Creates an edge in RDG for each distance vector from DDR. The
+ order that we keep track of in the RDG is the order in which
+ statements have to be executed. */
+
+static void
+create_rdg_edge_for_ddr (struct graph *rdg, ddr_p ddr)
+{
+ struct graph_edge *e;
+ int va, vb;
+ data_reference_p dra = DDR_A (ddr);
+ data_reference_p drb = DDR_B (ddr);
+ unsigned level = ddr_dependence_level (ddr);
+
+ /* For non scalar dependences, when the dependence is REVERSED,
+ statement B has to be executed before statement A. */
+ if (level > 0
+ && !DDR_REVERSED_P (ddr))
{
- dra = DDR_A (ddr);
- drb = DDR_B (ddr);
+ data_reference_p tmp = dra;
+ dra = drb;
+ drb = tmp;
}
- va = find_vertex_for_stmt (rdg, DR_STMT (dra));
- vb = find_vertex_for_stmt (rdg, DR_STMT (drb));
+ va = rdg_vertex_for_stmt (rdg, DR_STMT (dra));
+ vb = rdg_vertex_for_stmt (rdg, DR_STMT (drb));
+
+ if (va < 0 || vb < 0)
+ return;
e = add_edge (rdg, va, vb);
e->data = XNEW (struct rdg_edge);
+ RDGE_LEVEL (e) = level;
+
/* Determines the type of the data dependence. */
if (DR_IS_READ (dra) && DR_IS_READ (drb))
RDGE_TYPE (e) = input_dd;
@@ -4435,9 +4601,13 @@ create_rdg_edges_for_scalar (struct graph *rdg, tree def, int idef)
FOR_EACH_IMM_USE_FAST (imm_use_p, iterator, def)
{
- int use = find_vertex_for_stmt (rdg, USE_STMT (imm_use_p));
- struct graph_edge *e = add_edge (rdg, idef, use);
+ struct graph_edge *e;
+ int use = rdg_vertex_for_stmt (rdg, USE_STMT (imm_use_p));
+ if (use < 0)
+ continue;
+
+ e = add_edge (rdg, idef, use);
e->data = XNEW (struct rdg_edge);
RDGE_TYPE (e) = flow_dd;
}
@@ -4458,8 +4628,8 @@ create_rdg_edges (struct graph *rdg, VEC (ddr_p, heap) *ddrs)
create_rdg_edge_for_ddr (rdg, ddr);
for (i = 0; i < rdg->n_vertices; i++)
- FOR_EACH_PHI_OR_STMT_DEF (def_p, RDGV_STMT (&(rdg->vertices[i])),
- iter, SSA_OP_ALL_DEFS)
+ FOR_EACH_PHI_OR_STMT_DEF (def_p, RDG_STMT (rdg, i),
+ iter, SSA_OP_DEF)
create_rdg_edges_for_scalar (rdg, DEF_FROM_PTR (def_p), i);
}
@@ -4468,19 +4638,50 @@ create_rdg_edges (struct graph *rdg, VEC (ddr_p, heap) *ddrs)
static void
create_rdg_vertices (struct graph *rdg, VEC (tree, heap) *stmts)
{
- int i;
- tree s;
+ int i, j;
+ tree stmt;
- for (i = 0; VEC_iterate (tree, stmts, i, s); i++)
+ for (i = 0; VEC_iterate (tree, stmts, i, stmt); i++)
{
+ VEC (data_ref_loc, heap) *references;
+ data_ref_loc *ref;
struct vertex *v = &(rdg->vertices[i]);
+ struct rdg_vertex_info *rvi = XNEW (struct rdg_vertex_info);
+ struct rdg_vertex_info **slot;
+
+ rvi->stmt = stmt;
+ rvi->index = i;
+ slot = (struct rdg_vertex_info **) htab_find_slot (rdg->indices, rvi, INSERT);
+
+ if (!*slot)
+ *slot = rvi;
+ else
+ free (rvi);
v->data = XNEW (struct rdg_vertex);
- RDGV_STMT (v) = s;
+ RDG_STMT (rdg, i) = stmt;
+
+ RDG_MEM_WRITE_STMT (rdg, i) = false;
+ RDG_MEM_READS_STMT (rdg, i) = false;
+ if (TREE_CODE (stmt) == PHI_NODE)
+ continue;
+
+ get_references_in_stmt (stmt, &references);
+ for (j = 0; VEC_iterate (data_ref_loc, references, j, ref); j++)
+ if (!ref->is_read)
+ RDG_MEM_WRITE_STMT (rdg, i) = true;
+ else
+ RDG_MEM_READS_STMT (rdg, i) = true;
+
+ VEC_free (data_ref_loc, heap, references);
}
}
-/* Initialize STMTS with all the statements and PHI nodes of LOOP. */
+/* Initialize STMTS with all the statements of LOOP. When
+ INCLUDE_PHIS is true, include also the PHI nodes. The order in
+ which we discover statements is important as
+ generate_loops_for_partition is using the same traversal for
+ identifying statements. */
static void
stmts_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
@@ -4490,7 +4691,7 @@ stmts_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
for (i = 0; i < loop->num_nodes; i++)
{
- tree phi;
+ tree phi, stmt;
basic_block bb = bbs[i];
block_stmt_iterator bsi;
@@ -4498,7 +4699,8 @@ stmts_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
VEC_safe_push (tree, heap, *stmts, phi);
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- VEC_safe_push (tree, heap, *stmts, bsi_stmt (bsi));
+ if (TREE_CODE (stmt = bsi_stmt (bsi)) != LABEL_EXPR)
+ VEC_safe_push (tree, heap, *stmts, stmt);
}
free (bbs);
@@ -4519,8 +4721,39 @@ known_dependences_p (VEC (ddr_p, heap) *dependence_relations)
return true;
}
-/* Build a Reduced Dependence Graph with one vertex per statement of the
- loop nest and one edge per data dependence or scalar dependence. */
+/* Computes a hash function for element ELT. */
+
+static hashval_t
+hash_stmt_vertex_info (const void *elt)
+{
+ struct rdg_vertex_info *rvi = (struct rdg_vertex_info *) elt;
+ tree stmt = rvi->stmt;
+
+ return htab_hash_pointer (stmt);
+}
+
+/* Compares database elements E1 and E2. */
+
+static int
+eq_stmt_vertex_info (const void *e1, const void *e2)
+{
+ const struct rdg_vertex_info *elt1 = (const struct rdg_vertex_info *) e1;
+ const struct rdg_vertex_info *elt2 = (const struct rdg_vertex_info *) e2;
+
+ return elt1->stmt == elt2->stmt;
+}
+
+/* Free the element E. */
+
+static void
+hash_stmt_vertex_del (void *e)
+{
+ free (e);
+}
+
+/* Build the Reduced Dependence Graph (RDG) with one vertex per
+ statement of the loop nest, and one edge per data dependence or
+ scalar dependence. */
struct graph *
build_rdg (struct loop *loop)
@@ -4529,7 +4762,7 @@ build_rdg (struct loop *loop)
struct graph *rdg = NULL;
VEC (ddr_p, heap) *dependence_relations;
VEC (data_reference_p, heap) *datarefs;
- VEC (tree, heap) *stmts = VEC_alloc (tree, heap, 10);
+ VEC (tree, heap) *stmts = VEC_alloc (tree, heap, nb_data_refs);
dependence_relations = VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs) ;
datarefs = VEC_alloc (data_reference_p, heap, nb_data_refs);
@@ -4537,12 +4770,15 @@ build_rdg (struct loop *loop)
false,
&datarefs,
&dependence_relations);
-
+
if (!known_dependences_p (dependence_relations))
goto end_rdg;
stmts_from_loop (loop, &stmts);
rdg = new_graph (VEC_length (tree, stmts));
+
+ rdg->indices = htab_create (nb_data_refs, hash_stmt_vertex_info,
+ eq_stmt_vertex_info, hash_stmt_vertex_del);
create_rdg_vertices (rdg, stmts);
create_rdg_edges (rdg, dependence_relations);
@@ -4553,3 +4789,197 @@ build_rdg (struct loop *loop)
return rdg;
}
+
+/* Free the reduced dependence graph RDG. */
+
+void
+free_rdg (struct graph *rdg)
+{
+ int i;
+
+ for (i = 0; i < rdg->n_vertices; i++)
+ free (rdg->vertices[i].data);
+
+ htab_delete (rdg->indices);
+ free_graph (rdg);
+}
+
+/* Initialize STMTS with all the statements of LOOP that contain a
+ store to memory. */
+
+void
+stores_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
+{
+ unsigned int i;
+ basic_block *bbs = get_loop_body_in_dom_order (loop);
+
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ basic_block bb = bbs[i];
+ block_stmt_iterator bsi;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ if (!ZERO_SSA_OPERANDS (bsi_stmt (bsi), SSA_OP_VDEF))
+ VEC_safe_push (tree, heap, *stmts, bsi_stmt (bsi));
+ }
+
+ free (bbs);
+}
+
+/* For a data reference REF, return the declaration of its base
+ address or NULL_TREE if the base is not determined. */
+
+static inline tree
+ref_base_address (tree stmt, data_ref_loc *ref)
+{
+ tree base = NULL_TREE;
+ tree base_address;
+ struct data_reference *dr = XCNEW (struct data_reference);
+
+ DR_STMT (dr) = stmt;
+ DR_REF (dr) = *ref->pos;
+ dr_analyze_innermost (dr);
+ base_address = DR_BASE_ADDRESS (dr);
+
+ if (!base_address)
+ goto end;
+
+ switch (TREE_CODE (base_address))
+ {
+ case ADDR_EXPR:
+ base = TREE_OPERAND (base_address, 0);
+ break;
+
+ default:
+ base = base_address;
+ break;
+ }
+
+ end:
+ free_data_ref (dr);
+ return base;
+}
+
+/* Determines whether the statement from vertex V of the RDG has a
+ definition used outside the loop that contains this statement. */
+
+bool
+rdg_defs_used_in_other_loops_p (struct graph *rdg, int v)
+{
+ tree stmt = RDG_STMT (rdg, v);
+ struct loop *loop = loop_containing_stmt (stmt);
+ use_operand_p imm_use_p;
+ imm_use_iterator iterator;
+ ssa_op_iter it;
+ def_operand_p def_p;
+
+ if (!loop)
+ return true;
+
+ FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, it, SSA_OP_DEF)
+ {
+ FOR_EACH_IMM_USE_FAST (imm_use_p, iterator, DEF_FROM_PTR (def_p))
+ {
+ if (loop_containing_stmt (USE_STMT (imm_use_p)) != loop)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Determines whether statements S1 and S2 access to similar memory
+ locations. Two memory accesses are considered similar when they
+ have the same base address declaration, i.e. when their
+ ref_base_address is the same. */
+
+bool
+have_similar_memory_accesses (tree s1, tree s2)
+{
+ bool res = false;
+ unsigned i, j;
+ VEC (data_ref_loc, heap) *refs1, *refs2;
+ data_ref_loc *ref1, *ref2;
+
+ get_references_in_stmt (s1, &refs1);
+ get_references_in_stmt (s2, &refs2);
+
+ for (i = 0; VEC_iterate (data_ref_loc, refs1, i, ref1); i++)
+ {
+ tree base1 = ref_base_address (s1, ref1);
+
+ if (base1)
+ for (j = 0; VEC_iterate (data_ref_loc, refs2, j, ref2); j++)
+ if (base1 == ref_base_address (s2, ref2))
+ {
+ res = true;
+ goto end;
+ }
+ }
+
+ end:
+ VEC_free (data_ref_loc, heap, refs1);
+ VEC_free (data_ref_loc, heap, refs2);
+ return res;
+}
+
+/* Helper function for the hashtab. */
+
+static int
+have_similar_memory_accesses_1 (const void *s1, const void *s2)
+{
+ return have_similar_memory_accesses ((tree) s1, (tree) s2);
+}
+
+/* Helper function for the hashtab. */
+
+static hashval_t
+ref_base_address_1 (const void *s)
+{
+ tree stmt = (tree) s;
+ unsigned i;
+ VEC (data_ref_loc, heap) *refs;
+ data_ref_loc *ref;
+ hashval_t res = 0;
+
+ get_references_in_stmt (stmt, &refs);
+
+ for (i = 0; VEC_iterate (data_ref_loc, refs, i, ref); i++)
+ if (!ref->is_read)
+ {
+ res = htab_hash_pointer (ref_base_address (stmt, ref));
+ break;
+ }
+
+ VEC_free (data_ref_loc, heap, refs);
+ return res;
+}
+
+/* Try to remove duplicated write data references from STMTS. */
+
+void
+remove_similar_memory_refs (VEC (tree, heap) **stmts)
+{
+ unsigned i;
+ tree stmt;
+ htab_t seen = htab_create (VEC_length (tree, *stmts), ref_base_address_1,
+ have_similar_memory_accesses_1, NULL);
+
+ for (i = 0; VEC_iterate (tree, *stmts, i, stmt); )
+ {
+ void **slot;
+
+ slot = htab_find_slot (seen, stmt, INSERT);
+
+ if (*slot)
+ VEC_ordered_remove (tree, *stmts, i);
+ else
+ {
+ *slot = (void *) stmt;
+ i++;
+ }
+ }
+
+ htab_delete (seen);
+}
+
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index 2ae58266db6..b24fd63095f 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "graphds.h"
#include "lambda.h"
#include "omega.h"
+#include "tree-chrec.h"
/*
innermost_loop_behavior describes the evolution of the address of the memory
@@ -38,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
Example 1 Example 2
data-ref a[j].b[i][j] *(p + x + 16B + 4B * j)
+
innermost_loop_behavior
base_address &a p
offset i * D_i x
@@ -319,26 +321,107 @@ extern void debug_data_dependence_relation (struct data_dependence_relation *);
extern void dump_data_dependence_relation (FILE *,
struct data_dependence_relation *);
extern void dump_data_dependence_relations (FILE *, VEC (ddr_p, heap) *);
+extern void debug_data_dependence_relations (VEC (ddr_p, heap) *);
extern void dump_data_dependence_direction (FILE *,
enum data_dependence_direction);
extern void free_dependence_relation (struct data_dependence_relation *);
extern void free_dependence_relations (VEC (ddr_p, heap) *);
+extern void free_data_ref (data_reference_p);
extern void free_data_refs (VEC (data_reference_p, heap) *);
struct data_reference *create_data_ref (struct loop *, tree, tree, bool);
bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
void compute_all_dependences (VEC (data_reference_p, heap) *,
VEC (ddr_p, heap) **, VEC (loop_p, heap) *, bool);
+/* Return true when the DDR contains two data references that have the
+ same access functions. */
+
+static inline bool
+same_access_functions (const struct data_dependence_relation *ddr)
+{
+ unsigned i;
+
+ for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
+ if (!eq_evolutions_p (DR_ACCESS_FN (DDR_A (ddr), i),
+ DR_ACCESS_FN (DDR_B (ddr), i)))
+ return false;
+
+ return true;
+}
+
+/* Return true when DDR is an anti-dependence relation. */
+
+static inline bool
+ddr_is_anti_dependent (ddr_p ddr)
+{
+ return (DDR_ARE_DEPENDENT (ddr) == NULL_TREE
+ && DR_IS_READ (DDR_A (ddr))
+ && !DR_IS_READ (DDR_B (ddr))
+ && !same_access_functions (ddr));
+}
+
+/* Return true when DEPENDENCE_RELATIONS contains an anti-dependence. */
+
+static inline bool
+ddrs_have_anti_deps (VEC (ddr_p, heap) *dependence_relations)
+{
+ unsigned i;
+ ddr_p ddr;
+
+ for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++)
+ if (ddr_is_anti_dependent (ddr))
+ return true;
+
+ return false;
+}
+
+/* Return the dependence level for the DDR relation. */
+
+static inline unsigned
+ddr_dependence_level (ddr_p ddr)
+{
+ unsigned vector;
+ unsigned level = 0;
+
+ if (DDR_DIST_VECTS (ddr))
+ level = dependence_level (DDR_DIST_VECT (ddr, 0), DDR_NB_LOOPS (ddr));
+
+ for (vector = 1; vector < DDR_NUM_DIST_VECTS (ddr); vector++)
+ level = MIN (level, dependence_level (DDR_DIST_VECT (ddr, vector),
+ DDR_NB_LOOPS (ddr)));
+ return level;
+}
+
-/* A RDG vertex representing a statement. */
+/* A Reduced Dependence Graph (RDG) vertex representing a statement. */
typedef struct rdg_vertex
{
/* The statement represented by this vertex. */
tree stmt;
+
+ /* True when the statement contains a write to memory. */
+ bool has_mem_write;
+
+ /* True when the statement contains a read from memory. */
+ bool has_mem_reads;
} *rdg_vertex_p;
-#define RDGV_STMT(V) ((struct rdg_vertex *) ((V)->data))->stmt
+#define RDGV_STMT(V) ((struct rdg_vertex *) ((V)->data))->stmt
+#define RDGV_HAS_MEM_WRITE(V) ((struct rdg_vertex *) ((V)->data))->has_mem_write
+#define RDGV_HAS_MEM_READS(V) ((struct rdg_vertex *) ((V)->data))->has_mem_reads
+#define RDG_STMT(RDG, I) RDGV_STMT (&(RDG->vertices[I]))
+#define RDG_MEM_WRITE_STMT(RDG, I) RDGV_HAS_MEM_WRITE (&(RDG->vertices[I]))
+#define RDG_MEM_READS_STMT(RDG, I) RDGV_HAS_MEM_READS (&(RDG->vertices[I]))
+
+void dump_rdg_vertex (FILE *, struct graph *, int);
+void debug_rdg_vertex (struct graph *, int);
+void dump_rdg_component (FILE *, struct graph *, int, bitmap);
+void debug_rdg_component (struct graph *, int);
+void dump_rdg (FILE *, struct graph *);
+void debug_rdg (struct graph *);
+void dot_rdg (struct graph *);
+int rdg_vertex_for_stmt (struct graph *, tree);
/* Data dependence type. */
@@ -363,11 +446,17 @@ typedef struct rdg_edge
{
/* Type of the dependence. */
enum rdg_dep_type type;
+
+ /* Levels of the dependence: the depth of the loops that
+ carry the dependence. */
+ unsigned level;
} *rdg_edge_p;
#define RDGE_TYPE(E) ((struct rdg_edge *) ((E)->data))->type
+#define RDGE_LEVEL(E) ((struct rdg_edge *) ((E)->data))->level
struct graph *build_rdg (struct loop *);
+void free_rdg (struct graph *);
/* Return the index of the variable VAR in the LOOP_NEST array. */
@@ -385,6 +474,21 @@ index_in_loop_nest (int var, VEC (loop_p, heap) *loop_nest)
return var_index;
}
+void stores_from_loop (struct loop *, VEC (tree, heap) **);
+void remove_similar_memory_refs (VEC (tree, heap) **);
+bool rdg_defs_used_in_other_loops_p (struct graph *, int);
+bool have_similar_memory_accesses (tree, tree);
+
+/* Determines whether RDG vertices V1 and V2 access to similar memory
+ locations, in which case they have to be in the same partition. */
+
+static inline bool
+rdg_has_similar_memory_accesses (struct graph *rdg, int v1, int v2)
+{
+ return have_similar_memory_accesses (RDG_STMT (rdg, v1),
+ RDG_STMT (rdg, v2));
+}
+
/* In lambda-code.c */
bool lambda_transform_legal_p (lambda_trans_matrix, int, VEC (ddr_p, heap) *);
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index 6af106af934..a377deb959f 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -1,5 +1,5 @@
/* Tree-dumping functionality for intermediate representation.
- Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>
@@ -550,7 +550,7 @@ dequeue_and_dump (dump_info_p di)
dump_string_field (di, "link", "extern");
else
dump_string_field (di, "link", "static");
- if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
+ if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
dump_child ("body", DECL_SAVED_TREE (t));
break;
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index 75288e991cb..1f8a3096cb9 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -512,7 +512,7 @@ next_readonly_imm_use (imm_use_iterator *imm)
imm->imm_use = old->next;
if (end_readonly_imm_use_p (imm))
- return old;
+ return NULL_USE_OPERAND_P;
return imm->imm_use;
}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 286c60bce20..555d3a32a57 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -792,6 +792,7 @@ extern void end_recording_case_labels (void);
extern basic_block move_sese_region_to_fn (struct function *, basic_block,
basic_block);
void remove_edge_and_dominated_blocks (edge);
+void mark_virtual_ops_in_bb (basic_block);
/* In tree-cfgcleanup.c */
extern bitmap cfgcleanup_altered_bbs;
@@ -1022,6 +1023,8 @@ bool tree_duplicate_loop_to_header_edge (struct loop *, edge,
unsigned int, sbitmap,
edge, VEC (edge, heap) **,
int);
+struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
+void rename_variables_in_loop (struct loop *);
struct loop *tree_ssa_loop_version (struct loop *, tree,
basic_block *);
tree expand_simple_operations (tree);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 9fb87926cf5..74895a82c93 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1899,7 +1899,6 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
/* We cannot inline functions that take a variable number of
arguments. */
case BUILT_IN_VA_START:
- case BUILT_IN_STDARG_START:
case BUILT_IN_NEXT_ARG:
case BUILT_IN_VA_END:
inline_forbidden_reason
@@ -3724,5 +3723,7 @@ build_duplicate_type (tree type)
pointer_map_destroy (id.decl_map);
+ TYPE_CANONICAL (type) = type;
+
return type;
}
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
new file mode 100644
index 00000000000..2d4a5d69373
--- /dev/null
+++ b/gcc/tree-loop-distribution.c
@@ -0,0 +1,1173 @@
+/* Loop distribution.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+ Contributed by Georges-Andre Silber <Georges-Andre.Silber@ensmp.fr>
+ and Sebastian Pop <sebastian.pop@amd.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* This pass performs loop distribution: for example, the loop
+
+ |DO I = 2, N
+ | A(I) = B(I) + C
+ | D(I) = A(I-1)*E
+ |ENDDO
+
+ is transformed to
+
+ |DOALL I = 2, N
+ | A(I) = B(I) + C
+ |ENDDO
+ |
+ |DOALL I = 2, N
+ | D(I) = A(I-1)*E
+ |ENDDO
+
+ This pass uses an RDG, Reduced Dependence Graph built on top of the
+ data dependence relations. The RDG is then topologically sorted to
+ obtain a map of information producers/consumers based on which it
+ generates the new loops. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "ggc.h"
+#include "tree.h"
+#include "target.h"
+
+#include "rtl.h"
+#include "basic-block.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "timevar.h"
+#include "cfgloop.h"
+#include "expr.h"
+#include "optabs.h"
+#include "tree-chrec.h"
+#include "tree-data-ref.h"
+#include "tree-scalar-evolution.h"
+#include "tree-pass.h"
+#include "lambda.h"
+#include "langhooks.h"
+#include "tree-vectorizer.h"
+
+/* If bit I is not set, it means that this node represents an
+ operation that has already been performed, and that should not be
+ performed again. This is the subgraph of remaining important
+ computations that is passed to the DFS algorithm for avoiding to
+ include several times the same stores in different loops. */
+static bitmap remaining_stmts;
+
+/* A node of the RDG is marked in this bitmap when it has as a
+ predecessor a node that writes to memory. */
+static bitmap upstream_mem_writes;
+
+/* Update the PHI nodes of NEW_LOOP. NEW_LOOP is a duplicate of
+ ORIG_LOOP. */
+
+static void
+update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
+{
+ tree new_ssa_name;
+ tree phi_new, phi_orig;
+ edge orig_loop_latch = loop_latch_edge (orig_loop);
+ edge orig_entry_e = loop_preheader_edge (orig_loop);
+ edge new_loop_entry_e = loop_preheader_edge (new_loop);
+
+ /* Scan the phis in the headers of the old and new loops
+ (they are organized in exactly the same order). */
+
+ for (phi_new = phi_nodes (new_loop->header),
+ phi_orig = phi_nodes (orig_loop->header);
+ phi_new && phi_orig;
+ phi_new = PHI_CHAIN (phi_new), phi_orig = PHI_CHAIN (phi_orig))
+ {
+ /* Add the first phi argument for the phi in NEW_LOOP (the one
+ associated with the entry of NEW_LOOP) */
+ tree def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
+ add_phi_arg (phi_new, def, new_loop_entry_e);
+
+ /* Add the second phi argument for the phi in NEW_LOOP (the one
+ associated with the latch of NEW_LOOP) */
+ def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
+
+ if (TREE_CODE (def) == SSA_NAME)
+ {
+ new_ssa_name = get_current_def (def);
+
+ if (!new_ssa_name)
+ /* This only happens if there are no definitions inside the
+ loop. Use the phi_result in this case. */
+ new_ssa_name = PHI_RESULT (phi_new);
+ }
+ else
+ /* Could be an integer. */
+ new_ssa_name = def;
+
+ add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
+ }
+}
+
+/* Return a copy of LOOP placed before LOOP. */
+
+static struct loop *
+copy_loop_before (struct loop *loop)
+{
+ struct loop *res;
+ edge preheader = loop_preheader_edge (loop);
+
+ if (!single_exit (loop))
+ return NULL;
+
+ initialize_original_copy_tables ();
+ res = slpeel_tree_duplicate_loop_to_edge_cfg (loop, preheader);
+ free_original_copy_tables ();
+
+ if (!res)
+ return NULL;
+
+ update_phis_for_loop_copy (loop, res);
+ rename_variables_in_loop (res);
+
+ return res;
+}
+
+/* Creates an empty basic block after LOOP. */
+
+static void
+create_bb_after_loop (struct loop *loop)
+{
+ edge exit = single_exit (loop);
+
+ if (!exit)
+ return;
+
+ split_edge (exit);
+}
+
+/* Generate code for PARTITION from the code in LOOP. The loop is
+ copied when COPY_P is true. All the statements not flagged in the
+ PARTITION bitmap are removed from the loop or from its copy. The
+ statements are indexed in sequence inside a basic block, and the
+ basic blocks of a loop are taken in dom order. Returns true when
+ the code gen succeeded. */
+
+static bool
+generate_loops_for_partition (struct loop *loop, bitmap partition, bool copy_p)
+{
+ unsigned i, x;
+ block_stmt_iterator bsi;
+ basic_block *bbs;
+
+ if (copy_p)
+ {
+ loop = copy_loop_before (loop);
+ create_preheader (loop, CP_SIMPLE_PREHEADERS);
+ create_bb_after_loop (loop);
+ }
+
+ if (loop == NULL)
+ return false;
+
+ /* Remove stmts not in the PARTITION bitmap. The order in which we
+ visit the phi nodes and the statements is exactly as in
+ stmts_from_loop. */
+ bbs = get_loop_body_in_dom_order (loop);
+
+ for (x = 0, i = 0; i < loop->num_nodes; i++)
+ {
+ basic_block bb = bbs[i];
+ tree phi, prev = NULL_TREE, next;
+
+ for (phi = phi_nodes (bb); phi;)
+ if (!bitmap_bit_p (partition, x++))
+ {
+ next = PHI_CHAIN (phi);
+ remove_phi_node (phi, prev, true);
+ phi = next;
+ }
+ else
+ {
+ prev = phi;
+ phi = PHI_CHAIN (phi);
+ }
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
+ if (TREE_CODE (bsi_stmt (bsi)) != LABEL_EXPR
+ && !bitmap_bit_p (partition, x++))
+ bsi_remove (&bsi, false);
+ else
+ bsi_next (&bsi);
+
+ mark_virtual_ops_in_bb (bb);
+ }
+
+ free (bbs);
+ return true;
+}
+
+/* Generate a call to memset. Return true when the operation succeeded. */
+
+static bool
+generate_memset_zero (tree stmt, tree op0, tree nb_iter,
+ block_stmt_iterator bsi)
+{
+ tree s, t, stmts, nb_bytes, addr_base;
+ bool res = false;
+ tree stmt_list = NULL_TREE;
+ tree args [3];
+ tree fn_call, mem, fndecl, fntype, fn;
+ tree_stmt_iterator i;
+ ssa_op_iter iter;
+ struct data_reference *dr = XCNEW (struct data_reference);
+
+ nb_bytes = fold_build2 (MULT_EXPR, TREE_TYPE (nb_iter),
+ nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op0)));
+ nb_bytes = force_gimple_operand (nb_bytes, &stmts, true, NULL);
+ append_to_statement_list_force (stmts, &stmt_list);
+
+ DR_STMT (dr) = stmt;
+ DR_REF (dr) = op0;
+ dr_analyze_innermost (dr);
+
+ /* Test for a positive stride, iterating over every element. */
+ if (integer_zerop (fold_build2 (MINUS_EXPR, integer_type_node, DR_STEP (dr),
+ TYPE_SIZE_UNIT (TREE_TYPE (op0)))))
+ addr_base = fold_build2 (PLUS_EXPR, TREE_TYPE (DR_BASE_ADDRESS (dr)),
+ DR_BASE_ADDRESS (dr),
+ size_binop (PLUS_EXPR,
+ DR_OFFSET (dr), DR_INIT (dr)));
+
+ /* Test for a negative stride, iterating over every element. */
+ else if (integer_zerop (fold_build2 (PLUS_EXPR, integer_type_node,
+ TYPE_SIZE_UNIT (TREE_TYPE (op0)),
+ DR_STEP (dr))))
+ {
+ addr_base = size_binop (PLUS_EXPR, DR_OFFSET (dr), DR_INIT (dr));
+ addr_base = fold_build2 (MINUS_EXPR, sizetype, addr_base, nb_bytes);
+ addr_base = force_gimple_operand (addr_base, &stmts, true, NULL);
+ append_to_statement_list_force (stmts, &stmt_list);
+
+ addr_base = fold_build2 (POINTER_PLUS_EXPR,
+ TREE_TYPE (DR_BASE_ADDRESS (dr)),
+ DR_BASE_ADDRESS (dr), addr_base);
+ }
+ else
+ goto end;
+
+ mem = force_gimple_operand (addr_base, &stmts, true, NULL);
+ append_to_statement_list_force (stmts, &stmt_list);
+
+
+ fndecl = implicit_built_in_decls [BUILT_IN_MEMSET];
+ fntype = TREE_TYPE (fndecl);
+ fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
+
+ args[0] = mem;
+ args[1] = integer_zero_node;
+ args[2] = nb_bytes;
+
+ fn_call = build_call_array (fntype, fn, 3, args);
+ append_to_statement_list_force (fn_call, &stmt_list);
+
+ for (i = tsi_start (stmt_list); !tsi_end_p (i); tsi_next (&i))
+ {
+ s = tsi_stmt (i);
+ update_stmt_if_modified (s);
+
+ FOR_EACH_SSA_TREE_OPERAND (t, s, iter, SSA_OP_VIRTUAL_DEFS)
+ {
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+ mark_sym_for_renaming (t);
+ }
+ }
+
+ /* Mark also the uses of the VDEFS of STMT to be renamed. */
+ FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, SSA_OP_VIRTUAL_DEFS)
+ {
+ if (TREE_CODE (t) == SSA_NAME)
+ {
+ imm_use_iterator imm_iter;
+
+ FOR_EACH_IMM_USE_STMT (s, imm_iter, t)
+ update_stmt (s);
+
+ t = SSA_NAME_VAR (t);
+ }
+ mark_sym_for_renaming (t);
+ }
+
+ bsi_insert_after (&bsi, stmt_list, BSI_CONTINUE_LINKING);
+ res = true;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "generated memset zero\n");
+
+ end:
+ free_data_ref (dr);
+ return res;
+}
+
+/* Tries to generate a builtin function for the instructions of LOOP
+ pointed to by the bits set in PARTITION. Returns true when the
+ operation succeeded. */
+
+static bool
+generate_builtin (struct loop *loop, bitmap partition, bool copy_p)
+{
+ bool res = false;
+ unsigned i, x = 0;
+ basic_block *bbs;
+ tree write = NULL_TREE;
+ tree op0, op1;
+ block_stmt_iterator bsi;
+ tree nb_iter = number_of_exit_cond_executions (loop);
+
+ if (!nb_iter || nb_iter == chrec_dont_know)
+ return false;
+
+ bbs = get_loop_body_in_dom_order (loop);
+
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ basic_block bb = bbs[i];
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ x++;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ if (bitmap_bit_p (partition, x++)
+ && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ && !is_gimple_reg (GIMPLE_STMT_OPERAND (stmt, 0)))
+ {
+ /* Don't generate the builtins when there are more than
+ one memory write. */
+ if (write != NULL)
+ goto end;
+
+ write = stmt;
+ }
+ }
+ }
+
+ if (!write)
+ goto end;
+
+ op0 = GIMPLE_STMT_OPERAND (write, 0);
+ op1 = GIMPLE_STMT_OPERAND (write, 1);
+
+ if (!(TREE_CODE (op0) == ARRAY_REF
+ || TREE_CODE (op0) == INDIRECT_REF))
+ goto end;
+
+ /* The new statements will be placed before LOOP. */
+ bsi = bsi_last (loop_preheader_edge (loop)->src);
+
+ if (integer_zerop (op1) || real_zerop (op1))
+ res = generate_memset_zero (write, op0, nb_iter, bsi);
+
+ /* If this is the last partition for which we generate code, we have
+ to destroy the loop. */
+ if (res && !copy_p)
+ {
+ unsigned nbbs = loop->num_nodes;
+ basic_block src = loop_preheader_edge (loop)->src;
+ basic_block dest = single_exit (loop)->dest;
+ make_edge (src, dest, EDGE_FALLTHRU);
+ set_immediate_dominator (CDI_DOMINATORS, dest, src);
+ cancel_loop_tree (loop);
+
+ for (i = 0; i < nbbs; i++)
+ delete_basic_block (bbs[i]);
+ }
+
+ end:
+ free (bbs);
+ return res;
+}
+
+/* Generates code for PARTITION. For simple loops, this function can
+ generate a built-in. */
+
+static bool
+generate_code_for_partition (struct loop *loop, bitmap partition, bool copy_p)
+{
+ if (generate_builtin (loop, partition, copy_p))
+ return true;
+
+ return generate_loops_for_partition (loop, partition, copy_p);
+}
+
+
+/* Returns true if the node V of RDG cannot be recomputed. */
+
+static bool
+rdg_cannot_recompute_vertex_p (struct graph *rdg, int v)
+{
+ if (RDG_MEM_WRITE_STMT (rdg, v))
+ return true;
+
+ return false;
+}
+
+/* Returns true when the vertex V has already been generated in the
+ current partition (V is in PROCESSED), or when V belongs to another
+ partition and cannot be recomputed (V is not in REMAINING_STMTS). */
+
+static inline bool
+already_processed_vertex_p (bitmap processed, int v)
+{
+ return (bitmap_bit_p (processed, v)
+ || !bitmap_bit_p (remaining_stmts, v));
+}
+
+/* Returns NULL when there is no anti-dependence among the successors
+ of vertex V, otherwise returns the edge with the anti-dep. */
+
+static struct graph_edge *
+has_anti_dependence (struct vertex *v)
+{
+ struct graph_edge *e;
+
+ if (v->succ)
+ for (e = v->succ; e; e = e->succ_next)
+ if (RDGE_TYPE (e) == anti_dd)
+ return e;
+
+ return NULL;
+}
+
+/* Returns true when V has an anti-dependence edge among its successors. */
+
+static bool
+predecessor_has_mem_write (struct graph *rdg, struct vertex *v)
+{
+ struct graph_edge *e;
+
+ if (v->pred)
+ for (e = v->pred; e; e = e->pred_next)
+ if (bitmap_bit_p (upstream_mem_writes, e->src)
+ /* Don't consider flow channels: a write to memory followed
+ by a read from memory. These channels allow the split of
+ the RDG in different partitions. */
+ && !RDG_MEM_WRITE_STMT (rdg, e->src))
+ return true;
+
+ return false;
+}
+
+/* Initializes the upstream_mem_writes bitmap following the
+ information from RDG. */
+
+static void
+mark_nodes_having_upstream_mem_writes (struct graph *rdg)
+{
+ int v, x;
+ bitmap seen = BITMAP_ALLOC (NULL);
+
+ for (v = rdg->n_vertices - 1; v >= 0; v--)
+ if (!bitmap_bit_p (seen, v))
+ {
+ unsigned i;
+ VEC (int, heap) *nodes = VEC_alloc (int, heap, 3);
+ bool has_upstream_mem_write_p = false;
+
+ graphds_dfs (rdg, &v, 1, &nodes, false, NULL);
+
+ for (i = 0; VEC_iterate (int, nodes, i, x); i++)
+ {
+ if (bitmap_bit_p (seen, x))
+ continue;
+
+ bitmap_set_bit (seen, x);
+
+ if (RDG_MEM_WRITE_STMT (rdg, x)
+ || predecessor_has_mem_write (rdg, &(rdg->vertices[x]))
+ /* In anti dependences the read should occur before
+ the write, this is why both the read and the write
+ should be placed in the same partition. */
+ || has_anti_dependence (&(rdg->vertices[x])))
+ {
+ has_upstream_mem_write_p = true;
+ bitmap_set_bit (upstream_mem_writes, x);
+ }
+ }
+
+ VEC_free (int, heap, nodes);
+ }
+}
+
+/* Returns true when vertex u has a memory write node as a predecessor
+ in RDG. */
+
+static bool
+has_upstream_mem_writes (int u)
+{
+ return bitmap_bit_p (upstream_mem_writes, u);
+}
+
+static void rdg_flag_vertex_and_dependent (struct graph *, int, bitmap, bitmap,
+ bitmap, bool *);
+
+/* Flag all the uses of U. */
+
+static void
+rdg_flag_all_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
+ bitmap processed, bool *part_has_writes)
+{
+ struct graph_edge *e;
+
+ for (e = rdg->vertices[u].succ; e; e = e->succ_next)
+ if (!bitmap_bit_p (processed, e->dest))
+ {
+ rdg_flag_vertex_and_dependent (rdg, e->dest, partition, loops,
+ processed, part_has_writes);
+ rdg_flag_all_uses (rdg, e->dest, partition, loops, processed,
+ part_has_writes);
+ }
+}
+
+/* Flag the uses of U stopping following the information from
+ upstream_mem_writes. */
+
+static void
+rdg_flag_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
+ bitmap processed, bool *part_has_writes)
+{
+ ssa_op_iter iter;
+ use_operand_p use_p;
+ struct vertex *x = &(rdg->vertices[u]);
+ tree stmt = RDGV_STMT (x);
+ struct graph_edge *anti_dep = has_anti_dependence (x);
+
+ /* Keep in the same partition the destination of an antidependence,
+ because this is a store to the exact same location. Putting this
+ in another partition is bad for cache locality. */
+ if (anti_dep)
+ {
+ int v = anti_dep->dest;
+
+ if (!already_processed_vertex_p (processed, v))
+ rdg_flag_vertex_and_dependent (rdg, v, partition, loops,
+ processed, part_has_writes);
+ }
+
+ if (TREE_CODE (stmt) != PHI_NODE)
+ {
+ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES)
+ {
+ tree use = USE_FROM_PTR (use_p);
+
+ if (TREE_CODE (use) == SSA_NAME)
+ {
+ tree def_stmt = SSA_NAME_DEF_STMT (use);
+ int v = rdg_vertex_for_stmt (rdg, def_stmt);
+
+ if (v >= 0
+ && !already_processed_vertex_p (processed, v))
+ rdg_flag_vertex_and_dependent (rdg, v, partition, loops,
+ processed, part_has_writes);
+ }
+ }
+ }
+
+ if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ && has_upstream_mem_writes (u))
+ {
+ tree op0 = GIMPLE_STMT_OPERAND (stmt, 0);
+
+ /* Scalar channels don't have enough space for transmitting data
+ between tasks, unless we add more storage by privatizing. */
+ if (is_gimple_reg (op0))
+ {
+ use_operand_p use_p;
+ imm_use_iterator iter;
+
+ FOR_EACH_IMM_USE_FAST (use_p, iter, op0)
+ {
+ int v = rdg_vertex_for_stmt (rdg, USE_STMT (use_p));
+
+ if (!already_processed_vertex_p (processed, v))
+ rdg_flag_vertex_and_dependent (rdg, v, partition, loops,
+ processed, part_has_writes);
+ }
+ }
+ }
+}
+
+/* Flag V from RDG as part of PARTITION, and also flag its loop number
+ in LOOPS. */
+
+static void
+rdg_flag_vertex (struct graph *rdg, int v, bitmap partition, bitmap loops,
+ bool *part_has_writes)
+{
+ struct loop *loop;
+
+ if (bitmap_bit_p (partition, v))
+ return;
+
+ loop = loop_containing_stmt (RDG_STMT (rdg, v));
+ bitmap_set_bit (loops, loop->num);
+ bitmap_set_bit (partition, v);
+
+ if (rdg_cannot_recompute_vertex_p (rdg, v))
+ {
+ *part_has_writes = true;
+ bitmap_clear_bit (remaining_stmts, v);
+ }
+}
+
+/* Flag in the bitmap PARTITION the vertex V and all its predecessors.
+ Alse flag their loop number in LOOPS. */
+
+static void
+rdg_flag_vertex_and_dependent (struct graph *rdg, int v, bitmap partition,
+ bitmap loops, bitmap processed,
+ bool *part_has_writes)
+{
+ unsigned i;
+ VEC (int, heap) *nodes = VEC_alloc (int, heap, 3);
+ int x;
+
+ bitmap_set_bit (processed, v);
+ rdg_flag_uses (rdg, v, partition, loops, processed, part_has_writes);
+ graphds_dfs (rdg, &v, 1, &nodes, false, remaining_stmts);
+ rdg_flag_vertex (rdg, v, partition, loops, part_has_writes);
+
+ for (i = 0; VEC_iterate (int, nodes, i, x); i++)
+ if (!already_processed_vertex_p (processed, x))
+ rdg_flag_vertex_and_dependent (rdg, x, partition, loops, processed,
+ part_has_writes);
+
+ VEC_free (int, heap, nodes);
+}
+
+/* Initialize CONDS with all the condition statements from the basic
+ blocks of LOOP. */
+
+static void
+collect_condition_stmts (struct loop *loop, VEC (tree, heap) **conds)
+{
+ unsigned i;
+ edge e;
+ VEC (edge, heap) *exits = get_loop_exit_edges (loop);
+
+ for (i = 0; VEC_iterate (edge, exits, i, e); i++)
+ {
+ tree cond = last_stmt (e->src);
+
+ if (cond)
+ VEC_safe_push (tree, heap, *conds, cond);
+ }
+
+ VEC_free (edge, heap, exits);
+}
+
+/* Add to PARTITION all the exit condition statements for LOOPS
+ together with all their dependent statements determined from
+ RDG. */
+
+static void
+rdg_flag_loop_exits (struct graph *rdg, bitmap loops, bitmap partition,
+ bitmap processed, bool *part_has_writes)
+{
+ unsigned i;
+ bitmap_iterator bi;
+ VEC (tree, heap) *conds = VEC_alloc (tree, heap, 3);
+
+ EXECUTE_IF_SET_IN_BITMAP (loops, 0, i, bi)
+ collect_condition_stmts (get_loop (i), &conds);
+
+ while (!VEC_empty (tree, conds))
+ {
+ tree cond = VEC_pop (tree, conds);
+ int v = rdg_vertex_for_stmt (rdg, cond);
+ bitmap new_loops = BITMAP_ALLOC (NULL);
+
+ if (!already_processed_vertex_p (processed, v))
+ rdg_flag_vertex_and_dependent (rdg, v, partition, new_loops, processed,
+ part_has_writes);
+
+ EXECUTE_IF_SET_IN_BITMAP (new_loops, 0, i, bi)
+ if (!bitmap_bit_p (loops, i))
+ {
+ bitmap_set_bit (loops, i);
+ collect_condition_stmts (get_loop (i), &conds);
+ }
+
+ BITMAP_FREE (new_loops);
+ }
+}
+
+/* Strongly connected components of the reduced data dependence graph. */
+
+typedef struct rdg_component
+{
+ int num;
+ VEC (int, heap) *vertices;
+} *rdgc;
+
+DEF_VEC_P (rdgc);
+DEF_VEC_ALLOC_P (rdgc, heap);
+
+/* Flag all the nodes of RDG containing memory accesses that could
+ potentially belong to arrays already accessed in the current
+ PARTITION. */
+
+static void
+rdg_flag_similar_memory_accesses (struct graph *rdg, bitmap partition,
+ bitmap loops, bitmap processed,
+ VEC (int, heap) **other_stores)
+{
+ bool foo;
+ unsigned i, n;
+ int j, k, kk;
+ bitmap_iterator ii;
+ struct graph_edge *e;
+
+ EXECUTE_IF_SET_IN_BITMAP (partition, 0, i, ii)
+ if (RDG_MEM_WRITE_STMT (rdg, i)
+ || RDG_MEM_READS_STMT (rdg, i))
+ {
+ for (j = 0; j < rdg->n_vertices; j++)
+ if (!bitmap_bit_p (processed, j)
+ && (RDG_MEM_WRITE_STMT (rdg, j)
+ || RDG_MEM_READS_STMT (rdg, j))
+ && rdg_has_similar_memory_accesses (rdg, i, j))
+ {
+ /* Flag first the node J itself, and all the nodes that
+ are needed to compute J. */
+ rdg_flag_vertex_and_dependent (rdg, j, partition, loops,
+ processed, &foo);
+
+ /* When J is a read, we want to coalesce in the same
+ PARTITION all the nodes that are using J: this is
+ needed for better cache locality. */
+ rdg_flag_all_uses (rdg, j, partition, loops, processed, &foo);
+
+ /* Remove from OTHER_STORES the vertex that we flagged. */
+ if (RDG_MEM_WRITE_STMT (rdg, j))
+ for (k = 0; VEC_iterate (int, *other_stores, k, kk); k++)
+ if (kk == j)
+ {
+ VEC_unordered_remove (int, *other_stores, k);
+ break;
+ }
+ }
+
+ /* If the node I has two uses, then keep these together in the
+ same PARTITION. */
+ for (n = 0, e = rdg->vertices[i].succ; e; e = e->succ_next, n++);
+
+ if (n > 1)
+ rdg_flag_all_uses (rdg, i, partition, loops, processed, &foo);
+ }
+}
+
+/* Returns a bitmap in which all the statements needed for computing
+ the strongly connected component C of the RDG are flagged, also
+ including the loop exit conditions. */
+
+static bitmap
+build_rdg_partition_for_component (struct graph *rdg, rdgc c,
+ bool *part_has_writes,
+ VEC (int, heap) **other_stores)
+{
+ int i, v;
+ bitmap partition = BITMAP_ALLOC (NULL);
+ bitmap loops = BITMAP_ALLOC (NULL);
+ bitmap processed = BITMAP_ALLOC (NULL);
+
+ for (i = 0; VEC_iterate (int, c->vertices, i, v); i++)
+ if (!already_processed_vertex_p (processed, v))
+ rdg_flag_vertex_and_dependent (rdg, v, partition, loops, processed,
+ part_has_writes);
+
+ /* Also iterate on the array of stores not in the starting vertices,
+ and determine those vertices that have some memory affinity with
+ the current nodes in the component: these are stores to the same
+ arrays, i.e. we're taking care of cache locality. */
+ rdg_flag_similar_memory_accesses (rdg, partition, loops, processed,
+ other_stores);
+
+ rdg_flag_loop_exits (rdg, loops, partition, processed, part_has_writes);
+
+ BITMAP_FREE (processed);
+ BITMAP_FREE (loops);
+ return partition;
+}
+
+/* Free memory for COMPONENTS. */
+
+static void
+free_rdg_components (VEC (rdgc, heap) *components)
+{
+ int i;
+ rdgc x;
+
+ for (i = 0; VEC_iterate (rdgc, components, i, x); i++)
+ {
+ VEC_free (int, heap, x->vertices);
+ free (x);
+ }
+}
+
+/* Build the COMPONENTS vector with the strongly connected components
+ of RDG in which the STARTING_VERTICES occur. */
+
+static void
+rdg_build_components (struct graph *rdg, VEC (int, heap) *starting_vertices,
+ VEC (rdgc, heap) **components)
+{
+ int i, v;
+ bitmap saved_components = BITMAP_ALLOC (NULL);
+ int n_components = graphds_scc (rdg, NULL);
+ VEC (int, heap) **all_components = XNEWVEC (VEC (int, heap) *, n_components);
+
+ for (i = 0; i < n_components; i++)
+ all_components[i] = VEC_alloc (int, heap, 3);
+
+ for (i = 0; i < rdg->n_vertices; i++)
+ VEC_safe_push (int, heap, all_components[rdg->vertices[i].component], i);
+
+ for (i = 0; VEC_iterate (int, starting_vertices, i, v); i++)
+ {
+ int c = rdg->vertices[v].component;
+
+ if (!bitmap_bit_p (saved_components, c))
+ {
+ rdgc x = XCNEW (struct rdg_component);
+ x->num = c;
+ x->vertices = all_components[c];
+
+ VEC_safe_push (rdgc, heap, *components, x);
+ bitmap_set_bit (saved_components, c);
+ }
+ }
+
+ for (i = 0; i < n_components; i++)
+ if (!bitmap_bit_p (saved_components, i))
+ VEC_free (int, heap, all_components[i]);
+
+ free (all_components);
+ BITMAP_FREE (saved_components);
+}
+
+DEF_VEC_P (bitmap);
+DEF_VEC_ALLOC_P (bitmap, heap);
+
+/* Aggregate several components into a useful partition that is
+ registered in the PARTITIONS vector. Partitions will be
+ distributed in different loops. */
+
+static void
+rdg_build_partitions (struct graph *rdg, VEC (rdgc, heap) *components,
+ VEC (int, heap) **other_stores,
+ VEC (bitmap, heap) **partitions, bitmap processed)
+{
+ int i;
+ rdgc x;
+ bitmap partition = BITMAP_ALLOC (NULL);
+
+ for (i = 0; VEC_iterate (rdgc, components, i, x); i++)
+ {
+ bitmap np;
+ bool part_has_writes = false;
+ int v = VEC_index (int, x->vertices, 0);
+
+ if (bitmap_bit_p (processed, v))
+ continue;
+
+ np = build_rdg_partition_for_component (rdg, x, &part_has_writes,
+ other_stores);
+ bitmap_ior_into (partition, np);
+ bitmap_ior_into (processed, np);
+ BITMAP_FREE (np);
+
+ if (part_has_writes)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "ldist useful partition:\n");
+ dump_bitmap (dump_file, partition);
+ }
+
+ VEC_safe_push (bitmap, heap, *partitions, partition);
+ partition = BITMAP_ALLOC (NULL);
+ }
+ }
+
+ /* Add the nodes from the RDG that were not marked as processed, and
+ that are used outside the current loop. These are scalar
+ computations that are not yet part of previous partitions. */
+ for (i = 0; i < rdg->n_vertices; i++)
+ if (!bitmap_bit_p (processed, i)
+ && rdg_defs_used_in_other_loops_p (rdg, i))
+ VEC_safe_push (int, heap, *other_stores, i);
+
+ /* If there are still statements left in the OTHER_STORES array,
+ create other components and partitions with these stores and
+ their dependences. */
+ if (VEC_length (int, *other_stores) > 0)
+ {
+ VEC (rdgc, heap) *comps = VEC_alloc (rdgc, heap, 3);
+ VEC (int, heap) *foo = VEC_alloc (int, heap, 3);
+
+ rdg_build_components (rdg, *other_stores, &comps);
+ rdg_build_partitions (rdg, comps, &foo, partitions, processed);
+
+ VEC_free (int, heap, foo);
+ free_rdg_components (comps);
+ }
+
+ /* If there is something left in the last partition, save it. */
+ if (bitmap_count_bits (partition) > 0)
+ VEC_safe_push (bitmap, heap, *partitions, partition);
+ else
+ BITMAP_FREE (partition);
+}
+
+/* Dump to FILE the PARTITIONS. */
+
+static void
+dump_rdg_partitions (FILE *file, VEC (bitmap, heap) *partitions)
+{
+ int i;
+ bitmap partition;
+
+ for (i = 0; VEC_iterate (bitmap, partitions, i, partition); i++)
+ debug_bitmap_file (file, partition);
+}
+
+/* Debug PARTITIONS. */
+extern void debug_rdg_partitions (VEC (bitmap, heap) *);
+
+void
+debug_rdg_partitions (VEC (bitmap, heap) *partitions)
+{
+ dump_rdg_partitions (stderr, partitions);
+}
+
+/* Generate code from STARTING_VERTICES in RDG. Returns the number of
+ distributed loops. */
+
+static int
+ldist_gen (struct loop *loop, struct graph *rdg,
+ VEC (int, heap) *starting_vertices)
+{
+ int i, nbp;
+ VEC (rdgc, heap) *components = VEC_alloc (rdgc, heap, 3);
+ VEC (bitmap, heap) *partitions = VEC_alloc (bitmap, heap, 3);
+ VEC (int, heap) *other_stores = VEC_alloc (int, heap, 3);
+ bitmap partition, processed = BITMAP_ALLOC (NULL);
+
+ remaining_stmts = BITMAP_ALLOC (NULL);
+ upstream_mem_writes = BITMAP_ALLOC (NULL);
+
+ for (i = 0; i < rdg->n_vertices; i++)
+ {
+ bitmap_set_bit (remaining_stmts, i);
+
+ /* Save in OTHER_STORES all the memory writes that are not in
+ STARTING_VERTICES. */
+ if (RDG_MEM_WRITE_STMT (rdg, i))
+ {
+ int v;
+ unsigned j;
+ bool found = false;
+
+ for (j = 0; VEC_iterate (int, starting_vertices, j, v); j++)
+ if (i == v)
+ {
+ found = true;
+ break;
+ }
+
+ if (!found)
+ VEC_safe_push (int, heap, other_stores, i);
+ }
+ }
+
+ mark_nodes_having_upstream_mem_writes (rdg);
+ rdg_build_components (rdg, starting_vertices, &components);
+ rdg_build_partitions (rdg, components, &other_stores, &partitions,
+ processed);
+ BITMAP_FREE (processed);
+ nbp = VEC_length (bitmap, partitions);
+
+ if (nbp <= 1)
+ goto ldist_done;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_rdg_partitions (dump_file, partitions);
+
+ for (i = 0; VEC_iterate (bitmap, partitions, i, partition); i++)
+ if (!generate_code_for_partition (loop, partition, i < nbp - 1))
+ goto ldist_done;
+
+ rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
+ update_ssa (TODO_update_ssa_only_virtuals | TODO_update_ssa);
+
+ ldist_done:
+
+ BITMAP_FREE (remaining_stmts);
+ BITMAP_FREE (upstream_mem_writes);
+
+ for (i = 0; VEC_iterate (bitmap, partitions, i, partition); i++)
+ BITMAP_FREE (partition);
+
+ VEC_free (int, heap, other_stores);
+ VEC_free (bitmap, heap, partitions);
+ free_rdg_components (components);
+ return nbp;
+}
+
+/* Distributes the code from LOOP in such a way that producer
+ statements are placed before consumer statements. When STMTS is
+ NULL, performs the maximal distribution, if STMTS is not NULL,
+ tries to separate only these statements from the LOOP's body.
+ Returns the number of distributed loops. */
+
+static int
+distribute_loop (struct loop *loop, VEC (tree, heap) *stmts)
+{
+ bool res = false;
+ struct graph *rdg;
+ tree s;
+ unsigned i;
+ VEC (int, heap) *vertices;
+
+ if (loop->num_nodes > 2)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "FIXME: Loop %d not distributed: it has more than two basic blocks.\n",
+ loop->num);
+
+ return res;
+ }
+
+ rdg = build_rdg (loop);
+
+ if (!rdg)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "FIXME: Loop %d not distributed: failed to build the RDG.\n",
+ loop->num);
+
+ return res;
+ }
+
+ vertices = VEC_alloc (int, heap, 3);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_rdg (dump_file, rdg);
+
+ for (i = 0; VEC_iterate (tree, stmts, i, s); i++)
+ {
+ int v = rdg_vertex_for_stmt (rdg, s);
+
+ if (v >= 0)
+ {
+ VEC_safe_push (int, heap, vertices, v);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "ldist asked to generate code for vertex %d\n", v);
+ }
+ }
+
+ res = ldist_gen (loop, rdg, vertices);
+ VEC_free (int, heap, vertices);
+ free_rdg (rdg);
+
+ return res;
+}
+
+/* Distribute all loops in the current function. */
+
+static unsigned int
+tree_loop_distribution (void)
+{
+ struct loop *loop;
+ loop_iterator li;
+ int nb_generated_loops = 0;
+
+ FOR_EACH_LOOP (li, loop, 0)
+ {
+ VEC (tree, heap) *work_list = VEC_alloc (tree, heap, 3);
+
+ /* With the following working list, we're asking distribute_loop
+ to separate the stores of the loop: when dependences allow,
+ it will end on having one store per loop. */
+ stores_from_loop (loop, &work_list);
+
+ /* A simple heuristic for cache locality is to not split stores
+ to the same array. Without this call, an unrolled loop would
+ be split into as many loops as unroll factor, each loop
+ storing in the same array. */
+ remove_similar_memory_refs (&work_list);
+
+ nb_generated_loops = distribute_loop (loop, work_list);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ if (nb_generated_loops > 1)
+ fprintf (dump_file, "Loop %d distributed: split to %d loops.\n",
+ loop->num, nb_generated_loops);
+ else
+ fprintf (dump_file, "Loop %d is the same.\n", loop->num);
+ }
+
+ verify_loop_structure ();
+
+ VEC_free (tree, heap, work_list);
+ }
+
+ return 0;
+}
+
+static bool
+gate_tree_loop_distribution (void)
+{
+ return flag_tree_loop_distribution != 0;
+}
+
+struct tree_opt_pass pass_loop_distribution =
+{
+ "ldist", /* name */
+ gate_tree_loop_distribution, /* gate */
+ tree_loop_distribution, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_LOOP_DISTRIBUTION, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_loops, /* todo_flags_finish */
+ 0 /* letter */
+};
diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c
index 88a77dd228c..806d9e6d1cb 100644
--- a/gcc/tree-loop-linear.c
+++ b/gcc/tree-loop-linear.c
@@ -179,10 +179,14 @@ try_interchange_loops (lambda_trans_matrix trans,
VEC (data_reference_p, heap) *datarefs,
struct loop *first_loop)
{
+ bool res;
struct loop *loop_i;
struct loop *loop_j;
unsigned int dependence_steps_i, dependence_steps_j;
double_int access_strides_i, access_strides_j;
+ double_int small, large, nb_iter;
+ double_int l1_cache_size, l2_cache_size;
+ int cmp;
unsigned int nb_deps_not_carried_by_i, nb_deps_not_carried_by_j;
struct data_dependence_relation *ddr;
@@ -194,7 +198,10 @@ try_interchange_loops (lambda_trans_matrix trans,
ddr = VEC_index (ddr_p, dependence_relations, 0);
if (ddr == NULL || DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
return trans;
-
+
+ l1_cache_size = uhwi_to_double_int (L1_CACHE_SIZE * 1024);
+ l2_cache_size = uhwi_to_double_int (L2_CACHE_SIZE * 1024);
+
/* LOOP_I is always the outer loop. */
for (loop_j = first_loop->inner;
loop_j;
@@ -216,18 +223,38 @@ try_interchange_loops (lambda_trans_matrix trans,
/* Heuristics for loop interchange profitability:
+ 0. Don't transform if the smallest stride is larger than
+ the L2 cache, or if the largest stride multiplied by the
+ number of iterations is smaller than the L1 cache.
+
1. (spatial locality) Inner loops should have smallest
dependence steps.
2. (spatial locality) Inner loops should contain more
dependence relations not carried by the loop.
- 3. (temporal locality) Inner loops should have smallest
+ 3. (temporal locality) Inner loops should have smallest
array access strides.
*/
+
+ cmp = double_int_ucmp (access_strides_i, access_strides_j);
+ small = cmp < 0 ? access_strides_i : access_strides_j;
+ large = cmp < 0 ? access_strides_j : access_strides_i;
+
+ if (double_int_ucmp (small, l2_cache_size) > 0)
+ continue;
+
+ res = cmp < 0 ?
+ estimated_loop_iterations (loop_j, false, &nb_iter):
+ estimated_loop_iterations (loop_i, false, &nb_iter);
+ large = double_int_mul (large, nb_iter);
+
+ if (res && double_int_ucmp (large, l1_cache_size) < 0)
+ continue;
+
if (dependence_steps_i < dependence_steps_j
|| nb_deps_not_carried_by_i > nb_deps_not_carried_by_j
- || double_int_ucmp (access_strides_i, access_strides_j) < 0)
+ || cmp < 0)
{
lambda_matrix_row_exchange (LTM_MATRIX (trans),
loop_depth (loop_i) - loop_depth (first_loop),
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
index 4b9c11830ba..190a3d3ce2d 100644
--- a/gcc/tree-mudflap.c
+++ b/gcc/tree-mudflap.c
@@ -1,5 +1,5 @@
/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Frank Ch. Eigler <fche@redhat.com>
and Graydon Hoare <graydon@redhat.com>
@@ -121,9 +121,7 @@ mf_varname_tree (tree decl)
const char *sourcefile;
unsigned sourceline = xloc.line;
unsigned sourcecolumn = 0;
-#ifdef USE_MAPPED_LOCATION
sourcecolumn = xloc.column;
-#endif
sourcefile = xloc.file;
if (sourcefile == NULL && current_function_decl != NULL_TREE)
sourcefile = DECL_SOURCE_FILE (current_function_decl);
@@ -214,11 +212,9 @@ mf_file_function_line_tree (location_t location)
if (xloc.line > 0)
{
-#ifdef USE_MAPPED_LOCATION
if (xloc.column > 0)
sprintf (linecolbuf, "%d:%d", xloc.line, xloc.column);
else
-#endif
sprintf (linecolbuf, "%d", xloc.line);
colon = ":";
line = linecolbuf;
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index cb30ba401cd..544d75daabe 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -427,10 +427,10 @@ tree_rest_of_compilation (tree fndecl)
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
- warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
+ warning (OPT_Wlarger_than_eq, "size of return value of %q+D is %u bytes",
fndecl, size_as_int);
else
- warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
+ warning (OPT_Wlarger_than_eq, "size of return value of %q+D is larger than %wd bytes",
fndecl, larger_than_size);
}
}
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 06b38929b5c..0033f6ad718 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -265,6 +265,7 @@ extern struct tree_opt_pass pass_scev_cprop;
extern struct tree_opt_pass pass_empty_loop;
extern struct tree_opt_pass pass_record_bounds;
extern struct tree_opt_pass pass_if_conversion;
+extern struct tree_opt_pass pass_loop_distribution;
extern struct tree_opt_pass pass_vectorize;
extern struct tree_opt_pass pass_complete_unroll;
extern struct tree_opt_pass pass_parallelize_loops;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 3b60b258ae4..b64571dbae2 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1,5 +1,5 @@
/* Pretty formatting of GENERIC trees in C syntax.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
@@ -3112,20 +3112,10 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
{
INDENT (indent);
- if ((flags & TDF_LINENO)
-#ifdef USE_MAPPED_LOCATION
- && e->goto_locus != UNKNOWN_LOCATION
-#else
- && e->goto_locus
-#endif
- )
+ if ((flags & TDF_LINENO) && e->goto_locus != UNKNOWN_LOCATION)
{
expanded_location goto_xloc;
-#ifdef USE_MAPPED_LOCATION
goto_xloc = expand_location (e->goto_locus);
-#else
- goto_xloc = *e->goto_locus;
-#endif
pp_character (buffer, '[');
if (goto_xloc.file)
{
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 26f1af4196a..1f2d6c25e62 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2139,7 +2139,7 @@ sra_build_assignment (tree dst, tree src)
if (scalar_bitfield_p (src))
{
tree var, shift, width;
- tree utype, stype, stmp, utmp;
+ tree utype, stype, stmp, utmp, dtmp;
tree list, stmt;
bool unsignedp = BIT_FIELD_REF_UNSIGNED (src);
@@ -2256,6 +2256,16 @@ sra_build_assignment (tree dst, tree src)
var = fold_convert (TREE_TYPE (dst), var);
else
var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var);
+
+ /* If the destination is not a register the conversion needs
+ to be a separate statement. */
+ if (!is_gimple_reg (dst))
+ {
+ dtmp = make_rename_temp (TREE_TYPE (dst), "SR");
+ stmt = build_gimple_modify_stmt (dtmp, var);
+ append_to_statement_list (stmt, &list);
+ var = dtmp;
+ }
}
stmt = build_gimple_modify_stmt (dst, var);
append_to_statement_list (stmt, &list);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 6a06b2a8004..a488257fdd4 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3256,7 +3256,9 @@ get_sccvn_value (tree name)
!ZERO_SSA_OPERANDS (defstmt2, SSA_OP_ALL_VIRTUALS))
gcc_assert (defstmt);
}
- valvh = vn_lookup_or_add_with_stmt (val, defstmt);
+ /* We lookup with the LHS, so do not use vn_lookup_or_add_with_stmt
+ here, as that will result in useless reference lookups. */
+ valvh = vn_lookup_or_add (val);
}
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 8380ebb35f2..929354e763d 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -241,9 +241,12 @@ static VEC (tree, heap) *sccstack;
DEF_VEC_P(vn_ssa_aux_t);
DEF_VEC_ALLOC_P(vn_ssa_aux_t, heap);
-/* Table of vn_ssa_aux_t's, one per ssa_name. */
+/* Table of vn_ssa_aux_t's, one per ssa_name. The vn_ssa_aux_t objects
+ are allocated on an obstack for locality reasons, and to free them
+ without looping over the VEC. */
static VEC (vn_ssa_aux_t, heap) *vn_ssa_aux_table;
+static struct obstack vn_ssa_aux_obstack;
/* Return the value numbering information for a given SSA name. */
@@ -264,13 +267,16 @@ VN_INFO_SET (tree name, vn_ssa_aux_t value)
SSA_NAME_VERSION (name), value);
}
-/* Get the value numbering info for a given SSA name, creating it if
- it does not exist. */
+/* Initialize the value numbering info for a given SSA name.
+ This should be called just once for every SSA name. */
vn_ssa_aux_t
VN_INFO_GET (tree name)
{
- vn_ssa_aux_t newinfo = XCNEW (struct vn_ssa_aux);
+ vn_ssa_aux_t newinfo;
+
+ newinfo = obstack_alloc (&vn_ssa_aux_obstack, sizeof (struct vn_ssa_aux));
+ memset (newinfo, 0, sizeof (struct vn_ssa_aux));
if (SSA_NAME_VERSION (name) >= VEC_length (vn_ssa_aux_t, vn_ssa_aux_table))
VEC_safe_grow (vn_ssa_aux_t, heap, vn_ssa_aux_table,
SSA_NAME_VERSION (name) + 1);
@@ -1225,6 +1231,8 @@ visit_reference_op_store (tree lhs, tree op, tree stmt)
{
if (TREE_CODE (result) == SSA_NAME)
result = SSA_VAL (result);
+ if (TREE_CODE (op) == SSA_NAME)
+ op = SSA_VAL (op);
resultsame = expressions_equal_p (result, op);
}
@@ -1521,13 +1529,10 @@ simplify_unary_expression (tree rhs)
static tree
try_to_simplify (tree stmt, tree rhs)
{
+ /* For stores we can end up simplifying a SSA_NAME rhs. Just return
+ in this case, there is no point in doing extra work. */
if (TREE_CODE (rhs) == SSA_NAME)
- {
- if (is_gimple_min_invariant (SSA_VAL (rhs)))
- return SSA_VAL (rhs);
- else if (VN_INFO (rhs)->has_constants)
- return VN_INFO (rhs)->expr;
- }
+ return rhs;
else
{
switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
@@ -1544,13 +1549,11 @@ try_to_simplify (tree stmt, tree rhs)
/* Fallthrough. */
case tcc_reference:
- {
- tree result = vn_reference_lookup (rhs,
- shared_vuses_from_stmt (stmt));
- if (result)
- return result;
- }
- /* Fallthrough for some codes. */
+ /* Do not do full-blown reference lookup here.
+ ??? But like for tcc_declaration, we should simplify
+ from constant initializers. */
+
+ /* Fallthrough for some codes that can operate on registers. */
if (!(TREE_CODE (rhs) == REALPART_EXPR
|| TREE_CODE (rhs) == IMAGPART_EXPR))
break;
@@ -2007,6 +2010,8 @@ init_scc_vn (void)
/* VEC_alloc doesn't actually grow it to the right size, it just
preallocates the space to do so. */
VEC_safe_grow (vn_ssa_aux_t, heap, vn_ssa_aux_table, num_ssa_names + 1);
+ gcc_obstack_init (&vn_ssa_aux_obstack);
+
shared_lookup_phiargs = NULL;
shared_lookup_vops = NULL;
shared_lookup_references = NULL;
@@ -2020,7 +2025,7 @@ init_scc_vn (void)
for (j = 0; j < n_basic_blocks - NUM_FIXED_BLOCKS; j++)
rpo_numbers[rpo_numbers_temp[j]] = j;
- free (rpo_numbers_temp);
+ XDELETE (rpo_numbers_temp);
VN_TOP = create_tmp_var_raw (void_type_node, "vn_top");
@@ -2071,19 +2076,18 @@ free_scc_vn (void)
VEC_free (tree, gc, shared_lookup_vops);
VEC_free (vn_reference_op_s, heap, shared_lookup_references);
XDELETEVEC (rpo_numbers);
+
for (i = 0; i < num_ssa_names; i++)
{
tree name = ssa_name (i);
- if (name)
- {
- XDELETE (VN_INFO (name));
- if (SSA_NAME_VALUE (name) &&
- TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
- SSA_NAME_VALUE (name) = NULL;
- }
+ if (name
+ && SSA_NAME_VALUE (name)
+ && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
+ SSA_NAME_VALUE (name) = NULL;
}
-
+ obstack_free (&vn_ssa_aux_obstack, NULL);
VEC_free (vn_ssa_aux_t, heap, vn_ssa_aux_table);
+
VEC_free (tree, heap, sccstack);
free_vn_table (valid_info);
XDELETE (valid_info);
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 8df09ec4979..8a275295aa4 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -648,7 +648,6 @@ execute_optimize_stdarg (void)
break;
/* If old style builtins are used, don't optimize anything. */
case BUILT_IN_SAVEREGS:
- case BUILT_IN_STDARG_START:
case BUILT_IN_ARGS_INFO:
case BUILT_IN_NEXT_ARG:
va_list_escapes = true;
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 3e8002f172b..9f9ea823f20 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -41,28 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "toplev.h"
#include "recog.h"
-/* Main analysis functions. */
-static bool vect_analyze_data_refs (loop_vec_info);
-static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
-static void vect_analyze_scalar_cycles (loop_vec_info);
-static bool vect_analyze_data_ref_accesses (loop_vec_info);
-static bool vect_analyze_data_ref_dependences (loop_vec_info);
-static bool vect_analyze_data_refs_alignment (loop_vec_info);
-static bool vect_compute_data_refs_alignment (loop_vec_info);
-static bool vect_enhance_data_refs_alignment (loop_vec_info);
-static bool vect_analyze_operations (loop_vec_info);
-static bool vect_determine_vectorization_factor (loop_vec_info);
-
-/* Utility functions for the analyses. */
-static bool exist_non_indexing_operands_for_use_p (tree, tree);
-static tree vect_get_loop_niters (struct loop *, tree *);
-static bool vect_analyze_data_ref_dependence
- (struct data_dependence_relation *, loop_vec_info);
-static bool vect_compute_data_ref_alignment (struct data_reference *);
-static bool vect_analyze_data_ref_access (struct data_reference *);
static bool vect_can_advance_ivs_p (loop_vec_info);
-static void vect_update_misalignment_for_peel
- (struct data_reference *, struct data_reference *, int npeel);
/* Function vect_determine_vectorization_factor
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 352939f03b2..883d7457077 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -1,5 +1,5 @@
/* Transformation Utilities for Loop Vectorization.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Dorit Naishlos <dorit@il.ibm.com>
This file is part of GCC.
@@ -2111,11 +2111,7 @@ vect_finish_stmt_generation (tree stmt, tree vec_stmt,
/* Make sure bsi points to the stmt that is being vectorized. */
gcc_assert (stmt == bsi_stmt (*bsi));
-#ifdef USE_MAPPED_LOCATION
SET_EXPR_LOCATION (vec_stmt, EXPR_LOCATION (stmt));
-#else
- SET_EXPR_LOCUS (vec_stmt, EXPR_LOCUS (stmt));
-#endif
}
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 16b0ecacdb2..f657eeaa198 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -147,24 +147,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
/*************************************************************************
- Simple Loop Peeling Utilities
- *************************************************************************/
-static void slpeel_update_phis_for_duplicate_loop
- (struct loop *, struct loop *, bool after);
-static void slpeel_update_phi_nodes_for_guard1
- (edge, struct loop *, bool, basic_block *, bitmap *);
-static void slpeel_update_phi_nodes_for_guard2
- (edge, struct loop *, bool, basic_block *);
-static edge slpeel_add_loop_guard (basic_block, tree, basic_block, basic_block);
-
-static void rename_use_op (use_operand_p);
-static void rename_variables_in_bb (basic_block);
-static void rename_variables_in_loop (struct loop *);
-
-/*************************************************************************
General Vectorization Utilities
*************************************************************************/
-static void vect_set_dump_settings (void);
/* vect_dump will be set to stderr or dump_file if exist. */
FILE *vect_dump;
@@ -241,7 +225,7 @@ rename_variables_in_bb (basic_block bb)
/* Renames variables in new generated LOOP. */
-static void
+void
rename_variables_in_loop (struct loop *loop)
{
unsigned i;
@@ -806,7 +790,7 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
/* Given LOOP this function generates a new copy of it and puts it
on E which is either the entry or exit of LOOP. */
-static struct loop *
+struct loop *
slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
{
struct loop *new_loop;
@@ -871,6 +855,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
if (at_exit) /* Add the loop copy at exit. */
{
redirect_edge_and_branch_force (e, new_loop->header);
+ PENDING_STMT (e) = NULL;
set_immediate_dominator (CDI_DOMINATORS, new_loop->header, e->src);
if (was_imm_dom)
set_immediate_dominator (CDI_DOMINATORS, exit_dest, new_loop->header);
@@ -888,6 +873,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
new_exit_e = EDGE_SUCC (new_loop->header, 1);
redirect_edge_and_branch_force (new_exit_e, loop->header);
+ PENDING_STMT (new_exit_e) = NULL;
set_immediate_dominator (CDI_DOMINATORS, loop->header,
new_exit_e->src);
@@ -901,6 +887,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
}
redirect_edge_and_branch_force (entry_e, new_loop->header);
+ PENDING_STMT (entry_e) = NULL;
set_immediate_dominator (CDI_DOMINATORS, new_loop->header, preheader);
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 7716e8e876e..7b2be7457b6 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1,5 +1,5 @@
/* Loop Vectorization
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Dorit Naishlos <dorit@il.ibm.com>
This file is part of GCC.
@@ -21,19 +21,11 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_VECTORIZER_H
#define GCC_TREE_VECTORIZER_H
-#ifdef USE_MAPPED_LOCATION
- typedef source_location LOC;
- #define UNKNOWN_LOC UNKNOWN_LOCATION
- #define EXPR_LOC(e) EXPR_LOCATION(e)
- #define LOC_FILE(l) LOCATION_FILE (l)
- #define LOC_LINE(l) LOCATION_LINE (l)
-#else
- typedef source_locus LOC;
- #define UNKNOWN_LOC NULL
- #define EXPR_LOC(e) EXPR_LOCUS(e)
- #define LOC_FILE(l) (l)->file
- #define LOC_LINE(l) (l)->line
-#endif
+typedef source_location LOC;
+#define UNKNOWN_LOC UNKNOWN_LOCATION
+#define EXPR_LOC(e) EXPR_LOCATION(e)
+#define LOC_FILE(l) LOCATION_FILE (l)
+#define LOC_LINE(l) LOCATION_LINE (l)
/* Used for naming of new temporaries. */
enum vect_var_kind {
@@ -638,6 +630,7 @@ extern struct loop *slpeel_tree_peel_loop_to_edge
(struct loop *, edge, tree, tree, bool, unsigned int, bool);
extern void set_prologue_iterations (basic_block, tree,
struct loop *, unsigned int);
+struct loop *tree_duplicate_loop_on_edge (struct loop *, edge);
extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
#ifdef ENABLE_CHECKING
diff --git a/gcc/tree.c b/gcc/tree.c
index 043968cb95f..c39bccda098 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1,6 +1,6 @@
/* Language-independent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -3019,11 +3019,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
TREE_SET_CODE (t, code);
TREE_TYPE (t) = type;
-#ifdef USE_MAPPED_LOCATION
SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
-#else
- SET_EXPR_LOCUS (t, NULL);
-#endif
TREE_OPERAND (t, 0) = node;
TREE_BLOCK (t) = NULL_TREE;
if (node && !TYPE_P (node))
@@ -3385,13 +3381,6 @@ build_block (tree vars, tree subblocks, tree supercontext, tree chain)
return block;
}
-#if 1 /* ! defined(USE_MAPPED_LOCATION) */
-/* ??? gengtype doesn't handle conditionals */
-static GTY(()) source_locus last_annotated_node;
-#endif
-
-#ifdef USE_MAPPED_LOCATION
-
expanded_location
expand_location (source_location loc)
{
@@ -3412,53 +3401,6 @@ expand_location (source_location loc)
return xloc;
}
-#else
-
-/* Record the exact location where an expression or an identifier were
- encountered. */
-
-void
-annotate_with_file_line (tree node, const char *file, int line)
-{
- location_t *new_loc;
-
- /* Roughly one percent of the calls to this function are to annotate
- a node with the same information already attached to that node!
- Just return instead of wasting memory. */
- if (EXPR_LOCUS (node)
- && EXPR_LINENO (node) == line
- && (EXPR_FILENAME (node) == file
- || !strcmp (EXPR_FILENAME (node), file)))
- {
- last_annotated_node = EXPR_LOCUS (node);
- return;
- }
-
- /* In heavily macroized code (such as GCC itself) this single
- entry cache can reduce the number of allocations by more
- than half. */
- if (last_annotated_node
- && last_annotated_node->line == line
- && (last_annotated_node->file == file
- || !strcmp (last_annotated_node->file, file)))
- {
- SET_EXPR_LOCUS (node, last_annotated_node);
- return;
- }
-
- new_loc = GGC_NEW (location_t);
- new_loc->file = file;
- new_loc->line = line;
- SET_EXPR_LOCUS (node, new_loc);
- last_annotated_node = new_loc;
-}
-
-void
-annotate_with_locus (tree node, location_t locus)
-{
- annotate_with_file_line (node, locus.file, locus.line);
-}
-#endif
/* Source location accessor functions. */
@@ -3469,71 +3411,39 @@ annotate_with_locus (tree node, location_t locus)
location_t
expr_location (const_tree node)
{
-#ifdef USE_MAPPED_LOCATION
if (GIMPLE_STMT_P (node))
return GIMPLE_STMT_LOCUS (node);
return EXPR_P (node) ? node->exp.locus : UNKNOWN_LOCATION;
-#else
- if (GIMPLE_STMT_P (node))
- return EXPR_HAS_LOCATION (node)
- ? *GIMPLE_STMT_LOCUS (node) : UNKNOWN_LOCATION;
- return EXPR_HAS_LOCATION (node) ? *node->exp.locus : UNKNOWN_LOCATION;
-#endif
}
void
set_expr_location (tree node, location_t locus)
{
-#ifdef USE_MAPPED_LOCATION
if (GIMPLE_STMT_P (node))
GIMPLE_STMT_LOCUS (node) = locus;
else
EXPR_CHECK (node)->exp.locus = locus;
-#else
- annotate_with_locus (node, locus);
-#endif
}
bool
expr_has_location (const_tree node)
{
-#ifdef USE_MAPPED_LOCATION
return expr_location (node) != UNKNOWN_LOCATION;
-#else
- return expr_locus (node) != NULL;
-#endif
}
-#ifdef USE_MAPPED_LOCATION
source_location *
-#else
-source_locus
-#endif
expr_locus (const_tree node)
{
-#ifdef USE_MAPPED_LOCATION
if (GIMPLE_STMT_P (node))
return CONST_CAST (source_location *, &GIMPLE_STMT_LOCUS (node));
return (EXPR_P (node)
? CONST_CAST (source_location *, &node->exp.locus)
: (source_location *) NULL);
-#else
- if (GIMPLE_STMT_P (node))
- return GIMPLE_STMT_LOCUS (node);
- return EXPR_P (node) ? node->exp.locus : (source_locus) NULL;
-#endif
}
void
-set_expr_locus (tree node,
-#ifdef USE_MAPPED_LOCATION
- source_location *loc
-#else
- source_locus loc
-#endif
- )
+set_expr_locus (tree node, source_location *loc)
{
-#ifdef USE_MAPPED_LOCATION
if (loc == NULL)
{
if (GIMPLE_STMT_P (node))
@@ -3548,12 +3458,6 @@ set_expr_locus (tree node,
else
EXPR_CHECK (node)->exp.locus = *loc;
}
-#else
- if (GIMPLE_STMT_P (node))
- GIMPLE_STMT_LOCUS (node) = loc;
- else
- EXPR_CHECK (node)->exp.locus = loc;
-#endif
}
/* Return the file name of the location of NODE. */
@@ -3561,8 +3465,8 @@ const char *
expr_filename (const_tree node)
{
if (GIMPLE_STMT_P (node))
- return LOCATION_FILE (location_from_locus (GIMPLE_STMT_LOCUS (node)));
- return LOCATION_FILE (location_from_locus (EXPR_CHECK (node)->exp.locus));
+ return LOCATION_FILE (GIMPLE_STMT_LOCUS (node));
+ return LOCATION_FILE (EXPR_CHECK (node)->exp.locus);
}
/* Return the line number of the location of NODE. */
@@ -3570,8 +3474,8 @@ int
expr_lineno (const_tree node)
{
if (GIMPLE_STMT_P (node))
- return LOCATION_LINE (location_from_locus (GIMPLE_STMT_LOCUS (node)));
- return LOCATION_LINE (location_from_locus (EXPR_CHECK (node)->exp.locus));
+ return LOCATION_LINE (GIMPLE_STMT_LOCUS (node));
+ return LOCATION_LINE (EXPR_CHECK (node)->exp.locus);
}
@@ -4067,6 +3971,16 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
return NULL_TREE;
}
+ if (TREE_CODE (node) == TYPE_DECL
+ && TREE_CODE (TREE_TYPE (node)) != RECORD_TYPE
+ && TREE_CODE (TREE_TYPE (node)) != UNION_TYPE)
+ {
+ *no_add_attrs = true;
+ warning (OPT_Wattributes, "%qs attribute ignored",
+ IDENTIFIER_POINTER (name));
+ return NULL_TREE;
+ }
+
/* Report error on dllimport ambiguities seen now before they cause
any damage. */
else if (is_attribute_p ("dllimport", name))
diff --git a/gcc/tree.h b/gcc/tree.h
index f98afe9be80..02682683769 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -417,7 +417,7 @@ struct tree_common GTY(())
struct gimple_stmt GTY(())
{
struct tree_base base;
- source_locus locus;
+ location_t locus;
tree block;
/* FIXME tuples: Eventually this should be of type ``struct gimple_expr''. */
tree GTY ((length ("TREE_CODE_LENGTH (TREE_CODE (&%h))"))) operands[1];
@@ -1841,7 +1841,7 @@ enum omp_clause_default_kind
struct tree_exp GTY(())
{
struct tree_common common;
- source_locus locus;
+ location_t locus;
tree block;
tree GTY ((special ("tree_exp"),
desc ("TREE_CODE ((tree) &%0)")))
@@ -2515,12 +2515,8 @@ struct function;
#define DECL_SOURCE_LOCATION(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.locus)
#define DECL_SOURCE_FILE(NODE) LOCATION_FILE (DECL_SOURCE_LOCATION (NODE))
#define DECL_SOURCE_LINE(NODE) LOCATION_LINE (DECL_SOURCE_LOCATION (NODE))
-#ifdef USE_MAPPED_LOCATION
#define DECL_IS_BUILTIN(DECL) \
(DECL_SOURCE_LOCATION (DECL) <= BUILTINS_LOCATION)
-#else
-#define DECL_IS_BUILTIN(DECL) (DECL_SOURCE_LINE(DECL) == 0)
-#endif
/* For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
@@ -3999,10 +3995,6 @@ extern tree build_decl_stat (enum tree_code, tree, tree MEM_STAT_DECL);
extern tree build_fn_decl (const char *, tree);
#define build_decl(c,t,q) build_decl_stat (c,t,q MEM_STAT_INFO)
extern tree build_block (tree, tree, tree, tree);
-#ifndef USE_MAPPED_LOCATION
-extern void annotate_with_file_line (tree, const char *, int);
-extern void annotate_with_locus (tree, location_t);
-#endif
extern tree build_empty_stmt (void);
extern tree build_omp_clause (enum omp_clause_code);
@@ -4935,13 +4927,8 @@ extern location_t expr_location (const_tree);
extern void set_expr_location (tree, location_t);
extern bool expr_has_location (const_tree);
-#ifdef USE_MAPPED_LOCATION
-extern source_locus *expr_locus (const_tree);
+extern location_t *expr_locus (const_tree);
extern void set_expr_locus (tree, source_location *);
-#else
-extern source_locus expr_locus (const_tree);
-extern void set_expr_locus (tree, source_locus loc);
-#endif
extern const char *expr_filename (const_tree);
extern int expr_lineno (const_tree);
diff --git a/gcc/treelang/ChangeLog b/gcc/treelang/ChangeLog
index 51a7988d91a..5aef0c14a3f 100644
--- a/gcc/treelang/ChangeLog
+++ b/gcc/treelang/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * tree1.c (treelang_init): Remove old location code.
+ (treelang_parse_file): Likewise.
+ * lex.l (LINEMAP_POSITION_FOR_COLUMN): Remove.
+ (update_lineno_charno): Remove old location code.
+
2008-02-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
PR other/35107
diff --git a/gcc/treelang/lex.l b/gcc/treelang/lex.l
index d0964c4af90..86a81d78343 100644
--- a/gcc/treelang/lex.l
+++ b/gcc/treelang/lex.l
@@ -5,7 +5,7 @@
---------------------------------------------------------------------
Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2007 Free Software Foundation, Inc.
+ 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -59,10 +59,6 @@ static void dump_lex_value (int lexret);
{fprintf (stderr, "\nlexer returning"); dump_lex_value (a);} return a;}
#define NOT_RETURN(a) {update_yylval (a); if (option_lexer_trace)\
{fprintf (stderr, "\nlexer swallowing"); dump_lex_value (a);}}
-#ifndef USE_MAPPED_LOCATION
-#undef LINEMAP_POSITION_FOR_COLUMN
-#define LINEMAP_POSITION_FOR_COLUMN(INPUT, LINETABLE, COL)
-#endif
%}
%option nostack
@@ -242,13 +238,9 @@ update_lineno_charno (void)
{
if ( yytext[yyl] == '\n' )
{
-#ifdef USE_MAPPED_LOCATION
source_location s = linemap_line_start (line_table, ++lineno,
80);
input_location = s;
-#else
- input_line = ++lineno;
-#endif
next_tree_charno = 1;
}
else
diff --git a/gcc/treelang/tree1.c b/gcc/treelang/tree1.c
index a2f990f862d..e667a846eba 100644
--- a/gcc/treelang/tree1.c
+++ b/gcc/treelang/tree1.c
@@ -2,7 +2,7 @@
Called by GCC's toplev.c
Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -139,11 +139,7 @@ treelang_handle_option (size_t scode, const char *arg ATTRIBUTE_UNUSED,
bool
treelang_init (void)
{
-#ifndef USE_MAPPED_LOCATION
- input_filename = main_input_filename;
-#else
linemap_add (line_table, LC_ENTER, false, main_input_filename, 1);
-#endif
/* This error will not happen from GCC as it will always create a
fake input file. */
@@ -165,10 +161,8 @@ treelang_init (void)
exit (1);
}
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_RENAME, false, "<built-in>", 1);
linemap_line_start (line_table, 0, 1);
-#endif
/* Init decls, etc. */
treelang_init_decl_processing ();
@@ -189,21 +183,15 @@ treelang_finish (void)
void
treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED)
{
-#ifdef USE_MAPPED_LOCATION
source_location s;
linemap_add (line_table, LC_RENAME, false, main_input_filename, 1);
s = linemap_line_start (line_table, 1, 80);
input_location = s;
-#else
- input_line = 1;
-#endif
treelang_debug ();
yyparse ();
cgraph_finalize_compilation_unit ();
-#ifdef USE_MAPPED_LOCATION
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
-#endif
cgraph_optimize ();
}