This commit was generated by cvs2svn to compensate for changes in r104752,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
kan 2002-10-10 04:40:18 +00:00
commit 369fa86760
40 changed files with 1236 additions and 724 deletions

View File

@ -1,3 +1,335 @@
2002-10-09 Zack Weinberg <zack@codesourcery.com>
PR c/7353
* c-decl.c (start_decl): Unconditionally issue error for
'typedef foo = bar'.
(finish_decl): Remove special case for TYPE_DECL with initializer.
* doc/extend.texi: Delete "Naming Types" section. Change all
cross-references to that section to refer to "Typeof" instead.
Add the useful safe-max()-macro example from "Naming Types" to
"Typeof", rewritten using that extension. Add some compatibility
notes to "Typeof."
2002-10-02 Richard Henderson <rth@redhat.com>
PR opt/7124
* config/i386/i386.c (ix86_register_move_cost): Increase cost
for secondary_memory_needed pairs.
Wed Oct 9 19:09:13 CEST 2002 Jan Hubicka <jh@suse.cz>
PR opt/7912
PR opt/7390
* i386.c (athlon_cost): Fix the move costs.
2002-10-09 Alan Modra <amodra@bigpond.net.au>
* libgcc2.c (__floatdisf): Properly cure double rounding.
2002-10-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
PR doc/7484
* doc/invoke.texi (Option Summary): List
-Wmissing-declarations as a C only option.
2002-10-08 Jakub Jelinek <jakub@redhat.com>
* config/sparc/t-linux64 (MULTILIB_OPTIONS): Remove
mno-app-regs|mcmodel=medany.
(MULTILIB_DIRNAMES, MULTILIB_OSDIRNAMES): Remove alt.
(MULTILIB_EXCEPTIONS, MULTILIB_EXCLUSIONS, MULTILIB_MATCHES): Remove.
(CRTSTUFF_T_CFLAGS): Define.
2002-09-25 Eric Botcazou <ebotcazou@libertysurf.fr>
Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c/7411
* expr.c (expand_expr) [PLUS]: Simplify after the operands
have been expanded in EXPAND_NORMAL mode.
2002-10-06 Richard Henderson <rth@redhat.com>
* config/rs6000/rs6000.md (load_toc_v4_PIC_2): Fix base constraint.
2002-10-06 Roger Sayle <roger@eyesopen.com>
PR optimization/6627
* toplev.c (force_align_functions_log): New global variable.
* flags.h (force_align_functions_log): Add extern prototype.
* varasm.c (assemble_start_function): Use it to force minimum
function alignment.
* config/i386/i386.h (FUNCTION_BOUNDARY): Set the correct
minimum function alignment to one byte.
(TARGET_PTRMEMFUNC_VBIT_LOCATION): Store the virtual bit in
the least significant bit of vtable member function pointers.
* tree.h (enum ptrmemfunc_vbit_where_t): Move definition to
here from cp/cp-tree.h.
2002-10-06 Neil Booth <neil@daikokuya.co.uk>
Debian BTS Bug #157416
* cpplib.c (destringize_and_run): Kludge around getting
tokens from in-progress macros.
(_cpp_do__Pragma): Simplify.
2002-10-06 Frank Ch. Eigler <fche@redhat.com>
* cppinit.c (init_standard_includes, parse_option): Use strncmp.
2002-10-05 Jakub Jelinek <jakub@redhat.com>
* gcc.c (set_multilib_dir): Don't access *end.
Use memcpy instead of strncpy. Don't write beyond malloced buffer.
(print_multilib_info): Don't show paths starting with ".:".
* genmultilib: Add new option, "yes" if multilibs are enabled.
Update comments. If multilibs not enabled, print .:${osdirout}
for each directory. If multilibs are enabled, always print
${dirout}:${osdirout}, even if the two are the same.
* Makefile.in (s-mlib): Pass @enable_multilib@ to genmultilib.
Pass all MULTILIB_* variables to genmultilib even if
--disable-multilib but MULTILIB_OSDIRNAMES is not empty.
* gcc.c (print_multi_os_directory): New variable.
(option_map): Support --print-multi-os-directory.
(struct prefix_list): Add os_multilib field.
(multilib_os_dir): New variable.
(static_specs): Add multilib_options.
(find_a_file): Add multilib argument. Search in GCC or OS multilib
subdirs if non-zero.
(read_specs, execute): Update callers.
(find_file): Likewise. Don't prefix name with multilib_dir, instead
pass 1 as multilib option.
(display_help): Include --print-multi-os-directory.
(add_prefix): Add os_multilib argument. Initialize pl->os_multilib.
(process_command): Update callers. Handle --print-multi-os-directory.
(do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is
set.
(main): Update find_a_file and add_prefix callers.
Handle print_multi_os_directory.
(struct mdswitchstr): New.
(mdswitches, n_mdswitches): New variables.
(used_arg): Add MULTILIB_DEFAULT switches too if they are not
present on the command line nor their mutually incompatible
switches.
(default_arg): Optimize.
(set_multilib_dir): Compute multilib_os_dir. Initialize mdswitches
array.
(print_multilib_info): Only print GCC multilib dir name, not OS
multilib dirname.
* genmultilib: Add osdirnames parameter. Output multilib_options
variable. If osdirnames is specified, output dirnames as
dirname:osdirname.
* mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory
and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES
to compute libgcc_s soname and install path.
* Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of
SHLIB_SLIBDIR_SUFFIXES to mklibgcc.
(s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib
argument.
* config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.
* config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64,
ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove.
(STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32
and -m64.
* config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.
* config/sparc/sol2-bi.h (STARTFILE_SPEC32, STARTFILE_SPEC64): Remove.
(STARTFILE_ARCH_SPEC): Remove.
(STARTFILE_SPEC): Add values-X*.o here.
* config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.
* config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
(STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between m32 and
!m32.
* config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.
2002-10-05 Neil Booth <neil@daikokuya.co.uk>
PR preprocessor/8120
* doc/cpp.texi: Update documentation of bad use of ##.
Thu Oct 3 23:15:15 CEST 2002 Jan Hubicka <jh@suse.cz>
* i386.h (CPP_SPECS): fix defines for -msse, -msse2, -mpentium2,3.
Thu Oct 3 21:35:36 CEST 2002 Jan Hubicka <jh@suse.cz>
* toplev.c (rest_of_compilation): Dump loops before clobbering
the structure.
* expr.c (force_operand): Use expand_simple_* to handle more
cases.
* i386.c (q_regs_operand): Use ANY_QI_REG_P.
* i386.c (override_options): Fix stack alignment.
(classify_argument): Handle variable sized types.
(ix86_expand_int_movcc): Avoid RTL sharing problem.
* i386.md (prefetch_sse_rex, prefetch_3dnow_rex): New.
(prefetch): Properly handle 64bit case.
* i386.c (classify_argument): Properly compute word size of the analyzed object.
* jump.c (reg_or_subregno): New function.
* rtl.h (reg_or_subregno): Declare
* unroll.c (find_splittable_givs): Handle subregs.
Richard Sandiford <rsandifo@redhat.com>:
* expr.c (force_operand): Fix reversed move.
Andreas Jaeger <aj@suse.de>:
* config/i386/linux64.h (STARTFILE_PREFIX_SPEC): New.
Janis Johnson <janis187@us.ibm.com>:
* loop.c (emit_prefetch_instructions): Several small fixes.
Thu Sep 5 00:34:33 2002 J"orn Rennecke <joern.rennecke@superh.com>
* loop.c (scan_loop): Don't mark separate insns out of a libcall
for moving.
(move_movables): Abort if we see the first insn of a libcall.
2002-10-01 David S. Miller <davem@redhat.com>
PR middle-end/7151
* config/sparc/sparc.md (movdi_insn_sp32_v9): Accept 'e' regs.
(movdi reg/reg split): Match only on sparc32, and v9 when int regs.
2002-10-01 David S. Miller <davem@redhat.com>
Jan Hubicka <jh@suse.cz>
* reload1.c (gen_reload:SECONDARY_MEMORY_NEEDED): Handle SUBREG.
* reload.c (push_reload:SECONDARY_MEMORY_NEEDED): Likewise.
2002-09-30 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.h (REG_CLASS_NAMES, REG_CLASS_CONTENTS):
Add new RL_REGS register class.
(PREFERRED_RELOAD_CLASS, PREFERRED_OUTPUT_RELOAD_CLASS):
Call xtensa_preferred_reload_class for both input and output reloads.
* config/xtensa/xtensa.c (xtensa_regno_to_class): Use new RL_REGS class.
(xtensa_preferred_reload_class): Handle output reloads; use RL_REGS
instead of either AR_REGS or GR_REGS classes.
(xtensa_secondary_reload_class): Use new RL_REGS class.
* config/xtensa/xtensa-protos.h (xtensa_preferred_reload_class): Update.
2002-08-21 John David Anglin <dave@hiauly1.hia.nrc.ca>
* cppinit.c (remove_dup_nonsys_dirs): Fix warning and return value.
2002-08-20 John David Anglin <dave@hiauly1.hia.nrc.ca>
* cppinit.c (remove_dup_dir): Add head_ptr argument to handle removal
at head.
(remove_dup_nonsys_dirs): New function.
(remove_dup_dirs): Change argument head to head_ptr. Remove warnings.
(merge_include_chains): Remove non-system include directories from
quote and bracket include chains when they duplicate equivalent system
directories.
* doc/cpp.texi (-I): Update.
* doc/cppopts.texi (-I): Update.
* doc/install.texi (--with-local-prefix): Further document usage of
this option.
* doc/invoke.texi (-I): Update.
2002-09-30 Richard Earnshaw <rearnsha@arm.com>
* arm.h (BASE_REG_CLASS): Always return LO_REGS for Thumb.
(MODE_BASE_REG_CLASS, case Thumb): Only return BASE_REGS if we know
that we have a SImode access, and only then if reload hasn't completed;
for all other cases, use LO_REGS.
2002-09-29 David S. Miller <davem@redhat.com>
* config/sparc/linux64.h (STARTFILE_SPEC32, ENDFILE_SPEC32): Kill
hardcoded paths.
2002-09-27 Alexander N. Kabaev <ak03@gte.com>
PR preprocessor/8055
* cppmacro.c (stringify_arg): Do not overflow the buffer
with the terminating NUL when the argument to be stringified
has no tokens.
2002-09-26 David S. Miller <davem@redhat.com>
PR optimization/7335
* calls.c (emit_library_call_value_1): Passing args by reference
converts a CONST function into a PURE one.
2002-09-26 Richard Henderson <rth@redhat.com>
PR c/7160
* sched-deps.c (sched_analyze_insn): Make clobber insns depend
on call insns.
2002-09-27 Alan Modra <amodra@bigpond.net.au>
* doloop.c (doloop_modify_runtime <biv skips initial incr>): Adjust
by absolute loop increment, not loop increment.
2002-09-25 David S. Miller <davem@redhat.com>
PR target/7842
* config/sparc/sparc.c (set_extends): SImode ASHIFT does not
extend.
2002-09-20 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
* config/arm/arm.md (sign_extract_onebit, not_signextract_onebit):
Add clobber of the condition code register.
2002-09-18 Richard Earnshaw (rearnsha@arm.com)
PR optimization/7967
* arm.md (ne_zeroextractsi): Add clobber of the condition code
register.
2002-09-17 Richard Henderson <rth@redhat.com>
* sibcall.c (optimize_sibling_and_tail_recursive_call): Also remove
RTX_UNCHANGING_P markers for successful tail-recursive replacement.
2002-09-16 Richard Henderson <rth@redhat.com>
PR opt/7515
* c-objc-common.c (c_cannot_inline_tree_fn): Don't auto-inline
functions that don't bind locally.
2002-09-17 Alan Modra <amodra@bigpond.net.au>
Merge from mainline.
2002-07-20 Alan Modra <amodra@bigpond.net.au>
PR optimization/7130
* loop.h (struct loop_info): Add "preconditioned".
* unroll.c (unroll_loop): Set it.
* doloop.c (doloop_modify_runtime): Correct count for unrolled loops.
2002-06-24 Alan Modra <amodra@bigpond.net.au>
PR optimization/6984
* doloop.c (doloop_valid_p): Correct comment.
(doloop_modify_runtime <abs_inc != 1>): Simplify.
(doloop_modify_runtime <do-while>): Don't emit code when NE.
2002-09-16 Jeff Law <law@redhat.com>
* libgcc2.c: Do not include machmode.h.
2002-09-16 Jason Merrill <jason@redhat.com>
Danny Smith <dannysmith@users.sourceforge.net>
* config/i386/winnt.c (ix86_handle_dll_attribute): Set
DECL_EXTERN and TREE_PUBLIC for dllimported variables here...
(i386_pe_mark_dllimport): Not here.
2002-09-14 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.md ("movdi_internal"): Allow any offsetable
@ -185,7 +517,7 @@
2002-08-27 Mark Mitchell <mark@codesourcery.com>
* doc/invoke.texi: Document -Wabi.
2002-08-23 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.c (rs6000_select_section): Treat
@ -201,7 +533,7 @@
* explow.c (expr_size): Call it.
(int_expr_size): New fn.
* expr.h: Declare it.
* expr.c (expand_expr) [CONSTRUCTOR]: Use it to calculate how
* expr.c (expand_expr) [CONSTRUCTOR]: Use it to calculate how
much to store.
2002-08-23 Alan Modra <amodra@bigpond.net.au>

View File

@ -149,6 +149,14 @@ c_cannot_inline_tree_fn (fnp)
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
/* Don't auto-inline anything that might not be bound within
this unit of translation. */
if (!DECL_DECLARED_INLINE_P (fn) && flag_pic && TREE_PUBLIC (fn))
{
DECL_UNINLINABLE (fn) = 1;
return 1;
}
if (! function_attribute_inlinable_p (fn))
{
DECL_UNINLINABLE (fn) = 1;

View File

@ -3666,6 +3666,14 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#endif
;
/* If this was a CONST function, it is now PURE since
it now reads memory. */
if (flags & ECF_CONST)
{
flags &= ~ECF_CONST;
flags |= ECF_PURE;
}
if (GET_MODE (val) == MEM && ! must_copy)
slot = val;
else if (must_copy)

View File

@ -1093,14 +1093,16 @@ enum reg_class
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
#define BASE_REG_CLASS (TARGET_THUMB ? BASE_REGS : GENERAL_REGS)
#define BASE_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
/* For the Thumb the high registers cannot be used as base
registers when addressing quanitities in QI or HI mode. */
/* For the Thumb the high registers cannot be used as base registers
when addressing quanitities in QI or HI mode; if we don't know the
mode, then we must be conservative. After reload we must also be
conservative, since we can't support SP+reg addressing, and we
can't fix up any bad substitutions. */
#define MODE_BASE_REG_CLASS(MODE) \
(TARGET_ARM ? BASE_REGS : \
(((MODE) == QImode || (MODE) == HImode || (MODE) == VOIDmode) \
? LO_REGS : BASE_REGS))
(TARGET_ARM ? GENERAL_REGS : \
(((MODE) == SImode && !reload_completed) ? BASE_REGS : LO_REGS))
/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
registers explicitly used in the rtl to be used as spill registers

View File

@ -1837,7 +1837,8 @@
(match_operand:SI 1 "s_register_operand" "r")
(match_operand:SI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n"))
(const_int 0)))]
(const_int 0)))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARM
&& (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
&& INTVAL (operands[2]) > 0
@ -8947,7 +8948,8 @@
[(set (match_operand:SI 0 "s_register_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
(const_int 1)
(match_operand:SI 2 "const_int_operand" "n")))]
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARM"
"*
operands[2] = GEN_INT (1 << INTVAL (operands[2]));
@ -8963,7 +8965,8 @@
(not:SI
(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
(const_int 1)
(match_operand:SI 2 "const_int_operand" "n"))))]
(match_operand:SI 2 "const_int_operand" "n"))))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARM"
"*
operands[2] = GEN_INT (1 << INTVAL (operands[2]));

View File

@ -50,21 +50,14 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{m32:%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
%{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \
crti.o%s %{static:crtbeginT.o%s}\
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}} \
%{!m32:%{!shared: \
%{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} \
%{!p:%{profile:/usr/lib64/gcrt1.o%s} %{!profile:/usr/lib64/crt1.o%s}}}}\
/usr/lib64/crti.o%s %{static:crtbeginT.o%s} \
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}}"
"%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
%{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \
crti.o%s %{static:crtbeginT.o%s} \
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "\
%{m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s} \
%{!m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s}"
#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
#define MULTILIB_DEFAULTS { "m64" }

View File

@ -6,10 +6,9 @@ SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
MULTILIB_OPTIONS = m64/m32
MULTILIB_DIRNAMES = 64 32
MULTILIB_OSDIRNAMES = ../lib64 ../lib
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
SHLIB_SLIBDIR_SUFFIXES = 64:64 32:

View File

@ -76,6 +76,15 @@ ix86_handle_dll_attribute (node, name, args, flags, no_add_attrs)
}
}
/* `extern' needn't be specified with dllimport.
Specify `extern' now and hope for the best. Sigh. */
else if (TREE_CODE (*node) == VAR_DECL
&& is_attribute_p ("dllimport", name))
{
DECL_EXTERNAL (*node) = 1;
TREE_PUBLIC (*node) = 1;
}
return NULL_TREE;
}
@ -300,16 +309,6 @@ i386_pe_mark_dllimport (decl)
return;
}
/* `extern' needn't be specified with dllimport.
Specify `extern' now and hope for the best. Sigh. */
if (TREE_CODE (decl) == VAR_DECL
/* ??? Is this test for vtables needed? */
&& !DECL_VIRTUAL_P (decl))
{
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
}
newname = alloca (strlen (oldname) + 11);
sprintf (newname, "@i._imp__%s", oldname);

View File

@ -9657,7 +9657,7 @@
(define_insn "load_toc_v4_PIC_2"
[(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
(minus:SI (match_operand:SI 2 "immediate_operand" "s")
(match_operand:SI 3 "immediate_operand" "s")))))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"

View File

@ -1,5 +1,5 @@
/* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF.
Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
Copyright 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
Contributed by David S. Miller (davem@caip.rutgers.edu)
This file is part of GNU CC.
@ -56,38 +56,12 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC32 \
#define STARTFILE_SPEC \
"%{!shared: \
%{pg:/usr/lib/gcrt1.o%s} %{!pg:%{p:/usr/lib/gcrt1.o%s} %{!p:/usr/lib/crt1.o%s}}}\
/usr/lib/crti.o%s %{static:crtbeginT.o%s}\
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
crti.o%s %{static:crtbeginT.o%s}\
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
#define STARTFILE_SPEC64 \
"%{!shared: \
%{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} %{!p:/usr/lib64/crt1.o%s}}}\
/usr/lib64/crti.o%s %{static:crtbeginT.o%s}\
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
#ifdef SPARC_BI_ARCH
#if DEFAULT_ARCH32_P
#define STARTFILE_SPEC "\
%{m32:" STARTFILE_SPEC32 "} \
%{m64:" STARTFILE_SPEC64 "} \
%{!m32:%{!m64:" STARTFILE_SPEC32 "}}"
#else
#define STARTFILE_SPEC "\
%{m32:" STARTFILE_SPEC32 "} \
%{m64:" STARTFILE_SPEC64 "} \
%{!m32:%{!m64:" STARTFILE_SPEC64 "}}"
#endif
#else
#define STARTFILE_SPEC STARTFILE_SPEC64
#endif
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
the GNU/Linux magical crtend.o file (see crtstuff.c) which
provides part of the support for getting C++ file-scope static
@ -96,36 +70,9 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC32 \
"%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib/crtn.o%s"
#define ENDFILE_SPEC64 \
"%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s"
#define ENDFILE_SPEC_COMMON \
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
#ifdef SPARC_BI_ARCH
#if DEFAULT_ARCH32_P
#define ENDFILE_SPEC "\
%{m32:" ENDFILE_SPEC32 "} \
%{m64:" ENDFILE_SPEC64 "} \
%{!m32:%{!m64:" ENDFILE_SPEC32 "}} " \
ENDFILE_SPEC_COMMON
#else
#define ENDFILE_SPEC "\
%{m32:" ENDFILE_SPEC32 "} \
%{m64:" ENDFILE_SPEC64 "} \
%{!m32:%{!m64:" ENDFILE_SPEC64 "}} " \
ENDFILE_SPEC_COMMON
#endif
#else
#define ENDFILE_SPEC ENDFILE_SPEC64 " " ENDFILE_SPEC_COMMON
#endif
#define ENDFILE_SPEC \
"%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s\
%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
/* The GNU C++ standard library requires that these macros be defined. */
#undef CPLUSPLUS_CPP_SPEC

View File

@ -72,30 +72,6 @@
%{!mcpu*:%(asm_cpu_default)} \
"
#define STARTFILE_SPEC32 "\
%{ansi:values-Xc.o%s} \
%{!ansi: \
%{traditional:values-Xt.o%s} \
%{!traditional:values-Xa.o%s}}"
#define STARTFILE_SPEC64 "\
%{ansi:/usr/lib/sparcv9/values-Xc.o%s} \
%{!ansi: \
%{traditional:/usr/lib/sparcv9/values-Xt.o%s} \
%{!traditional:/usr/lib/sparcv9/values-Xa.o%s}}"
#if DEFAULT_ARCH32_P
#define STARTFILE_ARCH_SPEC "\
%{m32:" STARTFILE_SPEC32 "} \
%{m64:" STARTFILE_SPEC64 "} \
%{!m32:%{!m64:" STARTFILE_SPEC32 "}}"
#else
#define STARTFILE_ARCH_SPEC "\
%{m32:" STARTFILE_SPEC32 "} \
%{m64:" STARTFILE_SPEC64 "} \
%{!m32:%{!m64:" STARTFILE_SPEC64 "}}"
#endif
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared: \
%{!symbolic: \
@ -103,7 +79,10 @@
%{!p: \
%{pg:gcrt1.o%s gmon.o%s} \
%{!pg:crt1.o%s}}}} \
crti.o%s " STARTFILE_ARCH_SPEC " \
crti.o%s \
%{ansi:values-Xc.o%s} \
%{!ansi: %{traditional:values-Xt.o%s} \
%{!traditional:values-Xa.o%s}} \
crtbegin.o%s"
#undef CPP_CPU_DEFAULT_SPEC

View File

@ -8650,7 +8650,6 @@ set_extends (insn)
return INTVAL (op1) >= 0;
return (GET_CODE (op1) == REG && sparc_check_64 (op1, insn) == 1);
}
case ASHIFT:
case LSHIFTRT:
return GET_MODE (SET_SRC (pat)) == SImode;
/* Positive integers leave the high bits zero. */

View File

@ -2517,7 +2517,7 @@
;
}")
;; Be careful, fmovd does not exist when !arch64.
;; Be careful, fmovd does not exist when !v9.
;; We match MEM moves directly when we have correct even
;; numbered registers, but fall into splits otherwise.
;; The constraint ordering here is really important to
@ -2531,9 +2531,9 @@
(define_insn "*movdi_insn_sp32_v9"
[(set (match_operand:DI 0 "nonimmediate_operand"
"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f,?e,?e,?W")
(match_operand:DI 1 "input_operand"
" J,J,U,T,r,o,i,r, f, T, o, f, f"))]
" J,J,U,T,r,o,i,r, f, T, o, f, f, e, W, e"))]
"! TARGET_ARCH64 && TARGET_V9
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
@ -2549,9 +2549,13 @@
ldd\\t%1, %0
#
#
#"
[(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
(set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
#
fmovd\\t%1, %0
ldd\\t%1, %0
std\\t%1, %0"
[(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*,fpmove,fpload,fpstore")
(set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2,*,*,*")
(set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
(define_insn "*movdi_insn_sp32"
[(set (match_operand:DI 0 "nonimmediate_operand"
@ -2861,7 +2865,14 @@
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
"! TARGET_ARCH64 && reload_completed"
"reload_completed
&& (! TARGET_V9
|| (! TARGET_ARCH64
&& ((GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) < 32)
|| (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG
&& REGNO (SUBREG_REG (operands[0])) < 32))))"
[(clobber (const_int 0))]
"
{

View File

@ -1,8 +1,6 @@
MULTILIB_OPTIONS = m64/m32 mno-app-regs|mcmodel=medany
MULTILIB_DIRNAMES = 64 32 alt
MULTILIB_MATCHES = mcmodel?medany=mcmodel?medmid
MULTILIB_EXCEPTIONS = m32/mno-app-regs* m32/mcmodel=*
MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany
MULTILIB_OPTIONS = m64/m32
MULTILIB_DIRNAMES = 64 32
MULTILIB_OSDIRNAMES = ../lib64 ../lib
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
@ -10,10 +8,12 @@ INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
crtfastmath.o
SHLIB_SLIBDIR_SUFFIXES = 64:64 32:
# Override t-slibgcc-elf-ver to export some libgcc symbols with
# the symbol versions that glibc used.
# Avoid the t-linux version file.
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
$(srcdir)/config/sparc/libgcc-sparc-glibc.ver
CRTSTUFF_T_CFLAGS = `if test x$$($(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) \
-print-multi-os-directory) \
= x../lib64; then echo -mcmodel=medany; fi`

View File

@ -1,11 +1,10 @@
MULTILIB_OPTIONS = m32/m64
MULTILIB_DIRNAMES = sparcv7 sparcv9
MULTILIB_MATCHES =
MULTILIB_OSDIRNAMES = . sparcv9
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o \
crtfastmath.o
SHLIB_SLIBDIR_SUFFIXES = sparcv9:/sparcv9 sparcv7:

View File

@ -1,3 +1,54 @@
2002-10-09 Zack Weinberg <zack@codesourcery.com>
PR c/7353
* decl.c (start_decl): Unconditionally issue error for
'typedef foo = bar'.
(cp_finish_decl): Remove special case for TYPE_DECL with initializer.
(grokdeclarator): Remove redundant error for 'typedef foo = bar'.
2002-10-03 Mark Mitchell <mark@codesourcery.com>
PR c++/7754
* decl2.c (finish_anon_union): Do not expand anonymous unions when
procesing template functions.
* pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
type. Call layout_decl.
(tsubst_expr, case DECL_STMT): Handle anonymous unions.
2002-10-07 Richard Henderson <rth@redhat.com>
* decl2.c: Complete reversion of c++/7754.
2002-10-06 Roger Sayle <roger@eyesopen.com>
PR optimization/6627
* cp/cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition
from here, and move it to tree.h.
* cp/decl.c (cxx_init_decl_processing): If storing the vbit
in function pointers, ensure that force_align_functions_log
is atleast one.
2002-10-04 H.J. Lu (hjl@gnu.org)
* pt.c (tsubst_decl, case VAR_DECL): Back out the last change.
(tsubst_expr, case DECL_STMT): Likewise.
2002-10-02 Mark Mitchell <mark@codesourcery.com>
PR c++/7754
* decl2.c (finish_anon_union): Do not expand anonymous unions when
procesing template functions.
* pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
type. Call layout_decl.
(tsubst_expr, case DECL_STMT): Handle anonymous unions.
2002-10-02 Mark Mitchell <mark@codesourcery.com>
PR c++/7188.
* init.c (expand_member_init): Allow a FIELD_DECL to be passed in
directly.
* pt.c (tsubst_initializer_list): Use expand_member_init.
2002-09-04 Jakub Jelinek <jakub@redhat.com>
* decl.c (start_cleanup_fn): Clear interface_only before
@ -336,7 +387,7 @@
2002-04-29 Nathan Sidwell <nathan@codesourcery.com>
PR c++/5719
* decl.c (grok_op_properties): Assignment ops don't have to return
* decl.c (grok_op_properties): Assignment ops don't have to return
by value. operator% should.
2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
@ -420,7 +471,7 @@
(finish_init_stmts): Set STMT_EXPR_NO_SCOPE.
* semantics.c (begin_gobal_stmt_expr): Adjust call to
expand_start_stmt_expr.
2002-04-15 Mark Mitchell <mark@codesourcery.com>
* decl.c (register_dtor_fn): Pass the address of dso_handle, not
@ -449,11 +500,11 @@
* typeck.c (type_after_usual_arithmetic_conversions):
If two types have the same variant, return immediately.
When two floating-point operands are the same precision:
When two floating-point operands are the same precision:
convert to float if one of the operands is float;
if neither operand is one of the standard types, return the type
of the first operand.
2002-04-12 Richard Sandiford <rsandifo@redhat.com>
* decl.c (duplicate_decls): Don't try to unify an implicit typedef
@ -511,7 +562,7 @@
set before checking it.
PR c++/6179
* method.c (implicitly_declare_fn): Pass unqualified type to
* method.c (implicitly_declare_fn): Pass unqualified type to
synthesize_exception_spec.
2002-04-03 Jason Merrill <jason@redhat.com>
@ -576,7 +627,7 @@
PR c++/4884
* call.c (build_op_delete_call): Allow for the fact the placement
may be a COMPOUND_EXPR.
2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
PR c++/5682
@ -630,7 +681,7 @@
2002-03-18 Ashif Harji <asharji@uwaterloo.ca>
* lang-specs.h (compiler default_compilers): Add
* lang-specs.h (compiler default_compilers): Add
-no-integrated-cpp flag to invoke an external cpp.
2002-03-18 Jason Merrill <jason@redhat.com>
@ -747,7 +798,7 @@
with pointer to member conversions.
2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org>
* cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of
conditional return void.
@ -781,7 +832,7 @@
* decl.c (finish_function): Only warn about missing return
statement with -Wreturn-type.
2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
PR c++/4093
* cp-tree.h (SET_BINFO_MARKED): Cast false part of condition
@ -835,7 +886,7 @@
2002-02-19 Jason Merrill <jason@redhat.com>
ABI change: Mangle `void (A::*)() const' as
ABI change: Mangle `void (A::*)() const' as
M1AKFvvE, not MK1AFvvE.
* mangle.c (write_function_type): Write cv-quals for member
function type here.
@ -910,14 +961,14 @@
(coerce_template_template_parms, convert_template_argument,
coerce_template_parms, maybe_get_template_decl_from_type_decl,
lookup_template_class, tsubst_friend_function, tsubst_friend_class,
instantiate_class_template, tsubst_template_arg_vector,
tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
instantiate_class_template, tsubst_template_arg_vector,
tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
tsubst_decl, tsubst_arg_types, tsubst_function_type,
tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
instantiate_template, fn_type_unification,
resolve_overloaded_unification, verify_class_unification,
unify, get_bindings_real, do_type_instantiation,
regenerate_decl_from_template, instantiate_decl,
resolve_overloaded_unification, verify_class_unification,
unify, get_bindings_real, do_type_instantiation,
regenerate_decl_from_template, instantiate_decl,
tsubst_initializer_list, tsubst_enum,
get_mostly_instantiated_function_type,
invalid_nontype_parm_type_p): Likewise.
@ -978,7 +1029,7 @@
2002-02-01 Jason Merrill <jason@redhat.com>
PR c++/4872
* decl.c (finish_function): Warn about a non-void function with
* decl.c (finish_function): Warn about a non-void function with
no return statement and no abnormal exit.
* cp-tree.h (struct cp_language_function): Add returns_abnormally.
(current_function_returns_abnormally): New macro.

View File

@ -2557,32 +2557,6 @@ extern int flag_new_for_scope;
member function. [expr.unary.op]/3 */
#define PTRMEM_OK_P(NODE) TREE_LANG_FLAG_0 (NODE)
/* A pointer-to-function member type looks like:
struct {
__P __pfn;
ptrdiff_t __delta;
};
If __pfn is NULL, it is a NULL pointer-to-member-function.
(Because the vtable is always the first thing in the object, we
don't need its offset.) If the function is virtual, then PFN is
one plus twice the index into the vtable; otherwise, it is just a
pointer to the function.
Unfortunately, using the lowest bit of PFN doesn't work in
architectures that don't impose alignment requirements on function
addresses, or that use the lowest bit to tell one ISA from another,
for example. For such architectures, we use the lowest bit of
DELTA instead of the lowest bit of the PFN, and DELTA will be
multiplied by 2. */
enum ptrmemfunc_vbit_where_t
{
ptrmemfunc_vbit_in_pfn,
ptrmemfunc_vbit_in_delta
};
/* Get the POINTER_TYPE to the METHOD_TYPE associated with this
pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true,
before using this macro. */

View File

@ -1975,26 +1975,31 @@ finish_anon_union (anon_union_decl)
return;
}
main_decl = build_anon_union_vars (anon_union_decl,
&DECL_ANON_UNION_ELEMS (anon_union_decl),
static_p, external_p);
if (main_decl == NULL_TREE)
if (!processing_template_decl)
{
warning ("anonymous aggregate with no members");
return;
main_decl
= build_anon_union_vars (anon_union_decl,
&DECL_ANON_UNION_ELEMS (anon_union_decl),
static_p, external_p);
if (main_decl == NULL_TREE)
{
warning ("anonymous aggregate with no members");
return;
}
if (static_p)
{
make_decl_rtl (main_decl, 0);
COPY_DECL_RTL (main_decl, anon_union_decl);
expand_anon_union_decl (anon_union_decl,
NULL_TREE,
DECL_ANON_UNION_ELEMS (anon_union_decl));
return;
}
}
if (static_p)
{
make_decl_rtl (main_decl, 0);
COPY_DECL_RTL (main_decl, anon_union_decl);
expand_anon_union_decl (anon_union_decl,
NULL_TREE,
DECL_ANON_UNION_ELEMS (anon_union_decl));
}
else
add_decl_stmt (anon_union_decl);
add_decl_stmt (anon_union_decl);
}
/* Finish processing a builtin type TYPE. It's name is NAME,

View File

@ -1094,7 +1094,10 @@ expand_member_init (exp, name, init)
}
else
{
field = lookup_field (type, name, 1, 0);
if (TREE_CODE (name) == IDENTIFIER_NODE)
field = lookup_field (type, name, 1, 0);
else
field = name;
if (! member_init_ok_or_else (field, type, name))
return NULL_TREE;

View File

@ -6079,6 +6079,8 @@ tsubst_decl (t, args, type, complain)
}
r = copy_decl (t);
if (TREE_CODE (r) == VAR_DECL)
type = complete_type (type);
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (cp_type_quals (type), r);
DECL_CONTEXT (r) = ctx;
@ -6115,6 +6117,8 @@ tsubst_decl (t, args, type, complain)
TREE_CHAIN (r) = NULL_TREE;
if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
cp_error_at ("instantiation of `%D' as type `%T'", r, type);
/* Compute the size, alignment, etc. of R. */
layout_decl (r, 0);
}
break;
@ -7374,9 +7378,6 @@ tsubst_expr (t, args, complain, in_decl)
decl = tsubst (decl, args, complain, in_decl);
if (decl != error_mark_node)
{
if (TREE_CODE (decl) != TYPE_DECL)
/* Make sure the type is instantiated now. */
complete_type (TREE_TYPE (decl));
if (init)
DECL_INITIAL (decl) = error_mark_node;
/* By marking the declaration as instantiated, we avoid
@ -7386,19 +7387,26 @@ tsubst_expr (t, args, complain, in_decl)
do. */
if (TREE_CODE (decl) == VAR_DECL)
DECL_TEMPLATE_INSTANTIATED (decl) = 1;
maybe_push_decl (decl);
if (DECL_PRETTY_FUNCTION_P (decl))
if (TREE_CODE (decl) == VAR_DECL
&& ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
/* Anonymous aggregates are a special case. */
finish_anon_union (decl);
else
{
/* For __PRETTY_FUNCTION__ we have to adjust the
initializer. */
const char *const name
= (*decl_printable_name) (current_function_decl, 2);
init = cp_fname_init (name);
TREE_TYPE (decl) = TREE_TYPE (init);
maybe_push_decl (decl);
if (DECL_PRETTY_FUNCTION_P (decl))
{
/* For __PRETTY_FUNCTION__ we have to adjust the
initializer. */
const char *const name
= (*decl_printable_name) (current_function_decl, 2);
init = cp_fname_init (name);
TREE_TYPE (decl) = TREE_TYPE (init);
}
else
init = tsubst_expr (init, args, complain, in_decl);
cp_finish_decl (decl, init, NULL_TREE, 0);
}
else
init = tsubst_expr (init, args, complain, in_decl);
cp_finish_decl (decl, init, NULL_TREE, 0);
}
}
@ -10274,8 +10282,10 @@ tsubst_initializer_list (t, argvec)
else
init = convert_from_reference (init);
*p = build_tree_list (decl, init);
p = &TREE_CHAIN (*p);
*p = expand_member_init (current_class_ref, decl,
init ? init : void_type_node);
if (*p)
p = &TREE_CHAIN (*p);
}
return first;
}

View File

@ -1224,6 +1224,9 @@ destringize_and_run (pfile, in)
{
const unsigned char *src, *limit;
char *dest, *result;
cpp_context saved_context;
cpp_context *saved_cur_context;
unsigned int saved_line;
dest = result = alloca (in->len + 1);
for (src = in->text, limit = src + in->len; src < limit;)
@ -1235,7 +1238,40 @@ destringize_and_run (pfile, in)
}
*dest = '\0';
/* FIXME. All this saving is a horrible kludge to handle the case
when we're in a macro expansion.
A better strategy it to not convert _Pragma to #pragma if doing
preprocessed output, but to just pass it through as-is, unless it
is a CPP pragma in which case is should be processed normally.
When compiling the preprocessed output the _Pragma should be
handled. This will be become necessary when we move to
line-at-a-time lexing since we will be macro-expanding the line
before outputting / compiling it. */
saved_line = pfile->line;
saved_context = pfile->base_context;
saved_cur_context = pfile->context;
pfile->context = &pfile->base_context;
run_directive (pfile, T_PRAGMA, result, dest - result);
pfile->context = saved_cur_context;
pfile->base_context = saved_context;
pfile->line = saved_line;
/* See above comment. For the moment, we'd like
token1 _Pragma ("foo") token2
to be output as
token1
# 7 "file.c"
#pragma foo
# 7 "file.c"
token2
Getting the line markers is a little tricky. */
if (pfile->cb.line_change)
(*pfile->cb.line_change) (pfile, pfile->cur_token, false);
}
/* Handle the _Pragma operator. */
@ -1245,25 +1281,10 @@ _cpp_do__Pragma (pfile)
{
const cpp_token *string = get__Pragma_string (pfile);
if (!string)
cpp_error (pfile, "_Pragma takes a parenthesized string literal");
if (string)
destringize_and_run (pfile, &string->val.str);
else
{
/* Ideally, we'd like
token1 _Pragma ("foo") token2
to be output as
token1
# 7 "file.c"
#pragma foo
# 7 "file.c"
token2
Getting these correct line markers is a little tricky. */
unsigned int orig_line = pfile->line;
destringize_and_run (pfile, &string->val.str);
pfile->line = orig_line;
pfile->buffer->saved_flags = BOL;
}
cpp_error (pfile, "_Pragma takes a parenthesized string literal");
}
/* Just ignore #sccs, on systems where we define it at all. */

View File

@ -348,6 +348,12 @@ stringify_arg (pfile, arg)
}
/* Commit the memory, including NUL, and return the token. */
if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < 1)
{
size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
_cpp_extend_buff (pfile, &pfile->u_buff, 1);
dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
}
len = dest - BUFF_FRONT (pfile->u_buff);
BUFF_FRONT (pfile->u_buff) = dest + 1;
return new_string_token (pfile, dest - len, len);

View File

@ -830,11 +830,22 @@ version of GCC in use.
You can add to this list with the @option{-I@var{dir}} command line
option. All the directories named by @option{-I} are searched, in
left-to-right order, @emph{before} the default directories. You can
also prevent GCC from searching any of the default directories with the
@option{-nostdinc} option. This is useful when you are compiling an
left-to-right order, @emph{before} the default directories. The only
exception is when @file{dir} is already searched by default. In
this case, the option is ignored and the search order for system
directories remains unchanged.
Duplicate directories are removed from the quote and bracket search
chains before the two chains are merged to make the final search chain.
Thus, it is possible for a directory to occur twice in the final search
chain if it was specified in both the quote and bracket chains.
You can prevent GCC from searching any of the default directories with
the @option{-nostdinc} option. This is useful when you are compiling an
operating system kernel or some other program that does not use the
standard C library facilities, or the standard C library itself.
@option{-I} options are not ignored as described above when
@option{-nostdinc} is in effect.
GCC looks for headers requested with @code{@w{#include "@var{file}"}}
first in the directory containing the current file, then in the same
@ -843,12 +854,6 @@ For example, if @file{/usr/include/sys/stat.h} contains
@code{@w{#include "types.h"}}, GCC looks for @file{types.h} first in
@file{/usr/include/sys}, then in its usual search path.
If you name a search directory with @option{-I@var{dir}} that is also a
system include directory, the @option{-I} wins; the directory will be
searched according to the @option{-I} ordering, and it will not be
treated as a system include directory. GCC will warn you when a system
include directory is hidden in this way.
@samp{#line} (@pxref{Line Control}) does not change GCC's idea of the
directory containing the current file.
@ -1081,8 +1086,8 @@ found in that directory will be considered system headers.
All directories named by @option{-isystem} are searched @emph{after} all
directories named by @option{-I}, no matter what their order was on the
command line. If the same directory is named by both @option{-I} and
@option{-isystem}, @option{-I} wins; it is as if the @option{-isystem} option
had never been specified at all. GCC warns you when this happens.
@option{-isystem}, the @option{-I} option is ignored. GCC provides an
informative message when this occurs if @option{-v} is used.
@findex #pragma GCC system_header
There is also a directive, @code{@w{#pragma GCC system_header}}, which
@ -1815,9 +1820,7 @@ conformance to the C Standard. GNU CPP follows the host convention when
processing system header files, but when processing user files
@code{__STDC__} is always 1. This has been reported to cause problems;
for instance, some versions of Solaris provide X Windows headers that
expect @code{__STDC__} to be either undefined or 1. You may be able to
work around this sort of problem by using an @option{-I} option to
cancel treatment of those headers as system headers. @xref{Invocation}.
expect @code{__STDC__} to be either undefined or 1. @xref{Invocation}.
@item __STDC_VERSION__
This macro expands to the C Standard's version number, a long integer
@ -3733,9 +3736,9 @@ Here are a few more obsolete features.
@item Attempting to paste two tokens which together do not form a valid
preprocessing token.
The preprocessor currently warns about this and outputs the two tokens
adjacently, which is probably the behavior the programmer intends. It
may not work in future, though.
The preprocessor currently warns about this, and the resulting
preprocessed output is undefined. The tokens remain distinct if the
preprocessor is being used directly by the compiler front end.
Most of the time, when you get this warning, you will find that @samp{##}
is being used superstitiously, to guard against whitespace appearing

View File

@ -385,7 +385,6 @@ extensions, accepted by GCC in C89 mode and in C++.
* Labels as Values:: Getting pointers to labels, and computed gotos.
* Nested Functions:: As in Algol and Pascal, lexical scoping of functions.
* Constructing Calls:: Dispatching a call to another function.
* Naming Types:: Giving a name to the type of some expression.
* Typeof:: @code{typeof}: referring to the type of an expression.
* Lvalues:: Using @samp{?:}, @samp{,} and casts in lvalues.
* Conditionals:: Omitting the middle operand of a @samp{?:} expression.
@ -495,8 +494,7 @@ the value of an enumeration constant, the width of a bit-field, or
the initial value of a static variable.
If you don't know the type of the operand, you can still do this, but you
must use @code{typeof} (@pxref{Typeof}) or type naming (@pxref{Naming
Types}).
must use @code{typeof} (@pxref{Typeof}).
Statement expressions are not supported fully in G++, and their fate
there is unclear. (It is possible that they will become fully supported
@ -845,29 +843,6 @@ the containing function. You should specify, for @var{result}, a value
returned by @code{__builtin_apply}.
@end deftypefn
@node Naming Types
@section Naming an Expression's Type
@cindex naming types
You can give a name to the type of an expression using a @code{typedef}
declaration with an initializer. Here is how to define @var{name} as a
type name for the type of @var{exp}:
@example
typedef @var{name} = @var{exp};
@end example
This is useful in conjunction with the statements-within-expressions
feature. Here is how the two together can be used to define a safe
``maximum'' macro that operates on any arithmetic type:
@example
#define max(a,b) \
(@{typedef _ta = (a), _tb = (b); \
_ta _a = (a); _tb _b = (b); \
_a > _b ? _a : _b; @})
@end example
@cindex underscores in variables in macros
@cindex @samp{_} in variables in macros
@cindex local variables in macros
@ -919,6 +894,21 @@ A @code{typeof}-construct can be used anywhere a typedef name could be
used. For example, you can use it in a declaration, in a cast, or inside
of @code{sizeof} or @code{typeof}.
@code{typeof} is often useful in conjunction with the
statements-within-expressions feature. Here is how the two together can
be used to define a safe ``maximum'' macro that operates on any
arithmetic type and evaluates each of its arguments exactly once:
@example
#define max(a,b) \
(@{ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; @})
@end example
@noindent
Some more examples of the use of @code{typeof}:
@itemize @bullet
@item
This declares @code{y} with the type of what @code{x} points to.
@ -968,6 +958,26 @@ Thus, @code{array (pointer (char), 4)} is the type of arrays of 4
pointers to @code{char}.
@end itemize
@emph{Compatibility Note:} In addition to @code{typeof}, GCC 2 supported
a more limited extension which permitted one to write
@example
typedef @var{T} = @var{expr};
@end example
@noindent
with the effect of declaring @var{T} to have the type of the expression
@var{expr}. This extension does not work with GCC 3 (versions between
3.0 and 3.2 will crash; 3.2.1 and later give an error). Code which
relies on it should be rewritten to use @code{typeof}:
@example
typedef typeof(@var{expr}) @var{T};
@end example
@noindent
This will work with all versions of GCC@.
@node Lvalues
@section Generalized Lvalues
@cindex compound expressions as lvalues
@ -6170,12 +6180,12 @@ the minimum value of variables @var{i} and @var{j}.
However, side effects in @code{X} or @code{Y} may cause unintended
behavior. For example, @code{MIN (i++, j++)} will fail, incrementing
the smaller counter twice. A GNU C extension allows you to write safe
macros that avoid this kind of problem (@pxref{Naming Types,,Naming an
Expression's Type}). However, writing @code{MIN} and @code{MAX} as
macros also forces you to use function-call notation for a
fundamental arithmetic operation. Using GNU C++ extensions, you can
write @w{@samp{int min = i <? j;}} instead.
the smaller counter twice. The GNU C @code{typeof} extension allows you
to write safe macros that avoid this kind of problem (@pxref{Typeof}).
However, writing @code{MIN} and @code{MAX} as macros also forces you to
use function-call notation for a fundamental arithmetic operation.
Using GNU C++ extensions, you can write @w{@samp{int min = i <? j;}}
instead.
Since @code{<?} and @code{>?} are built into the compiler, they properly
handle expressions with side-effects; @w{@samp{int min = i++ <? j++;}}

View File

@ -222,7 +222,7 @@ in the following sections.
-Werror-implicit-function-declaration @gol
-Wimport -Winline @gol
-Wlarger-than-@var{len} -Wlong-long @gol
-Wmain -Wmissing-braces -Wmissing-declarations @gol
-Wmain -Wmissing-braces @gol
-Wmissing-format-attribute -Wmissing-noreturn @gol
-Wmultichar -Wno-format-extra-args -Wno-format-y2k @gol
-Wno-import -Wpacked -Wpadded @gol
@ -236,8 +236,8 @@ in the following sections.
@item C-only Warning Options
@gccoptlist{
-Wbad-function-cast -Wmissing-prototypes -Wnested-externs @gol
-Wstrict-prototypes -Wtraditional}
-Wbad-function-cast -Wmissing-declarations -Wmissing-prototypes @gol
-Wnested-externs -Wstrict-prototypes -Wtraditional}
@item Debugging Options
@xref{Debugging Options,,Options for Debugging Your Program or GCC}.
@ -4246,15 +4246,13 @@ one @option{-I} option, the directories are scanned in left-to-right
order; the standard system directories come after.
If a standard system include directory, or a directory specified with
@option{-isystem}, is also specified with @option{-I}, it will be
searched only in the position requested by @option{-I}. Also, it will
not be considered a system include directory. If that directory really
does contain system headers, there is a good chance that they will
break. For instance, if GCC's installation procedure edited the headers
in @file{/usr/include} to fix bugs, @samp{-I/usr/include} will cause the
original, buggy headers to be found instead of the corrected ones. GCC
will issue a warning when a system include directory is hidden in this
way.
@option{-isystem}, is also specified with @option{-I}, the @option{-I}
option will be ignored. The directory will still be searched but as a
system directory at its normal position in the system include chain.
This is to ensure that GCC's procedure to fix buggy system headers and
the ordering for the include_next directive are not inadvertantly changed.
If you really need to change the search order for system directories,
use the @option{-nostdinc} and/or @option{-isystem} options.
@item -I-
@opindex I-

View File

@ -552,6 +552,7 @@ doloop_modify_runtime (loop, iterations_max,
{
const struct loop_info *loop_info = LOOP_INFO (loop);
HOST_WIDE_INT abs_inc;
HOST_WIDE_INT abs_loop_inc;
int neg_inc;
rtx diff;
rtx sequence;
@ -591,13 +592,22 @@ doloop_modify_runtime (loop, iterations_max,
n = abs (final - initial) / abs_inc;
n += (abs (final - initial) % abs_inc) != 0;
If the loop has been unrolled, then the loop body has been
preconditioned to iterate a multiple of unroll_number times. If
abs_inc is != 1, the full calculation is
But when abs_inc is a power of two, the summation won't overflow
except in cases where the loop never terminates. So we don't
need to use this more costly calculation.
t1 = abs_inc * unroll_number;
n = abs (final - initial) / t1;
n += (abs (final - initial) % t1) > t1 - abs_inc;
If the loop has been unrolled, the full calculation is
t1 = abs_inc * unroll_number; increment per loop
n = abs (final - initial) / t1; full loops
n += (abs (final - initial) % t1) != 0; partial loop
However, in certain cases the unrolled loop will be preconditioned
by emitting copies of the loop body with conditional branches,
so that the unrolled loop is always a full loop and thus needs
no exit tests. In this case we don't want to add the partial
loop count. As above, when t1 is a power of two we don't need to
worry about overflow.
The division and modulo operations can be avoided by requiring
that the increment is a power of 2 (precondition_loop_p enforces
@ -658,58 +668,32 @@ doloop_modify_runtime (loop, iterations_max,
fprintf (loop_dump_stream,
"Doloop: Basic induction var skips initial incr.\n");
diff = expand_simple_binop (mode, PLUS, diff, increment, diff,
unsigned_p, OPTAB_LIB_WIDEN);
diff = expand_simple_binop (mode, PLUS, diff, GEN_INT (abs_inc),
diff, unsigned_p, OPTAB_LIB_WIDEN);
}
}
if (abs_inc * loop_info->unroll_number != 1)
abs_loop_inc = abs_inc * loop_info->unroll_number;
if (abs_loop_inc != 1)
{
int shift_count;
rtx extra;
rtx label;
unsigned HOST_WIDE_INT limit;
shift_count = exact_log2 (abs_inc * loop_info->unroll_number);
shift_count = exact_log2 (abs_loop_inc);
if (shift_count < 0)
abort ();
/* abs (final - initial) / (abs_inc * unroll_number) */
iterations = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
diff, GEN_INT (shift_count),
NULL_RTX, 1,
OPTAB_LIB_WIDEN);
if (!loop_info->preconditioned)
diff = expand_simple_binop (GET_MODE (diff), PLUS,
diff, GEN_INT (abs_loop_inc - 1),
diff, 1, OPTAB_LIB_WIDEN);
if (abs_inc != 1)
{
/* abs (final - initial) % (abs_inc * unroll_number) */
rtx count = GEN_INT (abs_inc * loop_info->unroll_number - 1);
extra = expand_simple_binop (GET_MODE (iterations), AND,
diff, count, NULL_RTX, 1,
OPTAB_LIB_WIDEN);
/* If (abs (final - initial) % (abs_inc * unroll_number)
<= abs_inc * (unroll - 1)),
jump past following increment instruction. */
label = gen_label_rtx ();
limit = abs_inc * (loop_info->unroll_number - 1);
emit_cmp_and_jump_insns (extra, GEN_INT (limit),
limit == 0 ? EQ : LEU, NULL_RTX,
GET_MODE (extra), 0, label);
JUMP_LABEL (get_last_insn ()) = label;
LABEL_NUSES (label)++;
/* Increment the iteration count by one. */
iterations = expand_simple_binop (GET_MODE (iterations), PLUS,
iterations, GEN_INT (1),
iterations, 1,
OPTAB_LIB_WIDEN);
emit_label (label);
}
/* (abs (final - initial) + abs_inc * unroll_number - 1)
/ (abs_inc * unroll_number) */
diff = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
diff, GEN_INT (shift_count),
diff, 1, OPTAB_LIB_WIDEN);
}
else
iterations = diff;
iterations = diff;
/* If there is a NOTE_INSN_LOOP_VTOP, we have a `for' or `while'
style loop, with a loop exit test at the start. Thus, we can
@ -722,17 +706,20 @@ doloop_modify_runtime (loop, iterations_max,
iteration count to one if necessary. */
if (! loop->vtop)
{
rtx label;
if (loop_dump_stream)
fprintf (loop_dump_stream, "Doloop: Do-while loop.\n");
/* A `do-while' loop must iterate at least once. If the
iteration count is bogus, we set the iteration count to 1.
/* A `do-while' loop must iterate at least once. For code like
i = initial; do { ... } while (++i < final);
we will calculate a bogus iteration count if initial > final.
So detect this and set the iteration count to 1.
Note that if the loop has been unrolled, then the loop body
is guaranteed to execute at least once. */
if (loop_info->unroll_number == 1)
is guaranteed to execute at least once. Also, when the
comparison is NE, our calculated count will be OK. */
if (loop_info->unroll_number == 1 && comparison_code != NE)
{
rtx label;
/* Emit insns to test if the loop will immediately
terminate and to set the iteration count to 1 if true. */
label = gen_label_rtx();

View File

@ -5434,16 +5434,13 @@ rtx
force_operand (value, target)
rtx value, target;
{
optab binoptab = 0;
/* Use a temporary to force order of execution of calls to
`force_operand'. */
rtx tmp;
rtx op2;
rtx op1, op2;
/* Use subtarget as the target for operand 0 of a binary operation. */
rtx subtarget = get_subtarget (target);
enum rtx_code code = GET_CODE (value);
/* Check for a PIC address load. */
if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
if ((code == PLUS || code == MINUS)
&& XEXP (value, 0) == pic_offset_table_rtx
&& (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
|| GET_CODE (XEXP (value, 1)) == LABEL_REF
@ -5455,60 +5452,88 @@ force_operand (value, target)
return subtarget;
}
if (GET_CODE (value) == PLUS)
binoptab = add_optab;
else if (GET_CODE (value) == MINUS)
binoptab = sub_optab;
else if (GET_CODE (value) == MULT)
if (code == ZERO_EXTEND || code == SIGN_EXTEND)
{
op2 = XEXP (value, 1);
if (!CONSTANT_P (op2)
&& !(GET_CODE (op2) == REG && op2 != subtarget))
subtarget = 0;
tmp = force_operand (XEXP (value, 0), subtarget);
return expand_mult (GET_MODE (value), tmp,
force_operand (op2, NULL_RTX),
target, 1);
if (!target)
target = gen_reg_rtx (GET_MODE (value));
convert_move (target, force_operand (XEXP (value, 0), NULL),
code == ZERO_EXTEND);
return target;
}
if (binoptab)
if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c')
{
op2 = XEXP (value, 1);
if (!CONSTANT_P (op2)
&& !(GET_CODE (op2) == REG && op2 != subtarget))
if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget))
subtarget = 0;
if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT)
if (code == MINUS && GET_CODE (op2) == CONST_INT)
{
binoptab = add_optab;
code = PLUS;
op2 = negate_rtx (GET_MODE (value), op2);
}
/* Check for an addition with OP2 a constant integer and our first
operand a PLUS of a virtual register and something else. In that
case, we want to emit the sum of the virtual register and the
constant first and then add the other value. This allows virtual
register instantiation to simply modify the constant rather than
creating another one around this addition. */
if (binoptab == add_optab && GET_CODE (op2) == CONST_INT
operand a PLUS of a virtual register and something else. In that
case, we want to emit the sum of the virtual register and the
constant first and then add the other value. This allows virtual
register instantiation to simply modify the constant rather than
creating another one around this addition. */
if (code == PLUS && GET_CODE (op2) == CONST_INT
&& GET_CODE (XEXP (value, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
&& REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
&& REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
{
rtx temp = expand_binop (GET_MODE (value), binoptab,
XEXP (XEXP (value, 0), 0), op2,
subtarget, 0, OPTAB_LIB_WIDEN);
return expand_binop (GET_MODE (value), binoptab, temp,
force_operand (XEXP (XEXP (value, 0), 1), 0),
target, 0, OPTAB_LIB_WIDEN);
rtx temp = expand_simple_binop (GET_MODE (value), code,
XEXP (XEXP (value, 0), 0), op2,
subtarget, 0, OPTAB_LIB_WIDEN);
return expand_simple_binop (GET_MODE (value), code, temp,
force_operand (XEXP (XEXP (value,
0), 1), 0),
target, 0, OPTAB_LIB_WIDEN);
}
tmp = force_operand (XEXP (value, 0), subtarget);
return expand_binop (GET_MODE (value), binoptab, tmp,
force_operand (op2, NULL_RTX),
target, 0, OPTAB_LIB_WIDEN);
/* We give UNSIGNEDP = 0 to expand_binop
because the only operations we are expanding here are signed ones. */
op1 = force_operand (XEXP (value, 0), subtarget);
op2 = force_operand (op2, NULL_RTX);
switch (code)
{
case MULT:
return expand_mult (GET_MODE (value), op1, op2, target, 1);
case DIV:
if (!INTEGRAL_MODE_P (GET_MODE (value)))
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 1, OPTAB_LIB_WIDEN);
else
return expand_divmod (0,
FLOAT_MODE_P (GET_MODE (value))
? RDIV_EXPR : TRUNC_DIV_EXPR,
GET_MODE (value), op1, op2, target, 0);
break;
case MOD:
return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
target, 0);
break;
case UDIV:
return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
target, 1);
break;
case UMOD:
return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
target, 1);
break;
case ASHIFTRT:
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 0, OPTAB_LIB_WIDEN);
break;
default:
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 1, OPTAB_LIB_WIDEN);
}
}
if (GET_RTX_CLASS (code) == '1')
{
op1 = force_operand (XEXP (value, 0), NULL_RTX);
return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
}
#ifdef INSN_SCHEDULING
@ -7563,16 +7588,23 @@ expand_expr (exp, target, tmode, modifier)
}
}
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
subtarget = 0;
/* No sense saving up arithmetic to be done
if it's all in the wrong mode to form part of an address.
And force_operand won't know whether to sign-extend or
zero-extend. */
if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
|| mode != ptr_mode)
goto binop;
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
subtarget = 0;
{
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
temp = simplify_binary_operation (PLUS, mode, op0, op1);
if (temp)
return temp;
goto binop2;
}
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);

View File

@ -1,4 +1,4 @@
#include "ansidecl.h"
#include "f/version.h"
const char *const ffe_version_string = "3.2.1 20020916 (prerelease)";
const char *const ffe_version_string = "3.2.1 20021009 (prerelease)";

View File

@ -63,6 +63,14 @@
# for the rule to exclude a set. Options can be preceded with a '!' to
# match a logical NOT.
# The optional sevenths argument is a list of OS subdirectory names.
# The format is the same as of the second argument.
# The difference is that second argument describes multilib directories
# in GCC conventions, while this one the OS multilib convention.
# The last option should be "yes" if multilibs are enabled. If it is not
# "yes", all GCC multilib dir names will be ".".
# The output looks like
# #define MULTILIB_MATCHES "\
# SUBDIRECTORY OPTIONS;\
@ -79,17 +87,18 @@
# Here is an example (this is from the actual sparc64 case):
# genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
# 'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
# 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
# '' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
# '../lib64 ../lib32 alt' yes
# This produces:
# ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
# "64 m64 !m32 !mno-app-regs !mcmodel=medany;",
# "32 !m64 m32 !mno-app-regs !mcmodel=medany;",
# "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
# "32:../lib32 !m64 m32 !mno-app-regs !mcmodel=medany;",
# "alt !m64 !m32 mno-app-regs mcmodel=medany;",
# "alt !m64 !m32 mno-app-regs !mcmodel=medany;",
# "alt !m64 !m32 !mno-app-regs mcmodel=medany;",
# "64/alt m64 !m32 mno-app-regs mcmodel=medany;",
# "64/alt m64 !m32 mno-app-regs !mcmodel=medany;",
# "64/alt m64 !m32 !mno-app-regs mcmodel=medany;",
# "64/alt:../lib64/alt m64 !m32 mno-app-regs mcmodel=medany;",
# "64/alt:../lib64/alt m64 !m32 mno-app-regs !mcmodel=medany;",
# "64/alt:../lib64/alt m64 !m32 !mno-app-regs mcmodel=medany;",
#
# The effect is that `gcc -mno-app-regs' (for example) will append "alt"
# to the directory name when searching for libraries or startup files and
@ -106,6 +115,8 @@ matches=$3
exceptions=$4
extra=$5
exclusions=$6
osdirnames=$7
enable_multilib=$8
echo "static const char *const multilib_raw[] = {"
@ -202,6 +213,29 @@ if [ -n "${dirnames}" ]; then
done
fi
# Construct a sed pattern which will convert option names to OS directory
# names.
toosdirnames=
if [ -n "${osdirnames}" ]; then
set x ${osdirnames}
shift
for set in ${options}; do
for opts in `echo ${set} | sed -e 's|/| |'g`; do
patt="/"
for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
if [ "$1" != "${opt}" ]; then
toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g"
patt="${patt}${1}/"
if [ "${patt}" != "/${1}/" ]; then
toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g"
fi
fi
done
shift
done
done
fi
# We need another recursive shell script to correctly handle positive
# matches. If we are invoked as
# genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
@ -257,6 +291,25 @@ for combo in ${combinations}; do
# Remove the leading and trailing slashes.
dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
# Use the OS directory names rather than the option names.
if [ -n "${toosdirnames}" ]; then
osdirout=`echo ${combo} | sed ${toosdirnames}`
# Remove the leading and trailing slashes.
osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
if [ "x${enable_multilib}" != xyes ]; then
dirout=".:${osdirout}"
else
dirout="${dirout}:${osdirout}"
fi
else
if [ "x${enable_multilib}" != xyes ]; then
# genmultilib with --disable-multilib should be
# called with '' '' '' '' '' '' '' no
# if MULTILIB_OSDIRNAMES is empty.
exit 1
fi
fi
# Look through the options. We must output each option that is
# present, and negate each option that is not present.
optout=
@ -313,6 +366,11 @@ done
echo "NULL"
echo "};"
# Output the options now
moptions=`echo ${options} | sed -e 's,[ ][ ]*, ,g'`
echo ""
echo "static const char *multilib_options = \"${moptions}\";"
rm -f tmpmultilib2
exit 0

View File

@ -2428,3 +2428,15 @@ true_regnum (x)
}
return -1;
}
/* Return regno of the register REG and handle subregs too. */
unsigned int
reg_or_subregno (reg)
rtx reg;
{
if (REG_P (reg))
return REGNO (reg);
if (GET_CODE (reg) == SUBREG)
return REGNO (SUBREG_REG (reg));
abort ();
}

View File

@ -640,6 +640,7 @@ scan_loop (loop, flags)
int threshold;
/* Nonzero if we are scanning instructions in a sub-loop. */
int loop_depth = 0;
int in_libcall;
loop->top = 0;
@ -756,290 +757,311 @@ scan_loop (loop, flags)
When MAYBE_NEVER is 0, all insns will be executed at least once
so that is not a problem. */
for (p = next_insn_in_loop (loop, loop->scan_start);
for (in_libcall = 0, p = next_insn_in_loop (loop, loop->scan_start);
p != NULL_RTX;
p = next_insn_in_loop (loop, p))
{
if (GET_CODE (p) == INSN
&& (set = single_set (p))
&& GET_CODE (SET_DEST (set)) == REG
#ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
&& SET_DEST (set) != pic_offset_table_rtx
#endif
&& ! regs->array[REGNO (SET_DEST (set))].may_not_optimize)
if (in_libcall && INSN_P (p) && find_reg_note (p, REG_RETVAL, NULL_RTX))
in_libcall--;
if (GET_CODE (p) == INSN)
{
int tem1 = 0;
int tem2 = 0;
int move_insn = 0;
rtx src = SET_SRC (set);
rtx dependencies = 0;
/* Figure out what to use as a source of this insn. If a REG_EQUIV
note is given or if a REG_EQUAL note with a constant operand is
specified, use it as the source and mark that we should move
this insn by calling emit_move_insn rather that duplicating the
insn.
Otherwise, only use the REG_EQUAL contents if a REG_RETVAL note
is present. */
temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
temp = find_reg_note (p, REG_LIBCALL, NULL_RTX);
if (temp)
src = XEXP (temp, 0), move_insn = 1;
else
in_libcall++;
if (! in_libcall
&& (set = single_set (p))
&& GET_CODE (SET_DEST (set)) == REG
#ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
&& SET_DEST (set) != pic_offset_table_rtx
#endif
&& ! regs->array[REGNO (SET_DEST (set))].may_not_optimize)
{
temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
if (temp && CONSTANT_P (XEXP (temp, 0)))
int tem1 = 0;
int tem2 = 0;
int move_insn = 0;
rtx src = SET_SRC (set);
rtx dependencies = 0;
/* Figure out what to use as a source of this insn. If a
REG_EQUIV note is given or if a REG_EQUAL note with a
constant operand is specified, use it as the source and
mark that we should move this insn by calling
emit_move_insn rather that duplicating the insn.
Otherwise, only use the REG_EQUAL contents if a REG_RETVAL
note is present. */
temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
if (temp)
src = XEXP (temp, 0), move_insn = 1;
if (temp && find_reg_note (p, REG_RETVAL, NULL_RTX))
else
{
src = XEXP (temp, 0);
/* A libcall block can use regs that don't appear in
the equivalent expression. To move the libcall,
we must move those regs too. */
dependencies = libcall_other_reg (p, src);
}
}
/* For parallels, add any possible uses to the depencies, as we can't move
the insn without resolving them first. */
if (GET_CODE (PATTERN (p)) == PARALLEL)
{
for (i = 0; i < XVECLEN (PATTERN (p), 0); i++)
{
rtx x = XVECEXP (PATTERN (p), 0, i);
if (GET_CODE (x) == USE)
dependencies = gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0), dependencies);
}
}
/* Don't try to optimize a register that was made
by loop-optimization for an inner loop.
We don't know its life-span, so we can't compute the benefit. */
if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
;
else if (/* The register is used in basic blocks other
than the one where it is set (meaning that
something after this point in the loop might
depend on its value before the set). */
! reg_in_basic_block_p (p, SET_DEST (set))
/* And the set is not guaranteed to be executed once
the loop starts, or the value before the set is
needed before the set occurs...
??? Note we have quadratic behaviour here, mitigated
by the fact that the previous test will often fail for
large loops. Rather than re-scanning the entire loop
each time for register usage, we should build tables
of the register usage and use them here instead. */
&& (maybe_never
|| loop_reg_used_before_p (loop, set, p)))
/* It is unsafe to move the set.
This code used to consider it OK to move a set of a variable
which was not created by the user and not used in an exit test.
That behavior is incorrect and was removed. */
;
else if ((tem = loop_invariant_p (loop, src))
&& (dependencies == 0
|| (tem2 = loop_invariant_p (loop, dependencies)) != 0)
&& (regs->array[REGNO (SET_DEST (set))].set_in_loop == 1
|| (tem1
= consec_sets_invariant_p
(loop, SET_DEST (set),
regs->array[REGNO (SET_DEST (set))].set_in_loop,
p)))
/* If the insn can cause a trap (such as divide by zero),
can't move it unless it's guaranteed to be executed
once loop is entered. Even a function call might
prevent the trap insn from being reached
(since it might exit!) */
&& ! ((maybe_never || call_passed)
&& may_trap_p (src)))
{
struct movable *m;
int regno = REGNO (SET_DEST (set));
/* A potential lossage is where we have a case where two insns
can be combined as long as they are both in the loop, but
we move one of them outside the loop. For large loops,
this can lose. The most common case of this is the address
of a function being called.
Therefore, if this register is marked as being used exactly
once if we are in a loop with calls (a "large loop"), see if
we can replace the usage of this register with the source
of this SET. If we can, delete this insn.
Don't do this if P has a REG_RETVAL note or if we have
SMALL_REGISTER_CLASSES and SET_SRC is a hard register. */
if (loop_info->has_call
&& regs->array[regno].single_usage != 0
&& regs->array[regno].single_usage != const0_rtx
&& REGNO_FIRST_UID (regno) == INSN_UID (p)
&& (REGNO_LAST_UID (regno)
== INSN_UID (regs->array[regno].single_usage))
&& regs->array[regno].set_in_loop == 1
&& GET_CODE (SET_SRC (set)) != ASM_OPERANDS
&& ! side_effects_p (SET_SRC (set))
&& ! find_reg_note (p, REG_RETVAL, NULL_RTX)
&& (! SMALL_REGISTER_CLASSES
|| (! (GET_CODE (SET_SRC (set)) == REG
&& REGNO (SET_SRC (set)) < FIRST_PSEUDO_REGISTER)))
/* This test is not redundant; SET_SRC (set) might be
a call-clobbered register and the life of REGNO
might span a call. */
&& ! modified_between_p (SET_SRC (set), p,
regs->array[regno].single_usage)
&& no_labels_between_p (p, regs->array[regno].single_usage)
&& validate_replace_rtx (SET_DEST (set), SET_SRC (set),
regs->array[regno].single_usage))
{
/* Replace any usage in a REG_EQUAL note. Must copy the
new source, so that we don't get rtx sharing between the
SET_SOURCE and REG_NOTES of insn p. */
REG_NOTES (regs->array[regno].single_usage)
= replace_rtx (REG_NOTES (regs->array[regno].single_usage),
SET_DEST (set), copy_rtx (SET_SRC (set)));
delete_insn (p);
for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set)); i++)
regs->array[regno+i].set_in_loop = 0;
continue;
}
m = (struct movable *) xmalloc (sizeof (struct movable));
m->next = 0;
m->insn = p;
m->set_src = src;
m->dependencies = dependencies;
m->set_dest = SET_DEST (set);
m->force = 0;
m->consec = regs->array[REGNO (SET_DEST (set))].set_in_loop - 1;
m->done = 0;
m->forces = 0;
m->partial = 0;
m->move_insn = move_insn;
m->move_insn_first = 0;
m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
m->savemode = VOIDmode;
m->regno = regno;
/* Set M->cond if either loop_invariant_p
or consec_sets_invariant_p returned 2
(only conditionally invariant). */
m->cond = ((tem | tem1 | tem2) > 1);
m->global = LOOP_REG_GLOBAL_P (loop, regno);
m->match = 0;
m->lifetime = LOOP_REG_LIFETIME (loop, regno);
m->savings = regs->array[regno].n_times_set;
if (find_reg_note (p, REG_RETVAL, NULL_RTX))
m->savings += libcall_benefit (p);
for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set)); i++)
regs->array[regno+i].set_in_loop = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
if (m->consec > 0)
{
/* It is possible for the first instruction to have a
REG_EQUAL note but a non-invariant SET_SRC, so we must
remember the status of the first instruction in case
the last instruction doesn't have a REG_EQUAL note. */
m->move_insn_first = m->move_insn;
/* Skip this insn, not checking REG_LIBCALL notes. */
p = next_nonnote_insn (p);
/* Skip the consecutive insns, if there are any. */
p = skip_consec_insns (p, m->consec);
/* Back up to the last insn of the consecutive group. */
p = prev_nonnote_insn (p);
/* We must now reset m->move_insn, m->is_equiv, and possibly
m->set_src to correspond to the effects of all the
insns. */
temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
if (temp)
m->set_src = XEXP (temp, 0), m->move_insn = 1;
else
temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
if (temp && CONSTANT_P (XEXP (temp, 0)))
src = XEXP (temp, 0), move_insn = 1;
if (temp && find_reg_note (p, REG_RETVAL, NULL_RTX))
{
temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
if (temp && CONSTANT_P (XEXP (temp, 0)))
m->set_src = XEXP (temp, 0), m->move_insn = 1;
else
m->move_insn = 0;
src = XEXP (temp, 0);
/* A libcall block can use regs that don't appear in
the equivalent expression. To move the libcall,
we must move those regs too. */
dependencies = libcall_other_reg (p, src);
}
m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
}
}
/* If this register is always set within a STRICT_LOW_PART
or set to zero, then its high bytes are constant.
So clear them outside the loop and within the loop
just load the low bytes.
We must check that the machine has an instruction to do so.
Also, if the value loaded into the register
depends on the same register, this cannot be done. */
else if (SET_SRC (set) == const0_rtx
&& GET_CODE (NEXT_INSN (p)) == INSN
&& (set1 = single_set (NEXT_INSN (p)))
&& GET_CODE (set1) == SET
&& (GET_CODE (SET_DEST (set1)) == STRICT_LOW_PART)
&& (GET_CODE (XEXP (SET_DEST (set1), 0)) == SUBREG)
&& (SUBREG_REG (XEXP (SET_DEST (set1), 0))
== SET_DEST (set))
&& !reg_mentioned_p (SET_DEST (set), SET_SRC (set1)))
{
int regno = REGNO (SET_DEST (set));
if (regs->array[regno].set_in_loop == 2)
/* For parallels, add any possible uses to the depencies, as
we can't move the insn without resolving them first. */
if (GET_CODE (PATTERN (p)) == PARALLEL)
{
for (i = 0; i < XVECLEN (PATTERN (p), 0); i++)
{
rtx x = XVECEXP (PATTERN (p), 0, i);
if (GET_CODE (x) == USE)
dependencies
= gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0),
dependencies);
}
}
/* Don't try to optimize a register that was made
by loop-optimization for an inner loop.
We don't know its life-span, so we can't compute
the benefit. */
if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
;
else if (/* The register is used in basic blocks other
than the one where it is set (meaning that
something after this point in the loop might
depend on its value before the set). */
! reg_in_basic_block_p (p, SET_DEST (set))
/* And the set is not guaranteed to be executed once
the loop starts, or the value before the set is
needed before the set occurs...
??? Note we have quadratic behaviour here, mitigated
by the fact that the previous test will often fail for
large loops. Rather than re-scanning the entire loop
each time for register usage, we should build tables
of the register usage and use them here instead. */
&& (maybe_never
|| loop_reg_used_before_p (loop, set, p)))
/* It is unsafe to move the set.
This code used to consider it OK to move a set of a variable
which was not created by the user and not used in an exit
test.
That behavior is incorrect and was removed. */
;
else if ((tem = loop_invariant_p (loop, src))
&& (dependencies == 0
|| (tem2
= loop_invariant_p (loop, dependencies)) != 0)
&& (regs->array[REGNO (SET_DEST (set))].set_in_loop == 1
|| (tem1
= consec_sets_invariant_p
(loop, SET_DEST (set),
regs->array[REGNO (SET_DEST (set))].set_in_loop,
p)))
/* If the insn can cause a trap (such as divide by zero),
can't move it unless it's guaranteed to be executed
once loop is entered. Even a function call might
prevent the trap insn from being reached
(since it might exit!) */
&& ! ((maybe_never || call_passed)
&& may_trap_p (src)))
{
struct movable *m;
int regno = REGNO (SET_DEST (set));
/* A potential lossage is where we have a case where two insns
can be combined as long as they are both in the loop, but
we move one of them outside the loop. For large loops,
this can lose. The most common case of this is the address
of a function being called.
Therefore, if this register is marked as being used
exactly once if we are in a loop with calls
(a "large loop"), see if we can replace the usage of
this register with the source of this SET. If we can,
delete this insn.
Don't do this if P has a REG_RETVAL note or if we have
SMALL_REGISTER_CLASSES and SET_SRC is a hard register. */
if (loop_info->has_call
&& regs->array[regno].single_usage != 0
&& regs->array[regno].single_usage != const0_rtx
&& REGNO_FIRST_UID (regno) == INSN_UID (p)
&& (REGNO_LAST_UID (regno)
== INSN_UID (regs->array[regno].single_usage))
&& regs->array[regno].set_in_loop == 1
&& GET_CODE (SET_SRC (set)) != ASM_OPERANDS
&& ! side_effects_p (SET_SRC (set))
&& ! find_reg_note (p, REG_RETVAL, NULL_RTX)
&& (! SMALL_REGISTER_CLASSES
|| (! (GET_CODE (SET_SRC (set)) == REG
&& (REGNO (SET_SRC (set))
< FIRST_PSEUDO_REGISTER))))
/* This test is not redundant; SET_SRC (set) might be
a call-clobbered register and the life of REGNO
might span a call. */
&& ! modified_between_p (SET_SRC (set), p,
regs->array[regno].single_usage)
&& no_labels_between_p (p,
regs->array[regno].single_usage)
&& validate_replace_rtx (SET_DEST (set), SET_SRC (set),
regs->array[regno].single_usage))
{
/* Replace any usage in a REG_EQUAL note. Must copy
the new source, so that we don't get rtx sharing
between the SET_SOURCE and REG_NOTES of insn p. */
REG_NOTES (regs->array[regno].single_usage)
= (replace_rtx
(REG_NOTES (regs->array[regno].single_usage),
SET_DEST (set), copy_rtx (SET_SRC (set))));
delete_insn (p);
for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set));
i++)
regs->array[regno+i].set_in_loop = 0;
continue;
}
m = (struct movable *) xmalloc (sizeof (struct movable));
m->next = 0;
m->insn = p;
m->set_src = src;
m->dependencies = dependencies;
m->set_dest = SET_DEST (set);
m->dependencies = 0;
m->force = 0;
m->consec = 0;
m->consec
= regs->array[REGNO (SET_DEST (set))].set_in_loop - 1;
m->done = 0;
m->forces = 0;
m->move_insn = 0;
m->partial = 0;
m->move_insn = move_insn;
m->move_insn_first = 0;
m->partial = 1;
/* If the insn may not be executed on some cycles,
we can't clear the whole reg; clear just high part.
Not even if the reg is used only within this loop.
Consider this:
while (1)
while (s != t) {
if (foo ()) x = *s;
use (x);
}
Clearing x before the inner loop could clobber a value
being saved from the last time around the outer loop.
However, if the reg is not used outside this loop
and all uses of the register are in the same
basic block as the store, there is no problem.
If this insn was made by loop, we don't know its
INSN_LUID and hence must make a conservative
assumption. */
m->global = (INSN_UID (p) >= max_uid_for_loop
|| LOOP_REG_GLOBAL_P (loop, regno)
|| (labels_in_range_p
(p, REGNO_FIRST_LUID (regno))));
if (maybe_never && m->global)
m->savemode = GET_MODE (SET_SRC (set1));
else
m->savemode = VOIDmode;
m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
m->savemode = VOIDmode;
m->regno = regno;
m->cond = 0;
/* Set M->cond if either loop_invariant_p
or consec_sets_invariant_p returned 2
(only conditionally invariant). */
m->cond = ((tem | tem1 | tem2) > 1);
m->global = LOOP_REG_GLOBAL_P (loop, regno);
m->match = 0;
m->lifetime = LOOP_REG_LIFETIME (loop, regno);
m->savings = 1;
m->savings = regs->array[regno].n_times_set;
if (find_reg_note (p, REG_RETVAL, NULL_RTX))
m->savings += libcall_benefit (p);
for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set)); i++)
regs->array[regno+i].set_in_loop = -1;
regs->array[regno+i].set_in_loop = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
if (m->consec > 0)
{
/* It is possible for the first instruction to have a
REG_EQUAL note but a non-invariant SET_SRC, so we must
remember the status of the first instruction in case
the last instruction doesn't have a REG_EQUAL note. */
m->move_insn_first = m->move_insn;
/* Skip this insn, not checking REG_LIBCALL notes. */
p = next_nonnote_insn (p);
/* Skip the consecutive insns, if there are any. */
p = skip_consec_insns (p, m->consec);
/* Back up to the last insn of the consecutive group. */
p = prev_nonnote_insn (p);
/* We must now reset m->move_insn, m->is_equiv, and
possibly m->set_src to correspond to the effects of
all the insns. */
temp = find_reg_note (p, REG_EQUIV, NULL_RTX);
if (temp)
m->set_src = XEXP (temp, 0), m->move_insn = 1;
else
{
temp = find_reg_note (p, REG_EQUAL, NULL_RTX);
if (temp && CONSTANT_P (XEXP (temp, 0)))
m->set_src = XEXP (temp, 0), m->move_insn = 1;
else
m->move_insn = 0;
}
m->is_equiv
= (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
}
}
/* If this register is always set within a STRICT_LOW_PART
or set to zero, then its high bytes are constant.
So clear them outside the loop and within the loop
just load the low bytes.
We must check that the machine has an instruction to do so.
Also, if the value loaded into the register
depends on the same register, this cannot be done. */
else if (SET_SRC (set) == const0_rtx
&& GET_CODE (NEXT_INSN (p)) == INSN
&& (set1 = single_set (NEXT_INSN (p)))
&& GET_CODE (set1) == SET
&& (GET_CODE (SET_DEST (set1)) == STRICT_LOW_PART)
&& (GET_CODE (XEXP (SET_DEST (set1), 0)) == SUBREG)
&& (SUBREG_REG (XEXP (SET_DEST (set1), 0))
== SET_DEST (set))
&& !reg_mentioned_p (SET_DEST (set), SET_SRC (set1)))
{
int regno = REGNO (SET_DEST (set));
if (regs->array[regno].set_in_loop == 2)
{
struct movable *m;
m = (struct movable *) xmalloc (sizeof (struct movable));
m->next = 0;
m->insn = p;
m->set_dest = SET_DEST (set);
m->dependencies = 0;
m->force = 0;
m->consec = 0;
m->done = 0;
m->forces = 0;
m->move_insn = 0;
m->move_insn_first = 0;
m->partial = 1;
/* If the insn may not be executed on some cycles,
we can't clear the whole reg; clear just high part.
Not even if the reg is used only within this loop.
Consider this:
while (1)
while (s != t) {
if (foo ()) x = *s;
use (x);
}
Clearing x before the inner loop could clobber a value
being saved from the last time around the outer loop.
However, if the reg is not used outside this loop
and all uses of the register are in the same
basic block as the store, there is no problem.
If this insn was made by loop, we don't know its
INSN_LUID and hence must make a conservative
assumption. */
m->global = (INSN_UID (p) >= max_uid_for_loop
|| LOOP_REG_GLOBAL_P (loop, regno)
|| (labels_in_range_p
(p, REGNO_FIRST_LUID (regno))));
if (maybe_never && m->global)
m->savemode = GET_MODE (SET_SRC (set1));
else
m->savemode = VOIDmode;
m->regno = regno;
m->cond = 0;
m->match = 0;
m->lifetime = LOOP_REG_LIFETIME (loop, regno);
m->savings = 1;
for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set));
i++)
regs->array[regno+i].set_in_loop = -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
}
}
}
}
@ -1911,10 +1933,10 @@ move_movables (loop, movables, threshold, insn_count)
for (count = m->consec; count >= 0; count--)
{
/* If this is the first insn of a library call sequence,
skip to the end. */
something is very wrong. */
if (GET_CODE (p) != NOTE
&& (temp = find_reg_note (p, REG_LIBCALL, NULL_RTX)))
p = XEXP (temp, 0);
abort ();
/* If this is the last insn of a libcall sequence, then
delete every insn in the sequence except the last.
@ -4090,11 +4112,17 @@ emit_prefetch_instructions (loop)
{
rtx reg = gen_reg_rtx (Pmode);
rtx loop_start = loop->start;
rtx init_val = info[i].class->initial_value;
rtx add_val = simplify_gen_binary (PLUS, Pmode,
info[i].giv->add_val,
GEN_INT (y * PREFETCH_BLOCK));
loop_iv_add_mult_emit_before (loop, info[i].class->initial_value,
/* Functions called by LOOP_IV_ADD_EMIT_BEFORE expect a
non-constant INIT_VAL to have the same mode as REG, which
in this case we know to be Pmode. */
if (GET_MODE (init_val) != Pmode && !CONSTANT_P (init_val))
init_val = convert_to_mode (Pmode, init_val, 0);
loop_iv_add_mult_emit_before (loop, init_val,
info[i].giv->mult_val,
add_val, reg, 0, loop_start);
emit_insn_before (gen_prefetch (reg, GEN_INT (info[i].write),

View File

@ -314,6 +314,9 @@ struct loop_info
int has_multiple_exit_targets;
/* Nonzero if there is an indirect jump in the current function. */
int has_indirect_jump;
/* Whether loop unrolling has emitted copies of the loop body so
that the main loop needs no exit tests. */
int preconditioned;
/* Register or constant initial loop value. */
rtx initial_value;
/* Register or constant value used for comparison test. */

View File

@ -32,7 +32,7 @@
# SHLIB_MAPFILES
# SHLIB_NM_FLAGS
# SHLIB_INSTALL
# SHLIB_SLIBDIR_SUFFIXES
# MULTILIB_OSDIRNAMES
# Make needs VPATH to be literal.
echo 'srcdir = @srcdir@'
@ -317,22 +317,18 @@ for ml in $MULTILIBS; do
fi
shlib_so_name="$shlib_base_name"
shlib_dir=
if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then
if [ -n "$MULTILIB_OSDIRNAMES" ]; then
if [ "$dir" != . ]; then
gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory`
os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory`
shlib_dir="$dir"/
for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
if [ "$dir" = "$base_ml_dir" ]; then
shlib_so_name=libgcc_s
break
else
canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"`
if [ -n "$canon_dir" ]; then
shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g`
break
fi
fi
done
gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'`
os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"`
if [ -z "$os_multilib_base" ]; then
shlib_so_name=libgcc_s
else
shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g`
fi
fi
fi
echo ""
@ -438,6 +434,7 @@ echo ""
echo "install: $all"
for ml in $MULTILIBS; do
dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
if [ $dir != . ]; then
ldir='$(libsubdir)'/$dir
echo " if [ -d $ldir ]; then true; else mkdir $ldir; chmod a+rx $ldir; fi;"
@ -460,39 +457,22 @@ for ml in $MULTILIBS; do
shlib_so_name="$shlib_base_name"
shlib_dir=
shlib_slibdir_qual=
if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then
shlib_slibdir_qual=none
if [ -n "$MULTILIB_OSDIRNAMES" ]; then
gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory`
os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory`
if [ "$dir" != . ]; then
shlib_dir="$dir"/
for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
if [ "$dir" = "$base_ml_dir" ]; then
shlib_so_name=libgcc_s
shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
break
else
canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"`
if [ -n "$canon_dir" ]; then
shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g`
shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
break
fi
fi
done
fi
if [ "$shlib_slibdir_qual" = none ]; then
for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
for ml2 in $MULTILIBS; do
dir2=`echo ${ml2} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
if [ "$base_ml_dir" = "$dir2" ]; then
shlib_slibdir_qual=
break
fi
done
if [ -n "$shlib_slibdir_qual" ]; then break; fi
done
gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'`
os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"`
if [ -z "$os_multilib_base" ]; then
shlib_so_name=libgcc_s
if [ "$os_multilib_dir" != "." ]; then
shlib_slibdir_qual="/$os_multilib_dir"
fi
else
shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g`
shlib_slibdir_qual="/$os_multilib_base"
fi
fi
echo " $SHLIB_INSTALL" \

View File

@ -7354,6 +7354,9 @@ gen_reload (out, in, opnum, type)
{
rtx last = get_last_insn ();
rtx tem;
#ifdef SECONDARY_MEMORY_NEEDED
int in_regnum, out_regnum;
#endif
/* If IN is a paradoxical SUBREG, remove it and try to put the
opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */
@ -7516,20 +7519,22 @@ gen_reload (out, in, opnum, type)
#ifdef SECONDARY_MEMORY_NEEDED
/* If we need a memory location to do the move, do it that way. */
else if (GET_CODE (in) == REG && REGNO (in) < FIRST_PSEUDO_REGISTER
&& GET_CODE (out) == REG && REGNO (out) < FIRST_PSEUDO_REGISTER
&& SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
REGNO_REG_CLASS (REGNO (out)),
else if ((in_regnum = true_regnum (in)) >= 0
&& in_regnum < FIRST_PSEUDO_REGISTER
&& (out_regnum = true_regnum (out)) >= 0
&& out_regnum < FIRST_PSEUDO_REGISTER
&& SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (in_regnum),
REGNO_REG_CLASS (out_regnum),
GET_MODE (out)))
{
/* Get the memory to use and rewrite both registers to its mode. */
rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
if (GET_MODE (loc) != GET_MODE (out))
out = gen_rtx_REG (GET_MODE (loc), REGNO (out));
out = gen_rtx_REG (GET_MODE (loc), out_regnum);
if (GET_MODE (loc) != GET_MODE (in))
in = gen_rtx_REG (GET_MODE (loc), REGNO (in));
in = gen_rtx_REG (GET_MODE (loc), in_regnum);
gen_reload (loc, in, opnum, type);
gen_reload (out, loc, opnum, type);
@ -7581,6 +7586,11 @@ delete_output_reload (insn, j, last_reload_reg)
rtx i1;
rtx substed;
/* It is possible that this reload has been only used to set another reload
we eliminated earlier and thus deleted this instruction too. */
if (INSN_DELETED_P (output_reload_insn))
return;
/* Get the raw pseudo-register referred to. */
while (GET_CODE (reg) == SUBREG)

View File

@ -1811,6 +1811,7 @@ extern int invert_jump_1 PARAMS ((rtx, rtx));
extern int invert_jump PARAMS ((rtx, rtx, int));
extern int rtx_renumbered_equal_p PARAMS ((rtx, rtx));
extern int true_regnum PARAMS ((rtx));
extern unsigned int reg_or_subregno PARAMS ((rtx));
extern int redirect_jump_1 PARAMS ((rtx, rtx));
extern int redirect_jump PARAMS ((rtx, rtx, int));
extern void rebuild_jump_labels PARAMS ((rtx));

View File

@ -923,7 +923,15 @@ sched_analyze_insn (deps, x, insn, loop_notes)
code = GET_CODE (x);
}
if (code == SET || code == CLOBBER)
sched_analyze_1 (deps, x, insn);
{
sched_analyze_1 (deps, x, insn);
/* Bare clobber insns are used for letting life analysis, reg-stack
and others know that a value is dead. Depend on the last call
instruction so that reg-stack won't get confused. */
if (code == CLOBBER)
add_dependence_list (insn, deps->last_function_call, REG_DEP_OUTPUT);
}
else if (code == PARALLEL)
{
int i;

View File

@ -574,8 +574,8 @@ optimize_sibling_and_tail_recursive_calls ()
rtx insn, insns;
basic_block alternate_exit = EXIT_BLOCK_PTR;
bool no_sibcalls_this_function = false;
int successful_sibling_call = 0;
int replaced_call_placeholder = 0;
bool successful_replacement = false;
bool replaced_call_placeholder = false;
edge e;
insns = get_insns ();
@ -715,10 +715,11 @@ optimize_sibling_and_tail_recursive_calls ()
/* Select a set of insns to implement the call and emit them.
Tail recursion is the most efficient, so select it over
a tail/sibling call. */
if (sibcall)
successful_sibling_call = 1;
replaced_call_placeholder = 1;
if (sibcall || tailrecursion)
successful_replacement = true;
replaced_call_placeholder = true;
replace_call_placeholder (insn,
tailrecursion != 0
? sibcall_use_tail_recursion
@ -728,7 +729,7 @@ optimize_sibling_and_tail_recursive_calls ()
}
}
if (successful_sibling_call)
if (successful_replacement)
{
rtx insn;
tree arg;

View File

@ -2051,6 +2051,33 @@ extern tree integer_types[itk_none];
#define long_long_integer_type_node integer_types[itk_long_long]
#define long_long_unsigned_type_node integer_types[itk_unsigned_long_long]
/* A pointer-to-function member type looks like:
struct {
__P __pfn;
ptrdiff_t __delta;
};
If __pfn is NULL, it is a NULL pointer-to-member-function.
(Because the vtable is always the first thing in the object, we
don't need its offset.) If the function is virtual, then PFN is
one plus twice the index into the vtable; otherwise, it is just a
pointer to the function.
Unfortunately, using the lowest bit of PFN doesn't work in
architectures that don't impose alignment requirements on function
addresses, or that use the lowest bit to tell one ISA from another,
for example. For such architectures, we use the lowest bit of
DELTA instead of the lowest bit of the PFN, and DELTA will be
multiplied by 2. */
enum ptrmemfunc_vbit_where_t
{
ptrmemfunc_vbit_in_pfn,
ptrmemfunc_vbit_in_delta
};
#define NULL_TREE (tree) NULL

View File

@ -1188,6 +1188,9 @@ unroll_loop (loop, insn_count, strength_reduce_p)
/* Keep track of the unroll factor for the loop. */
loop_info->unroll_number = unroll_number;
/* And whether the loop has been preconditioned. */
loop_info->preconditioned = loop_preconditioned;
/* For each biv and giv, determine whether it can be safely split into
a different variable for each unrolled copy of the loop body.
We precalculate and save this info here, since computing it is
@ -2868,7 +2871,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
value = tem;
}
splittable_regs[REGNO (v->new_reg)] = value;
splittable_regs[reg_or_subregno (v->new_reg)] = value;
}
else
{
@ -3047,21 +3050,21 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
itself does not have to be splittable. */
if (v->same && v->same->giv_type == DEST_REG)
addr_combined_regs[REGNO (v->same->new_reg)] = v->same;
addr_combined_regs[reg_or_subregno (v->same->new_reg)] = v->same;
if (GET_CODE (v->new_reg) == REG)
{
/* This giv maybe hasn't been combined with any others.
Make sure that it's giv is marked as splittable here. */
splittable_regs[REGNO (v->new_reg)] = value;
splittable_regs[reg_or_subregno (v->new_reg)] = value;
/* Make it appear to depend upon itself, so that the
giv will be properly split in the main loop above. */
if (! v->same)
{
v->same = v;
addr_combined_regs[REGNO (v->new_reg)] = v;
addr_combined_regs[reg_or_subregno (v->new_reg)] = v;
}
}
@ -3098,7 +3101,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
if (! v->ignore)
count = REG_IV_CLASS (ivs, REGNO (v->src_reg))->biv_count;
splittable_regs_updates[REGNO (v->new_reg)] = count;
splittable_regs_updates[reg_or_subregno (v->new_reg)] = count;
}
result++;

View File

@ -1194,6 +1194,8 @@ assemble_start_function (decl, fnname)
/* Tell assembler to move to target machine's alignment for functions. */
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
if (align < force_align_functions_log)
align = force_align_functions_log;
if (align > 0)
{
ASM_OUTPUT_ALIGN (asm_out_file, align);