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

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
obrien 2001-01-03 17:16:04 +00:00
commit 4e21a652d8
36 changed files with 1262 additions and 292 deletions

View File

@ -1,3 +1,357 @@
2001-01-01 Bernd Schmidt <bernds@redhat.co.uk>
* version.c: Bump.
* loop.c (instrument_loop_bct): Set JUMP_LABEL on new jump.
2000-12-27 Geoffrey Keating <geoffk@redhat.com>
* config/rs6000/rs6000.md (define_attr "length"): Correct
calculation.
2001-01-01 Philipp Thomas <pthomas@suse.de>
* configure.in: Make the help for --enable-nls make it
clear that this is an experimental feature.
* configure: Regenerate.
* ABOUT-GCC-NLS: Explain why NLS support is buggy.
2000-12-29 Bernd Schmidt <bernds@redhat.co.uk>
* version.c: Bump.
* combine.c (cant_combine_insn_p): Only restrict hard register
combinations for SMALL_REGISTER_CLASSES machines.
* config/sparc/sparc.c (pic_address_needs_scratch): LABEL_REFs are
not valid pic operands.
2000-12-26 Kazu Hirata <kazu@hxi.com>
* config/h8300/h8300.c (get_shift_alg): Fix a typo in the
assembly code for 12-bit ASHIFTRT in HImode.
2000-07-17 Kazu Hirata <kazu@hxi.com>
* h8300.md: Fix the format of mac.
(movsi_h8300hs): Output a tab after stmac instead of a space.
2000-10-07 Will Cohen <wcohen@redhat.com>, Kazu Hirata <kazu@hxi.com>
* config/h8300/h8300.md: Remove the memory alternative and correct
the insn lengths in the templates for sign extention and zero
extention.
2000-12-23 Philip Blundell <philb@gnu.org>
* config/arm/linux-elf.h (CPP_PREDEFINES): Don't define `arm' or
`arm_elf'; do define `__arm__'.
2000-08-22 Richard Henderson <rth@cygnus.com>
* alias.c (init_alias_analysis): Do not register
struct_value_incoming_rtx or static_chain_rtx as pointing
to stack memory.
Tue Dec 5 20:09:14 2000 Jeffrey A Law (law@cygnus.com)
* builtins.c (expand_builtin_setjmp_setup): Set
current_function_has_nonlocal_label.
2000-12-03 Richard Henderson <rth@redhat.com>
* builtins.c (expand_builtin_setjmp_setup): New.
(expand_builtin_setjmp_receiver): New.
(expand_builtin_setjmp): Split out _setup and _receiver functions.
Move argument parsing in from ...
(expand_builtin): ... here.
* except.c (receive_exception_label): Branch around receiver
unless new-style exceptions. Call expand_builtin_setjmp_receiver.
(start_dynamic_handler): Call expand_builtin_setjmp_setup.
* expr.h: Update builtin setjmp decls.
2000-12-22 Bernd Schmidt <bernds@redhat.co.uk>
* calls.c (emit_call_1): Fall back to call_pop/call_value_pop if no
non-popping calls are available.
* flow.c (propagate_block): Use flow_delete_insn instead of
NOTEifying a dead ADDR_VEC.
Fri Sep 10 11:43:07 1999 Philip Blundell <pb@futuretv.com>
* configure.in, config/arm/linux-oldld.h,
config/arm/linux-elf26.h, config/arm/linux-elf.h: Backport latest
ARM GNU/Linux config from mainline.
* configure: Regenerate.
2000-02-08 Geoff Keating <geoffk@cygnus.com>
* dwarf2.h (DW_CFA_GNU_negative_offset_extended): New constant.
* dwarf2out.c (dwarf_cfi_name): Print name of new constant.
(reg_save): Use DW_CFA_GNU_negative_offset_extended when needed.
(output_cfi): Handle output of DW_CFA_GNU_negative_offset_extended.
* frame.c (execute_cfa_insn): Handle
DW_CFA_GNU_negative_offset_extended.
2000-03-06 Mark Mitchell <mark@codesourcery.com>
* function.c (free_temps_for_rtl_expr): Don't free slots
that have been pushed into a higher level.
1999-12-16 David S. Miller <davem@redhat.com>
* expr.c (emit_move_insn_1): Only emit clobbers if one of
the outputs is a SUBREG.
Wed Sep 22 17:35:55 1999 Michael Meissner <meissner@cygnus.com>
* expr.c (emit_move_insn_1): If we are copying a complex that fits
in one word or less (complex char, complex short, or on 64 bit
systems complex float) to/from a hard register, copy it through
memory instead of dying in gen_{real,imag}part. If we have a
short complex type, prevent inlining since it allocates stack
memory.
Fri Dec 15 15:32:16 MET 2000 Jan Hubicka <jh@suse.cz>
* combine.c (cant_combine_insn_p): Get around SUBREGs when determining
hardreg<->reg moves.
2000-12-01 Bernd Schmidt <bernds@redhat.co.uk>
* combine.c (cant_combine_insn_p): Only disallow insns involving
hard regs if they are reg-reg moves.
2000-11-24 Bernd Schmidt <bernds@redhat.co.uk>
* combine.c (cant_combine_insn_p): New function.
(try_combine): Use it.
2000-12-20 Bernd Schmidt <bernds@redhat.co.uk>
* version.c: Bump.
* reload1.c (free_for_value_p): Fix error in last change.
2000-03-22 Richard Henderson <rth@cygnus.com>
* stmt.c (expand_asm_operands): Don't promote the temporary.
Sun Sep 19 09:03:40 1999 Mark Mitchell <mark@codesourcery.com>
* rtl.h (insns_safe_to_move_p): New function.
* loop.c (find_and_verify_loops): Use it.
* rtlanal.c (insns_safe_to_move_p): Define it.
Thu Nov 2 19:20:12 2000 J"orn Rennecke <amylaar@redhat.com>
* reload.c (find_equiv_reg): Test all hard registers for membership
in the requested class.
Sun Apr 23 16:24:35 2000 Denis Chertykov <denisc@overta.ru>
* reload.c (find_equiv_reg): Checks all valueno regs
as a reload_reg_p regs.
Fri Apr 21 14:58:29 2000 Denis Chertykov <denisc@overta.ru>
* reload.c (find_equiv_reg): Checks all valueno and regno regs
as a call-clobbered regs.
2000-12-18 Bernd Schmidt <bernds@redhat.co.uk>
2000-09-15 Bernd Schmidt <bernds@redhat.co.uk>
* optabs.c (emit_libcall_block): If target is a user variable,
copy to a temporary first.
2000-04-28 Kazu Hirata <kazu@hxi.com>
* h8300.c (function_epilogue): Clean up flags when the last insn
in a function is a barrier.
Mon Aug 30 01:02:09 1999 Jeffrey A Law (law@cygnus.com)
* emit-rtl.c (copy_rtx_if_shared): A MEM which references
virtual_stack_vars_rtx or virtual_incoming_args_rtx can not
be shared.
2000-03-24 Geoff Keating <geoffk@cygnus.com>
* flow.c (propagate_block): When we delete an ADDR_VEC,
also delete the BARRIER following it if there is one.
Wed Oct 27 14:10:27 1999 Geoffrey Keating <geoffk@cygnus.com>
* flow.c (propagate_block): When the last reference to a label
before an ADDR_VEC is deleted because the reference is a dead
store, delete the ADDR_VEC.
2000-03-19 Richard Henderson <rth@cygnus.com>
* flow.c (delete_block): Delete the addr_vec along with the block.
(flow_delete_insn): Decrement LABEL_NUSES when deleting insns that
reference labels.
2000-12-02 Bernd Schmidt <bernds@redhat.co.uk>
* reload1.c (free_for_value_p): New function, frontend to
reload_reg_free_for_value_p. All callers of the latter now call
this function with an additional mode argument.
2000-11-10 Bernd Schmidt <bernds@redhat.co.uk>
(regno_clobbered_p): New arg SETS. Examine SETs if it's nonzero. All
callers changed.
* reload1.c (choose_reload_regs): Registers set in the insn can't be
used for RELOAD_OTHER reloads.
2000-10-28 Bernd Schmidt <bernds@redhat.co.uk>
* reload1.c (choose_reload_regs): Never set reload_override_in for an
optional reload.
2000-09-07 Bernd Schmidt <bernds@redhat.co.uk>
* reload.c (regno_clobbered_p): Accept new arg, MODE, and use it
to handle multiword modes correctly. All callers and the declaration
changed.
2000-12-18 David Edelsohn <edelsohn@gnu.org>
* rs6000.c (and64_operand): Use logical_u_operand.
(first_reg_to_save): Don't save fixed or call-used registers
except PIC_OFFSET_TABLE_REGNUM when -fpic even though it is fixed.
* rs6000.md (anddi3): Prefer rldic? over andis instruction.
2000-12-18 Zack Weinberg <zackw@Stanford.EDU>:
* Makefile.in: Rename cpp to cpp0, tradcpp to tradcpp0, and
xcpp to cpp throughout.
(native): Remove unnecessary dependency on cpp.
* gcc.c (C specs): Call cpp0 to do preprocessing, not cpp.
* ch/lang-specs.h, cp/lang-specs.h, f/lang-specs.h,
objc/lang-specs.h: Call cpp0 to do preprocessing, not cpp.
2000-12-18 Christian Groessler <cpg@aladdin.de>
* toplev.c (check_lang_option): Use NUM_ELEM only on arrays, not on
pointers.
2000-12-18 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* linux.h (DEFAULT_VTABLE_THUNKS): Switch back to version 1.
* alpha/linux-elf.h (DEFAULT_VTABLE_THUNKS): Likewise.
* arm/linux-elf (DEFAULT_VTABLE_THUNKS): Likewise.
* i386/freebsd-elf.h (DEFAULT_VTABLE_THUNKS): Likewise.
* rs6000/linux.h (DEFAULT_VTABLE_THUNKS): Likewise.
* sparc/linux.h (DEFAULT_VTABLE_THUNKS): Likewise.
2000-12-05 Bernd Schmidt <bernds@redhat.co.uk>
* version.c: Bump.
2000-07-03 Nick Clifton <nickc@cygnus.com>
* config/arm/arm.md: Fix post increment and pre increment
peepholes so that they do not generate UNPREDICATBLE opcodes.
(ie ones where the increment clobbers the source/destination).
Mon Oct 25 00:42:35 1999 Jeffrey A Law (law@cygnus.com)
* arm.c (arm_override_options): Correct initialization of
arm_fast_multiply, arm_arch4, arm_arch5, arm_ld_sched,
arm_is_strong, and arm_is_6_or_7.
Thu Jul 29 19:01:58 1999 Bernd Schmidt <bernds@cygnus.co.uk>
* arm.h (Hint): Delete macro.
Substitute HOST_WIDE_INT for Hint in some prototypes.
* arm.c: Substitute HOST_WIDE_INT for Hint in one prototype.
2000-11-30 Bernd Schmidt <bernds@redhat.co.uk>
* version.c: Bump.
Based on a patch from Geoff Keating <geoffk@redhat.com>:
* loop.c (basic_induction_var): If a REG is set from something
that is not a biv, then the REG is not a biv. Even if it is
earlier set from something that is a biv.
2000-09-01 Jim Wilson <wilson@cygnus.com>
* loop.c (check_final_value): Check for biv use before checking for
giv use. Check for both biv and giv uses. Always set last_giv_use
if there is a giv use.
2000-09-29 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* loop.c (check_final_value): A GIV is not replaceable if used
before set.
Sun Oct 10 13:28:48 1999 Bernd Schmidt <bernds@redhat.co.uk>
* loop.c (find_and_verify_loops): When looking for a BARRIER, don't
use one before a jump table.
Fri Jul 9 10:48:28 1999 Bernd Schmidt <bernds@redhat.co.uk>
* loop.c (check_dbra_loop): When reversing a loop, delete all
REG_EQUAL notes referencing the reversed biv except those which are
for a giv based on it.
2000-11-24 Bernd Schmidt <bernds@redhat.co.uk>
* reload1.c (conflicts_with_override): New function.
(emit_input_reload_insns): Use it to tighten test for validity
of substituting into output of previous insn.
Wed Oct 27 03:09:23 1999 J"orn Rennecke <amylaar@redhat.co.uk>
* reload.h (earlyclobber_operand_p): Declare.
* reload.c (earlyclobber_operand_p): Don't declare. No longer static.
* reload1.c (reload_reg_free_for_value_p): RELOAD_OTHER reloads with
an earlyclobbered output conflict with RELOAD_INPUT reloads - handle
case where the RELOAD_OTHER reload is new. Use
earlyclobber_operand_p.
2000-01-12 Bernd Schmidt <bernds@redhat.co.uk>
* reload1.c (reload_reg_unavailable): New static variable.
(reload_reg_free_p): Test it.
(reload_reg_free_for_value_p): Test it instead of reload_reg_used.
(choose_reload_regs_init): Compute it.
Thu Jul 6 18:30:36 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* reload.c (push_reload): When seeing if can reuse a register,
check extra registers against widest of INMODE and OUTMODE.
1999-11-29 Bernd Schmidt <bernds@redhat.co.uk>
* reload.c (push_reload): When looking for a register to put into
reg_rtx, make sure all hard regs in a multi-reg register are in the
right class and nonfixed.
1999-11-29 Joern Rennecke <amylaar@redhat.co.uk>
* reload1.c (reloads_conflict): Reverse test comparing operand
numbers when testing for conflict between output/outaddr reloads.
2000-07-12 Richard Henderson <rth@redhat.com>
* reload.c (push_secondary_reload): Make sure to add the new
reload at the end, after acquiring secondary memory.
2000-09-14 Alexandre Oliva <aoliva@redhat.com>, Bernd Schmidt <bernds@redhat.co.uk>
* reload.c (find_reloads_address_1): Generate reloads for auto_inc
pseudos that refer to the original pseudos, not only to their
equivalent memory locations.
2000-09-18 Bernd Schmidt <bernds@redhat.co.uk>
* reload1.c (forget_old_reloads_1): If a hard reg is stored, clear
its entry in spill_reg_store.
Tue Oct 26 00:41:54 1999 Bernd Schmidt <bernds@cygnus.co.uk>
* reload1.c (reload_reg_free_for_value_p): Show
RELOAD_FOR_OTHER_ADDRESS reloads can conflict with RELOAD_OTHER
reloads.
2000-02-26 Geoff Keating <geoffk@cygnus.com>
* reload1.c (do_output_reload): Check reg_reloaded_valid before
looking at reg_reloaded_contents.
Thu Apr 13 19:39:56 2000 Clinton Popetz <cpopetz@cygnus.com>
* emit-rtl.c (try_split): Avoid infinite loop if the split
results in a sequence that contains the original insn.
1999-12-14 Bernd Schmidt <bernds@cygnus.co.uk>
* combine.c (combine_simplify_rtx): Don't make shared rtl.
(simplify_logical): Likewise.
Sat May 20 07:27:35 2000 Alexandre Oliva <aoliva@cygnus.com>
* fold-const.c (make_range): Handle degenerated intervals.
Fixes c-torture/execute/991221-1.c
2000-07-15 Michael Meissner <meissner@redhat.com>
* fold-const.c (fold): When optimizing FOO++ == CONST into ++FOO
== CONST + INCREMENT, don't overwrite the tree node for FOO++,
create a new node instead.
2000-01-01 Bernd Schmidt <bernds@cygnus.co.uk>
* expmed.c (emit_store_flag): Prevent losing a pending stack
adjust the same way we prevent losing queued increments.
2000-10-27 Bernd Schmidt <bernds@redhat.co.uk>
* expr.c (expand_expr, case INDIRECT_REF): If the address is a
PLUS, that does not prove the object is in a structure.
2000-08-25 David Edelsohn <edelsohn@gnu.org>
* collect2.c (use_import_list): Always return 0 (disable).
2000-07-07 Manfred Hollstein <manfredh@redhat.com>
* i386.md (exception_receiver): Add missing parameter in
call to load_pic_register.
Fri May 26 10:30:02 2000 Richard Earnshaw (rearnsha@arm.com)
* arm.md (negdi2): Add clobber of condition code register.

View File

@ -1455,15 +1455,6 @@ init_alias_analysis ()
new_reg_base_value[HARD_FRAME_POINTER_REGNUM]
= gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
#endif
if (struct_value_incoming_rtx
&& GET_CODE (struct_value_incoming_rtx) == REG)
new_reg_base_value[REGNO (struct_value_incoming_rtx)]
= gen_rtx_ADDRESS (Pmode, struct_value_incoming_rtx);
if (static_chain_rtx
&& GET_CODE (static_chain_rtx) == REG)
new_reg_base_value[REGNO (static_chain_rtx)]
= gen_rtx_ADDRESS (Pmode, static_chain_rtx);
/* Walk the insns adding values to the new_reg_base_value array. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))

View File

@ -405,7 +405,15 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
#ifndef ACCUMULATE_OUTGOING_ARGS
#if defined (HAVE_call_pop) && defined (HAVE_call_value_pop)
if (HAVE_call_pop && HAVE_call_value_pop && n_popped > 0)
/* If the target has "call" or "call_value" insns, then prefer them
if no arguments are actually popped. If the target does not have
"call" or "call_value" insns, then we must use the popping versions
even if the call has no arguments to pop. */
if (HAVE_call_pop && HAVE_call_value_pop
#if defined (HAVE_call) && defined (HAVE_call_value)
&& (n_popped > 0 || ! HAVE_call || ! HAVE_call_value)
#endif
)
{
rtx n_pop = GEN_INT (n_popped);
rtx pat;

View File

@ -3045,21 +3045,11 @@ scan_prog_file (prog_name, which_pass)
#ifdef COLLECT_EXPORT_LIST
/* This new function is used to decide whether we should
generate import list for an object or to use it directly. */
/* Never generate import list (gcc-2.95 branch). */
static int
use_import_list (prog_name)
char *prog_name;
{
char *p;
/* If we do not build a shared object then import list should not be used. */
if (! shared_obj) return 0;
/* Currently we check only for libgcc, but this can be changed in future. */
p = strstr (prog_name, "libgcc.a");
if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
return 1;
return 0;
}

View File

@ -392,6 +392,7 @@ static int n_occurrences;
static void init_reg_last_arrays PROTO((void));
static void setup_incoming_promotions PROTO((void));
static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx));
static int cant_combine_insn_p PROTO((rtx));
static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *));
static int sets_function_arg_p PROTO((rtx));
static int combinable_i3pat PROTO((rtx, rtx *, rtx, rtx, int, rtx *));
@ -1312,6 +1313,54 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
return 1;
}
/* Determine whether INSN can be used in a combination. Return nonzero if
not. This is used in try_combine to detect early some cases where we
can't perform combinations. */
static int
cant_combine_insn_p (insn)
rtx insn;
{
rtx set;
rtx src, dest;
/* If this isn't really an insn, we can't do anything.
This can occur when flow deletes an insn that it has merged into an
auto-increment address. */
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
return 1;
/* For the 2.95.3 release, restrict this code to only handle the machines
where it's strictly needed. */
if (! SMALL_REGISTER_CLASSES)
return 0;
/* Never combine loads and stores involving hard regs. The register
allocator can usually handle such reg-reg moves by tying. If we allow
the combiner to make substitutions of hard regs, we risk aborting in
reload on machines that have SMALL_REGISTER_CLASSES.
As an exception, we allow combinations involving fixed regs; these are
not available to the register allocator so there's no risk involved. */
set = single_set (insn);
if (! set)
return 0;
src = SET_SRC (set);
dest = SET_DEST (set);
if (GET_CODE (src) == SUBREG)
src = SUBREG_REG (src);
if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
if (REG_P (src) && REG_P (dest)
&& ((REGNO (src) < FIRST_PSEUDO_REGISTER
&& ! fixed_regs[REGNO (src)])
|| (REGNO (dest) < FIRST_PSEUDO_REGISTER
&& ! fixed_regs[REGNO (dest)])))
return 1;
return 0;
}
/* Try to combine the insns I1 and I2 into I3.
Here I1 and I2 appear earlier than I3.
I1 can be zero; then we combine just I2 into I3.
@ -1362,21 +1411,20 @@ try_combine (i3, i2, i1)
register rtx link;
int i;
/* If any of I1, I2, and I3 isn't really an insn, we can't do anything.
This can occur when flow deletes an insn that it has merged into an
auto-increment address. We also can't do anything if I3 has a
REG_LIBCALL note since we don't want to disrupt the contiguity of a
libcall. */
if (GET_RTX_CLASS (GET_CODE (i3)) != 'i'
|| GET_RTX_CLASS (GET_CODE (i2)) != 'i'
|| (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i')
/* Exit early if one of the insns involved can't be used for
combinations. */
if (cant_combine_insn_p (i3)
|| cant_combine_insn_p (i2)
|| (i1 && cant_combine_insn_p (i1))
/* We also can't do anything if I3 has a
REG_LIBCALL note since we don't want to disrupt the contiguity of a
libcall. */
#if 0
/* ??? This gives worse code, and appears to be unnecessary, since no
pass after flow uses REG_LIBCALL/REG_RETVAL notes. */
|| find_reg_note (i3, REG_LIBCALL, NULL_RTX)
#endif
)
)
return 0;
combine_attempts++;
@ -4015,7 +4063,8 @@ simplify_rtx (x, op0_mode, last, in_dest)
gen_binary (MULT, mode,
XEXP (XEXP (x, 0), 0), XEXP (x, 1)),
gen_binary (MULT, mode,
XEXP (XEXP (x, 0), 1), XEXP (x, 1))));
XEXP (XEXP (x, 0), 1),
copy_rtx (XEXP (x, 1)))));
if (GET_CODE (x) != MULT)
return x;
@ -4954,7 +5003,8 @@ simplify_logical (x, last)
x = apply_distributive_law
(gen_binary (GET_CODE (op0), mode,
gen_binary (AND, mode, XEXP (op0, 0), op1),
gen_binary (AND, mode, XEXP (op0, 1), op1)));
gen_binary (AND, mode, XEXP (op0, 1),
copy_rtx (op1))));
if (GET_CODE (x) != AND)
return x;
}
@ -4963,7 +5013,8 @@ simplify_logical (x, last)
return apply_distributive_law
(gen_binary (GET_CODE (op1), mode,
gen_binary (AND, mode, XEXP (op1, 0), op0),
gen_binary (AND, mode, XEXP (op1, 1), op0)));
gen_binary (AND, mode, XEXP (op1, 1),
copy_rtx (op0))));
/* Similarly, taking advantage of the fact that
(and (not A) (xor B C)) == (xor (ior A B) (ior A C)) */
@ -4972,13 +5023,14 @@ simplify_logical (x, last)
return apply_distributive_law
(gen_binary (XOR, mode,
gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)),
gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 1))));
gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)),
XEXP (op1, 1))));
else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR)
return apply_distributive_law
(gen_binary (XOR, mode,
gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)),
gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 1))));
gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1))));
break;
case IOR:
@ -5004,7 +5056,8 @@ simplify_logical (x, last)
x = apply_distributive_law
(gen_binary (AND, mode,
gen_binary (IOR, mode, XEXP (op0, 0), op1),
gen_binary (IOR, mode, XEXP (op0, 1), op1)));
gen_binary (IOR, mode, XEXP (op0, 1),
copy_rtx (op1))));
if (GET_CODE (x) != IOR)
return x;
@ -5015,7 +5068,8 @@ simplify_logical (x, last)
x = apply_distributive_law
(gen_binary (AND, mode,
gen_binary (IOR, mode, XEXP (op1, 0), op0),
gen_binary (IOR, mode, XEXP (op1, 1), op0)));
gen_binary (IOR, mode, XEXP (op1, 1),
copy_rtx (op0))));
if (GET_CODE (x) != IOR)
return x;

View File

@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA. */
#ifndef USE_GNULIBC_1
#undef DEFAULT_VTABLE_THUNKS
#define DEFAULT_VTABLE_THUNKS 2
#define DEFAULT_VTABLE_THUNKS 1
#endif
#ifndef USE_GNULIBC_1

View File

@ -89,7 +89,7 @@ Boston, MA 02111-1307, USA. */
#ifndef USE_GNULIBC_1
#undef DEFAULT_VTABLE_THUNKS
#define DEFAULT_VTABLE_THUNKS 2
#define DEFAULT_VTABLE_THUNKS 1
#endif
#undef LIB_SPEC

View File

@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA. */
#ifndef USE_GNULIBC_1
#undef DEFAULT_VTABLE_THUNKS
#define DEFAULT_VTABLE_THUNKS 2
#define DEFAULT_VTABLE_THUNKS 1
#endif
/* Use stabs instead of DWARF debug format. */

View File

@ -2429,6 +2429,9 @@ int
pic_address_needs_scratch (x)
rtx x;
{
if (GET_CODE (x) == LABEL_REF)
return 1;
/* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF

View File

@ -756,15 +756,31 @@ changequote([,])dnl
tmake_file=arm/t-linux
gnu_ld=yes
;;
arm*-*-linux-gnuoldld*) # ARM GNU/Linux with old ELF linker
xm_file=arm/xm-linux.h
xmake_file=x-linux
tm_file="arm/linux-oldld.h arm/linux-elf.h"
case $machine in
armv2*-*-*)
tm_file="arm/linux-elf26.h $tm_file"
;;
esac
tmake_file="t-linux arm/t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
gnu_ld=yes
case x${enable_threads} in
x | xyes | xpthreads | xposix)
thread_file='posix'
;;
esac
;;
arm*-*-linux-gnu*) # ARM GNU/Linux with ELF
xm_file=arm/xm-linux.h
xmake_file=x-linux
tm_file="arm/linux-elf.h"
case $machine in
armv2*-*-*)
tm_file=arm/linux-elf26.h
;;
*)
tm_file=arm/linux-elf.h
tm_file="arm/linux-elf26.h $tm_file"
;;
esac
tmake_file="t-linux arm/t-linux"
@ -3731,7 +3747,8 @@ ALL_LINGUAS="en_UK"
# NLS support is still experimental, so disable it by default for now.
AC_ARG_ENABLE(nls,
[ --enable-nls use Native Language Support (disabled by default)],
[ --enable-nls use Native Language Support (disabled by default).
EXPERIMENTAL, see ABOUT-GCC-NLS.],
, enable_nls=no)
AM_GNU_GETTEXT

View File

@ -1,3 +1,19 @@
Fri Jun 9 17:55:08 2000 Jeffrey A Law (law@cygnus.com)
2000-02-07 <loewis@informatik.hu-berlin.de>
* decl2.c (import_export_decl): vlist ctor wrappers follow virtual
methods in their interface.
(vlist_ctor_wrapper_p): new function.
(finish_vlist_ctor_wrapper): likewise.
2000-02-06 <loewis@informatik.hu-berlin.de>
* decl2.c (maybe_retrofit_in_chrg): Move call to
make_vlist_ctor_wrapper from here ...
* decl.c (grok_ctor_properties): ... to here.
* decl.c (grokfndecl): ... and here.
* init.c (no_vlist_base_init): Declare unseen Vlist ctor weak.
* decl2.c (maybe_retrofit_in_chrg): Be sorry about varargs ctors.
2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
* exception.cc (__cp_pop_exception): Cleanup the original object.

View File

@ -980,7 +980,11 @@ maybe_retrofit_in_chrg (fn)
if (DECL_CONSTRUCTOR_P (fn))
{
if (TYPE_USES_PVBASES (DECL_CLASS_CONTEXT (fn)))
DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_PVBASE;
{
DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_PVBASE;
if (flag_vtable_thunks_compat && varargs_function_p (fn))
sorry ("-fvtable-thunks=2 for vararg constructor", fn);
}
else
DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_VBASE;
}
@ -1028,10 +1032,6 @@ maybe_retrofit_in_chrg (fn)
fntype = build_exception_variant (fntype,
TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
TREE_TYPE (fn) = fntype;
if (flag_vtable_thunks_compat
&& DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))
make_vlist_ctor_wrapper (fn);
}
/* Classes overload their constituent function names automatically.
@ -2854,6 +2854,30 @@ import_export_decl (decl)
else
DECL_NOT_REALLY_EXTERN (decl) = 0;
}
else if (DECL_VLIST_CTOR_WRAPPER_P (decl))
{
int implement;
tree ctype = DECL_CLASS_CONTEXT (decl);
import_export_class (ctype);
if (!DECL_THIS_INLINE (DECL_VLIST_CTOR_WRAPPED (decl)))
{
/* No change. */
}
else if (CLASSTYPE_INTERFACE_KNOWN (ctype))
{
implement = !CLASSTYPE_INTERFACE_ONLY (ctype)
&& flag_implement_inlines;
DECL_NOT_REALLY_EXTERN (decl) = implement;
DECL_EXTERNAL (decl) = !implement;
}
else
{
DECL_NOT_REALLY_EXTERN (decl) = 1;
DECL_EXTERNAL (decl) = 1;
}
if (flag_weak)
comdat_linkage (decl);
}
else if (DECL_FUNCTION_MEMBER_P (decl))
{
tree ctype = DECL_CLASS_CONTEXT (decl);
@ -3606,6 +3630,33 @@ generate_ctor_and_dtor_functions_for_priority (n, data)
return 0;
}
/* Returns non-zero if T is a vlist ctor wrapper. */
static int
vlist_ctor_wrapper_p (t, data)
tree t;
void *data ATTRIBUTE_UNUSED;
{
return (TREE_CODE (t) == FUNCTION_DECL) && DECL_VLIST_CTOR_WRAPPER_P (t);
}
/* Emits a vlist ctor wrapper if necessary. */
static int
finish_vlist_ctor_wrapper (t, data)
tree *t;
void *data ATTRIBUTE_UNUSED;
{
import_export_decl (*t);
if (!DECL_EXTERNAL (*t) && !TREE_USED (*t))
{
mark_used (*t);
synthesize_method (*t);
return 1;
}
return 0;
}
/* This routine is called from the last rule in yyparse ().
Its job is to create all the code needed to initialize and
destroy the global aggregates. We do the destruction
@ -3682,6 +3733,12 @@ finish_file ()
/*data=*/0))
reconsider = 1;
if (walk_globals (vlist_ctor_wrapper_p,
finish_vlist_ctor_wrapper,
/*data=*/0))
reconsider = 1;
/* The list of objects with static storage duration is built up
in reverse order, so we reverse it here. We also clear
STATIC_AGGREGATES so that any new aggregates added during the

View File

@ -1262,6 +1262,14 @@ no_vlist_base_init (rval, exp, init, binfo, flags)
my_friendly_assert (TREE_CODE (func) == CALL_EXPR, 20000131);
func = TREE_OPERAND (func, 0);
my_friendly_assert (TREE_CODE (func) == ADDR_EXPR, 20000132);
func = TREE_OPERAND (func, 0);
my_friendly_assert (TREE_CODE (func) == FUNCTION_DECL, 20000133);
/* If we have already seen a definition for the wrapped function,
we don't need to declare it weak. Also, declare_weak will complain
if we do. */
if (!TREE_ASM_WRITTEN (func))
declare_weak (func);
if (init == NULL_TREE
|| (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))

View File

@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA. */
{"@c++",
#if USE_CPPLIB
{
"%{E|M|MM:cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
"%{E|M|MM:cpp0 -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
%{C:%{!E:%eGNU C++ does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
%{!no-gcc:-D__GNUC__=%v1 -D__GNUG__=%v1 -D__GNUC_MINOR__=%v2}\
@ -62,7 +62,7 @@ Boston, MA 02111-1307, USA. */
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
%{!pipe:%g.s} %A\n }}}}"}},
#else /* ! USE_CPPLIB */
{"cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
{"cpp0 -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
%{C:%{!E:%eGNU C++ does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
%{!no-gcc:-D__GNUC__=%v1 -D__GNUG__=%v1 -D__GNUC_MINOR__=%v2}\

View File

@ -2241,13 +2241,18 @@ emit_thunk (thunk_fndecl)
}
void
make_vlist_ctor_wrapper (fn)
maybe_vlist_ctor_wrapper (fn, definep)
tree fn;
int definep;
{
tree fntype, decl;
tree arg_types, parms, parm, basetype, pbasetype;
tree t, ctors;
if (!flag_vtable_thunks_compat
|| !DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))
return;
arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
pbasetype = TREE_VALUE (arg_types);
basetype = TREE_TYPE (pbasetype);
@ -2324,15 +2329,23 @@ make_vlist_ctor_wrapper (fn)
/* Remember the original function. */
DECL_VLIST_CTOR_WRAPPED (decl) = fn;
/* When fn is declared, DECL_INITIAL is null. When it is defined,
DECL_INITIAL will be error_mark_node. */
if (DECL_INITIAL (fn) == error_mark_node)
/* If this is called from start_method, definep is -1. Then we
are inside the class, and fn is inline by default. */
if (definep)
{
/* Record that the ctor is being defined, so we also emit the
wrapper later. */
TREE_USED (decl) = 1;
DECL_NOT_REALLY_EXTERN (decl) = 1;
DECL_INITIAL (decl) = NULL_TREE;
wrapper later. */
if (DECL_THIS_INLINE (fn) || (definep == -1))
{
DECL_THIS_INLINE (decl) = 1;
DECL_INLINE (decl) = 1;
pushdecl_top_level (decl);
}
else
{
TREE_USED (decl) = 1;
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1;
}
mark_inline_for_output (decl);
}
}
@ -2651,6 +2664,3 @@ synthesize_method (fndecl)
else if (nested)
pop_cp_function_context (context);
}

View File

@ -1,6 +1,7 @@
/* Declarations and definitions of codes relating to the DWARF2 symbolic
debugging information format.
Copyright (C) 1992, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1995, 1996, 1997, 2000
Free Software Foundation, Inc.
Contributed by Gary Funck (gary@intrepid.com). Derived from the
DWARF 1 implementation written by Ron Guilmette (rfg@monkeys.com).
@ -501,7 +502,8 @@ enum dwarf_call_frame_info
/* GNU extensions */
DW_CFA_GNU_window_save = 0x2d,
DW_CFA_GNU_args_size = 0x2e
DW_CFA_GNU_args_size = 0x2e,
DW_CFA_GNU_negative_offset_extended = 0x2f
};
#define DW_CIE_ID 0xffffffff

View File

@ -719,6 +719,8 @@ dwarf_cfi_name (cfi_opc)
return "DW_CFA_GNU_window_save";
case DW_CFA_GNU_args_size:
return "DW_CFA_GNU_args_size";
case DW_CFA_GNU_negative_offset_extended:
return "DW_CFA_GNU_negative_offset_extended";
default:
return "DW_CFA_<unknown>";
@ -948,7 +950,10 @@ reg_save (label, reg, sreg, offset)
offset /= DWARF_CIE_DATA_ALIGNMENT;
if (offset < 0)
abort ();
{
cfi->dw_cfi_opc = DW_CFA_GNU_negative_offset_extended;
offset = -offset;
}
cfi->dw_cfi_oprnd2.dw_cfi_offset = offset;
}
else
@ -1635,6 +1640,7 @@ output_cfi (cfi, fde)
break;
#endif
case DW_CFA_offset_extended:
case DW_CFA_GNU_negative_offset_extended:
case DW_CFA_def_cfa:
output_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
fputc ('\n', asm_out_file);

View File

@ -1847,25 +1847,17 @@ copy_rtx_if_shared (orig)
return x;
case MEM:
/* A MEM is allowed to be shared if its address is constant
or is a constant plus one of the special registers. */
if (CONSTANT_ADDRESS_P (XEXP (x, 0))
|| XEXP (x, 0) == virtual_stack_vars_rtx
|| XEXP (x, 0) == virtual_incoming_args_rtx)
/* A MEM is allowed to be shared if its address is constant.
We used to allow sharing of MEMs which referenced
virtual_stack_vars_rtx or virtual_incoming_args_rtx, but
that can lose. instantiate_virtual_regs will not unshare
the MEMs, and combine may change the structure of the address
because it looks safe and profitable in one context, but
in some other context it creates unrecognizable RTL. */
if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
return x;
if (GET_CODE (XEXP (x, 0)) == PLUS
&& (XEXP (XEXP (x, 0), 0) == virtual_stack_vars_rtx
|| XEXP (XEXP (x, 0), 0) == virtual_incoming_args_rtx)
&& CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
{
/* This MEM can appear in more than one place,
but its address better not be shared with anything else. */
if (! x->used)
XEXP (x, 0) = copy_rtx_if_shared (XEXP (x, 0));
x->used = 1;
return x;
}
break;
default:
@ -2359,10 +2351,18 @@ try_split (pat, trial, last)
it, in turn, will be split (SFmode on the 29k is an example). */
if (GET_CODE (seq) == SEQUENCE)
{
int i;
/* Avoid infinite loop if any insn of the result matches
the original pattern. */
for (i = 0; i < XVECLEN (seq, 0); i++)
if (GET_CODE (XVECEXP (seq, 0, i)) == INSN
&& rtx_equal_p (PATTERN (XVECEXP (seq, 0, i)), pat))
return trial;
/* If we are splitting a JUMP_INSN, look for the JUMP_INSN in
SEQ and copy our JUMP_LABEL to it. If JUMP_LABEL is non-zero,
increment the usage count so we don't delete the label. */
int i;
if (GET_CODE (trial) == JUMP_INSN)
for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)

View File

@ -723,21 +723,41 @@ static void
receive_exception_label (handler_label)
rtx handler_label;
{
rtx around_label = NULL_RTX;
if (! flag_new_exceptions || exceptions_via_longjmp)
{
around_label = gen_label_rtx ();
emit_jump (around_label);
emit_barrier ();
}
emit_label (handler_label);
if (! exceptions_via_longjmp)
{
#ifdef HAVE_exception_receiver
if (! exceptions_via_longjmp)
if (HAVE_exception_receiver)
emit_insn (gen_exception_receiver ());
if (HAVE_exception_receiver)
emit_insn (gen_exception_receiver ());
else
#endif
#ifdef HAVE_nonlocal_goto_receiver
if (! exceptions_via_longjmp)
if (HAVE_nonlocal_goto_receiver)
emit_insn (gen_nonlocal_goto_receiver ());
if (HAVE_nonlocal_goto_receiver)
emit_insn (gen_nonlocal_goto_receiver ());
else
#endif
}
{ /* Nothing */ }
}
else
{
#ifndef DONT_USE_BUILTIN_SETJMP
expand_builtin_setjmp_receiver (handler_label);
#endif
}
if (around_label)
emit_label (around_label);
}
struct func_eh_entry
{
@ -1320,7 +1340,7 @@ static void
start_dynamic_handler ()
{
rtx dhc, dcc;
rtx x, arg, buf;
rtx arg, buf;
int size;
#ifndef DONT_USE_BUILTIN_SETJMP
@ -1362,18 +1382,17 @@ start_dynamic_handler ()
buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
#ifdef DONT_USE_BUILTIN_SETJMP
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
buf, Pmode);
/* If we come back here for a catch, transfer control to the handler. */
jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
#else
{
/* A label to continue execution for the no exception case. */
rtx noex = gen_label_rtx();
x = expand_builtin_setjmp (buf, NULL_RTX, noex,
ehstack.top->entry->exception_handler_label);
emit_label (noex);
rtx x;
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST,
TYPE_MODE (integer_type_node), 1,
buf, Pmode);
/* If we come back here for a catch, transfer control to the handler. */
jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
}
#else
expand_builtin_setjmp_setup (buf,
ehstack.top->entry->exception_handler_label);
#endif
/* We are committed to this, so update the handler chain. */

View File

@ -4194,9 +4194,11 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
comparison and then the scc insn.
compare_from_rtx may call emit_queue, which would be deleted below
if the scc insn fails. So call it ourselves before setting LAST. */
if the scc insn fails. So call it ourselves before setting LAST.
Likewise for do_pending_stack_adjust. */
emit_queue ();
do_pending_stack_adjust ();
last = get_last_insn ();
comparison

View File

@ -191,6 +191,7 @@ static rtx expand_builtin PROTO((tree, rtx, rtx,
static int apply_args_size PROTO((void));
static int apply_result_size PROTO((void));
static rtx result_vector PROTO((int, rtx));
static rtx expand_builtin_setjmp PROTO((tree, rtx));
static rtx expand_builtin_apply_args PROTO((void));
static rtx expand_builtin_apply PROTO((rtx, rtx, rtx));
static void expand_builtin_return PROTO((rtx));
@ -2679,19 +2680,79 @@ emit_move_insn_1 (x, y)
}
else
{
/* Show the output dies here. This is necessary for pseudos;
rtx realpart_x, realpart_y;
rtx imagpart_x, imagpart_y;
/* If this is a complex value with each part being smaller than a
word, the usual calling sequence will likely pack the pieces into
a single register. Unfortunately, SUBREG of hard registers only
deals in terms of words, so we have a problem converting input
arguments to the CONCAT of two registers that is used elsewhere
for complex values. If this is before reload, we can copy it into
memory and reload. FIXME, we should see about using extract and
insert on integer registers, but complex short and complex char
variables should be rarely used. */
if (GET_MODE_BITSIZE (mode) < 2*BITS_PER_WORD
&& (reload_in_progress | reload_completed) == 0)
{
int packed_dest_p = (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER);
int packed_src_p = (REG_P (y) && REGNO (y) < FIRST_PSEUDO_REGISTER);
if (packed_dest_p || packed_src_p)
{
enum mode_class reg_class = ((class == MODE_COMPLEX_FLOAT)
? MODE_FLOAT : MODE_INT);
enum machine_mode reg_mode =
mode_for_size (GET_MODE_BITSIZE (mode), reg_class, 1);
if (reg_mode != BLKmode)
{
rtx mem = assign_stack_temp (reg_mode,
GET_MODE_SIZE (mode), 0);
rtx cmem = change_address (mem, mode, NULL_RTX);
current_function_cannot_inline
= "function using short complex types cannot be inline";
if (packed_dest_p)
{
rtx sreg = gen_rtx_SUBREG (reg_mode, x, 0);
emit_move_insn_1 (cmem, y);
return emit_move_insn_1 (sreg, mem);
}
else
{
rtx sreg = gen_rtx_SUBREG (reg_mode, y, 0);
emit_move_insn_1 (mem, sreg);
return emit_move_insn_1 (x, cmem);
}
}
}
}
realpart_x = gen_realpart (submode, x);
realpart_y = gen_realpart (submode, y);
imagpart_x = gen_imagpart (submode, x);
imagpart_y = gen_imagpart (submode, y);
/* Show the output dies here. This is necessary for SUBREGs
of pseudos since we cannot track their lifetimes correctly;
hard regs shouldn't appear here except as return values.
We never want to emit such a clobber after reload. */
if (x != y
&& ! (reload_in_progress || reload_completed))
&& ! (reload_in_progress || reload_completed)
&& (GET_CODE (realpart_x) == SUBREG
|| GET_CODE (imagpart_x) == SUBREG))
{
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
}
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
(gen_realpart (submode, x), gen_realpart (submode, y)));
(realpart_x, realpart_y));
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
(gen_imagpart (submode, x), gen_imagpart (submode, y)));
(imagpart_x, imagpart_y));
}
return get_last_insn ();
@ -2703,6 +2764,8 @@ emit_move_insn_1 (x, y)
else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
{
rtx last_insn = 0;
rtx seq;
int need_clobber;
#ifdef PUSH_ROUNDING
@ -2715,15 +2778,9 @@ emit_move_insn_1 (x, y)
}
#endif
/* Show the output dies here. This is necessary for pseudos;
hard regs shouldn't appear here except as return values.
We never want to emit such a clobber after reload. */
if (x != y
&& ! (reload_in_progress || reload_completed))
{
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
}
start_sequence ();
need_clobber = 0;
for (i = 0;
i < (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
i++)
@ -2745,9 +2802,27 @@ emit_move_insn_1 (x, y)
if (xpart == 0 || ypart == 0)
abort ();
need_clobber |= (GET_CODE (xpart) == SUBREG);
last_insn = emit_move_insn (xpart, ypart);
}
seq = gen_sequence ();
end_sequence ();
/* Show the output dies here. This is necessary for SUBREGs
of pseudos since we cannot track their lifetimes correctly;
hard regs shouldn't appear here except as return values.
We never want to emit such a clobber after reload. */
if (x != y
&& ! (reload_in_progress || reload_completed)
&& need_clobber != 0)
{
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
}
emit_insn (seq);
return last_insn;
}
else
@ -6262,12 +6337,8 @@ expand_expr (exp, target, tmode, modifier)
}
temp = gen_rtx_MEM (mode, op0);
/* If address was computed by addition,
mark this as an element of an aggregate. */
if (TREE_CODE (exp1) == PLUS_EXPR
|| (TREE_CODE (exp1) == SAVE_EXPR
&& TREE_CODE (TREE_OPERAND (exp1, 0)) == PLUS_EXPR)
|| AGGREGATE_TYPE_P (TREE_TYPE (exp))
if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
|| (TREE_CODE (exp1) == ADDR_EXPR
&& (exp2 = TREE_OPERAND (exp1, 0))
&& AGGREGATE_TYPE_P (TREE_TYPE (exp2))))
@ -8473,44 +8544,29 @@ expand_builtin_return_addr (fndecl_code, count, tem)
return tem;
}
/* __builtin_setjmp is passed a pointer to an array of five words (not
all will be used on all machines). It operates similarly to the C
library function of the same name, but is more efficient. Much of
the code below (and for longjmp) is copied from the handling of
non-local gotos.
/* Construct the leading half of a __builtin_setjmp call. Control will
return to RECEIVER_LABEL. This is used directly by sjlj exception
handling code. */
NOTE: This is intended for use by GNAT and the exception handling
scheme in the compiler and will only work in the method used by
them. */
rtx
expand_builtin_setjmp (buf_addr, target, first_label, next_label)
void
expand_builtin_setjmp_setup (buf_addr, receiver_label)
rtx buf_addr;
rtx target;
rtx first_label, next_label;
rtx receiver_label;
{
rtx lab1 = gen_label_rtx ();
enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
enum machine_mode value_mode;
rtx stack_save;
value_mode = TYPE_MODE (integer_type_node);
#ifdef POINTERS_EXTEND_UNSIGNED
buf_addr = convert_memory_address (Pmode, buf_addr);
#endif
buf_addr = force_reg (Pmode, buf_addr);
if (target == 0 || GET_CODE (target) != REG
|| REGNO (target) < FIRST_PSEUDO_REGISTER)
target = gen_reg_rtx (value_mode);
emit_queue ();
/* We store the frame pointer and the address of lab1 in the buffer
and use the rest of it for the stack save area, which is
machine-dependent. */
/* We store the frame pointer and the address of receiver_label in
the buffer and use the rest of it for the stack save area, which
is machine-dependent. */
#ifndef BUILTIN_SETJMP_FRAME_VALUE
#define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
@ -8522,7 +8578,7 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
(gen_rtx_MEM (Pmode,
plus_constant (buf_addr,
GET_MODE_SIZE (Pmode)))),
force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
stack_save = gen_rtx_MEM (sa_mode,
plus_constant (buf_addr,
@ -8535,20 +8591,22 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
emit_insn (gen_builtin_setjmp_setup (buf_addr));
#endif
/* Set TARGET to zero and branch to the first-time-through label. */
emit_move_insn (target, const0_rtx);
emit_jump_insn (gen_jump (first_label));
emit_barrier ();
emit_label (lab1);
/* Tell flow about the strange goings on. Putting `lab1' on
`nonlocal_goto_handler_labels' to indicates that function
calls may traverse the arc back to this label. */
/* Tell optimize_save_area_alloca that extra work is going to
need to go on during alloca. */
current_function_calls_setjmp = 1;
/* Set this so all the registers get saved in our frame; we need to be
able to copy the saved values for any registers from frames we unwind. */
current_function_has_nonlocal_label = 1;
nonlocal_goto_handler_labels =
gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
}
/* Construct the trailing part of a __builtin_setjmp call.
This is used directly by sjlj exception handling code. */
void
expand_builtin_setjmp_receiver (receiver_label)
rtx receiver_label ATTRIBUTE_UNUSED;
{
/* Clobber the FP when we get here, so we have to make sure it's
marked as used by this function. */
emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
@ -8595,7 +8653,7 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
#ifdef HAVE_builtin_setjmp_receiver
if (HAVE_builtin_setjmp_receiver)
emit_insn (gen_builtin_setjmp_receiver (lab1));
emit_insn (gen_builtin_setjmp_receiver (receiver_label));
else
#endif
#ifdef HAVE_nonlocal_goto_receiver
@ -8606,12 +8664,61 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
{
; /* Nothing */
}
}
/* Set TARGET, and branch to the next-time-through label. */
emit_move_insn (target, const1_rtx);
emit_jump_insn (gen_jump (next_label));
/* __builtin_setjmp is passed a pointer to an array of five words (not
all will be used on all machines). It operates similarly to the C
library function of the same name, but is more efficient. Much of
the code below (and for longjmp) is copied from the handling of
non-local gotos.
NOTE: This is intended for use by GNAT and the exception handling
scheme in the compiler and will only work in the method used by
them. */
static rtx
expand_builtin_setjmp (arglist, target)
tree arglist;
rtx target;
{
rtx buf_addr, next_lab, cont_lab;
if (arglist == 0
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
return NULL_RTX;
if (target == 0 || GET_CODE (target) != REG
|| REGNO (target) < FIRST_PSEUDO_REGISTER)
target = gen_reg_rtx (TYPE_MODE (integer_type_node));
buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
next_lab = gen_label_rtx ();
cont_lab = gen_label_rtx ();
expand_builtin_setjmp_setup (buf_addr, next_lab);
/* Set TARGET to zero and branch to the continue label. */
emit_move_insn (target, const0_rtx);
emit_jump_insn (gen_jump (cont_lab));
emit_barrier ();
emit_label (next_lab);
expand_builtin_setjmp_receiver (next_lab);
/* Set TARGET to one. */
emit_move_insn (target, const1_rtx);
emit_label (cont_lab);
/* Tell flow about the strange goings on. Putting `next_lab' on
`nonlocal_goto_handler_labels' to indicates that function
calls may traverse the arc back to this label. */
current_function_has_nonlocal_label = 1;
nonlocal_goto_handler_labels
= gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
return target;
}
@ -9632,18 +9739,10 @@ expand_builtin (exp, target, subtarget, mode, ignore)
#endif
case BUILT_IN_SETJMP:
if (arglist == 0
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
break;
else
{
rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
VOIDmode, 0);
rtx lab = gen_label_rtx ();
rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
emit_label (lab);
return ret;
}
target = expand_builtin_setjmp (arglist, target);
if (target)
return target;
break;
/* __builtin_longjmp is passed a pointer to an array of five words.
It's similar to the C library longjmp function but works with

View File

@ -831,7 +831,8 @@ extern rtx store_expr PROTO((tree, rtx, int));
Useful after calling expand_expr with 1 as sum_ok. */
extern rtx force_operand PROTO((rtx, rtx));
extern rtx expand_builtin_setjmp PROTO((rtx, rtx, rtx, rtx));
extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
extern void expand_builtin_setjmp_receiver PARAMS ((rtx));
#ifdef TREE_CODE
/* Generate code for computing expression EXP.

View File

@ -35,7 +35,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
Sun f77, at least) so you test `__unix' rather than `unix'.
-D_LANGUAGE_FORTRAN is used by some compilers like SGI and
might as well be in there. */
{"cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
{"cpp0 -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
%{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\
@ -85,7 +85,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
%{!pipe:%g.s} %A\n }}}}"}},
{"@f77-version",
{"cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I \
{"cpp0 -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I \
%{C:%{!E:%eGNU C does not support -C without using -E}} \
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG} \
%{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2} \

View File

@ -1 +1 @@
const char *ffe_version_string = "0.5.25 19991024 (release)";
const char *ffe_version_string = "0.5.25 19991030 (prerelease)";

View File

@ -1681,7 +1681,7 @@ delete_block (b)
basic_block b;
{
int deleted_handler = 0;
rtx insn, end;
rtx insn, end, tmp;
/* If the head of this block is a CODE_LABEL, then it might be the
label for an exception handler which can't be reached.
@ -1728,11 +1728,21 @@ delete_block (b)
}
}
/* Selectively unlink the insn chain. Include any BARRIER that may
follow the basic block. */
end = next_nonnote_insn (b->end);
if (!end || GET_CODE (end) != BARRIER)
end = b->end;
/* Include any jump table following the basic block. */
end = b->end;
if (GET_CODE (end) == JUMP_INSN
&& (tmp = JUMP_LABEL (end)) != NULL_RTX
&& (tmp = NEXT_INSN (tmp)) != NULL_RTX
&& GET_CODE (tmp) == JUMP_INSN
&& (GET_CODE (PATTERN (tmp)) == ADDR_VEC
|| GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
end = tmp;
/* Include any barrier that may follow the basic block. */
tmp = next_nonnote_insn (b->end);
if (tmp && GET_CODE (tmp) == BARRIER)
end = tmp;
delete_insn_chain (insn, end);
no_delete_insns:
@ -1796,6 +1806,7 @@ flow_delete_insn (insn)
{
rtx prev = PREV_INSN (insn);
rtx next = NEXT_INSN (insn);
rtx note;
PREV_INSN (insn) = NULL_RTX;
NEXT_INSN (insn) = NULL_RTX;
@ -1815,6 +1826,10 @@ flow_delete_insn (insn)
if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
LABEL_NUSES (JUMP_LABEL (insn))--;
/* Also if deleting an insn that references a label. */
else if ((note = find_reg_note (insn, REG_LABEL, NULL_RTX)) != NULL_RTX)
LABEL_NUSES (XEXP (note, 0))--;
return next;
}
@ -2721,6 +2736,39 @@ propagate_block (old, first, last, final, significant, bnum, remove_dead_code)
can cause trouble for first or last insn in a basic block. */
if (final && insn_is_dead)
{
rtx inote;
/* If the insn referred to a label, note that the label is
now less used. */
for (inote = REG_NOTES (insn); inote; inote = XEXP (inote, 1))
{
if (REG_NOTE_KIND (inote) == REG_LABEL)
{
rtx label = XEXP (inote, 0);
rtx next;
LABEL_NUSES (label)--;
/* If this label was attached to an ADDR_VEC, it's
safe to delete the ADDR_VEC. In fact, it's pretty much
mandatory to delete it, because the ADDR_VEC may
be referencing labels that no longer exist. */
if (LABEL_NUSES (label) == 0
&& (next = next_nonnote_insn (label)) != NULL
&& GET_CODE (next) == JUMP_INSN
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
{
rtx pat = PATTERN (next);
int diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
int len = XVECLEN (pat, diff_vec_p);
int i;
for (i = 0; i < len; i++)
LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
flow_delete_insn (next);
}
}
}
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;

View File

@ -3259,8 +3259,17 @@ make_range (exp, pin_p, plow, phigh)
low = range_binop (PLUS_EXPR, type, n_high, 0,
integer_one_node, 0);
high = range_binop (MINUS_EXPR, type, n_low, 0,
integer_one_node, 0);
in_p = ! in_p;
integer_one_node, 0);
/* If the range is of the form +/- [ x+1, x ], we won't
be able to normalize it. But then, it represents the
whole range or the empty set, so make it +/- [ -, - ].
*/
if (tree_int_cst_equal (n_low, low)
&& tree_int_cst_equal (n_high, high))
low = high = 0;
else
in_p = ! in_p;
}
else
low = n_low, high = n_high;
@ -5625,7 +5634,15 @@ fold (expr)
tree newconst
= fold (build (PLUS_EXPR, TREE_TYPE (varop),
constop, TREE_OPERAND (varop, 1)));
TREE_SET_CODE (varop, PREINCREMENT_EXPR);
/* Do not overwrite the current varop to be a preincrement,
create a new node so that we won't confuse our caller who
might create trees and throw them away, reusing the
arguments that they passed to build. This shows up in
the THEN or ELSE parts of ?: being postincrements. */
varop = build (PREINCREMENT_EXPR, TREE_TYPE (varop),
TREE_OPERAND (varop, 0),
TREE_OPERAND (varop, 1));
/* If VAROP is a reference to a bitfield, we must mask
the constant by the width of the field. */
@ -5669,9 +5686,9 @@ fold (expr)
}
t = build (code, type, TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
TREE_OPERAND (t, constopnum) = newconst;
t = build (code, type,
(constopnum == 0) ? newconst : varop,
(constopnum == 1) ? newconst : varop);
return t;
}
}
@ -5684,7 +5701,15 @@ fold (expr)
tree newconst
= fold (build (MINUS_EXPR, TREE_TYPE (varop),
constop, TREE_OPERAND (varop, 1)));
TREE_SET_CODE (varop, PREDECREMENT_EXPR);
/* Do not overwrite the current varop to be a predecrement,
create a new node so that we won't confuse our caller who
might create trees and throw them away, reusing the
arguments that they passed to build. This shows up in
the THEN or ELSE parts of ?: being postdecrements. */
varop = build (PREDECREMENT_EXPR, TREE_TYPE (varop),
TREE_OPERAND (varop, 0),
TREE_OPERAND (varop, 1));
if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
&& DECL_BIT_FIELD(TREE_OPERAND
@ -5723,9 +5748,9 @@ fold (expr)
}
t = build (code, type, TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
TREE_OPERAND (t, constopnum) = newconst;
t = build (code, type,
(constopnum == 0) ? newconst : varop,
(constopnum == 1) ? newconst : varop);
return t;
}
}

View File

@ -714,6 +714,14 @@ execute_cfa_insn (void *p, struct frame_state_internal *state,
state->s.args_size = offset;
break;
case DW_CFA_GNU_negative_offset_extended:
p = decode_uleb128 (p, &reg);
p = decode_uleb128 (p, &offset);
offset *= info->data_align;
state->s.saved[reg] = REG_SAVED_OFFSET;
state->s.reg_or_offset[reg] = -offset;
break;
default:
abort ();
}

View File

@ -2773,6 +2773,7 @@ find_and_verify_loops (f)
{
rtx p;
rtx our_next = next_real_insn (insn);
rtx last_insn_to_move = NEXT_INSN (insn);
int dest_loop;
int outer_loop = -1;
@ -2824,21 +2825,39 @@ find_and_verify_loops (f)
&& INSN_UID (JUMP_LABEL (p)) != 0
&& condjump_p (p)
&& ! simplejump_p (p)
&& next_real_insn (JUMP_LABEL (p)) == our_next)
&& next_real_insn (JUMP_LABEL (p)) == our_next
/* If it's not safe to move the sequence, then we
mustn't try. */
&& insns_safe_to_move_p (p, NEXT_INSN (insn),
&last_insn_to_move))
{
rtx target
= JUMP_LABEL (insn) ? JUMP_LABEL (insn) : get_last_insn ();
int target_loop_num = uid_loop_num[INSN_UID (target)];
rtx loc;
rtx loc, loc2;
for (loc = target; loc; loc = PREV_INSN (loc))
if (GET_CODE (loc) == BARRIER
/* Don't move things inside a tablejump. */
&& ((loc2 = next_nonnote_insn (loc)) == 0
|| GET_CODE (loc2) != CODE_LABEL
|| (loc2 = next_nonnote_insn (loc2)) == 0
|| GET_CODE (loc2) != JUMP_INSN
|| (GET_CODE (PATTERN (loc2)) != ADDR_VEC
&& GET_CODE (PATTERN (loc2)) != ADDR_DIFF_VEC))
&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
break;
if (loc == 0)
for (loc = target; loc; loc = NEXT_INSN (loc))
if (GET_CODE (loc) == BARRIER
/* Don't move things inside a tablejump. */
&& ((loc2 = next_nonnote_insn (loc)) == 0
|| GET_CODE (loc2) != CODE_LABEL
|| (loc2 = next_nonnote_insn (loc2)) == 0
|| GET_CODE (loc2) != JUMP_INSN
|| (GET_CODE (PATTERN (loc2)) != ADDR_VEC
&& GET_CODE (PATTERN (loc2)) != ADDR_DIFF_VEC))
&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
break;
@ -2879,11 +2898,13 @@ find_and_verify_loops (f)
/* Include the BARRIER after INSN and copy the
block after LOC. */
new_label = squeeze_notes (new_label, NEXT_INSN (insn));
reorder_insns (new_label, NEXT_INSN (insn), loc);
new_label = squeeze_notes (new_label,
last_insn_to_move);
reorder_insns (new_label, last_insn_to_move, loc);
/* All those insns are now in TARGET_LOOP_NUM. */
for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
for (q = new_label;
q != NEXT_INSN (last_insn_to_move);
q = NEXT_INSN (q))
uid_loop_num[INSN_UID (q)] = target_loop_num;
@ -5678,6 +5699,7 @@ check_final_value (v, loop_start, loop_end, n_iterations)
or all uses follow that insn in the same basic block),
- its final value can be calculated (this condition is different
than the one above in record_giv)
- it's not used before it's set
- no assignments to the biv occur during the giv's lifetime. */
#if 0
@ -5689,7 +5711,7 @@ check_final_value (v, loop_start, loop_end, n_iterations)
if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations))
&& (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
{
int biv_increment_seen = 0;
int biv_increment_seen = 0, before_giv_insn = 0;
rtx p = v->insn;
rtx last_giv_use;
@ -5719,26 +5741,35 @@ check_final_value (v, loop_start, loop_end, n_iterations)
{
p = NEXT_INSN (p);
if (p == loop_end)
p = NEXT_INSN (loop_start);
{
before_giv_insn = 1;
p = NEXT_INSN (loop_start);
}
if (p == v->insn)
break;
if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
|| GET_CODE (p) == CALL_INSN)
{
if (biv_increment_seen)
/* It is possible for the BIV increment to use the GIV if we
have a cycle. Thus we must be sure to check each insn for
both BIV and GIV uses, and we must check for BIV uses
first. */
if (! biv_increment_seen
&& reg_set_p (v->src_reg, PATTERN (p)))
biv_increment_seen = 1;
if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
{
if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
if (biv_increment_seen || before_giv_insn)
{
v->replaceable = 0;
v->not_replaceable = 1;
break;
}
last_giv_use = p;
}
else if (reg_set_p (v->src_reg, PATTERN (p)))
biv_increment_seen = 1;
else if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
last_giv_use = p;
}
}
@ -5983,6 +6014,7 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
insn = p;
while (1)
{
rtx dest;
do {
insn = PREV_INSN (insn);
} while (insn && GET_CODE (insn) == NOTE
@ -5994,20 +6026,26 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
if (set == 0)
break;
if ((SET_DEST (set) == x
|| (GET_CODE (SET_DEST (set)) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
<= UNITS_PER_WORD)
&& (GET_MODE_CLASS (GET_MODE (SET_DEST (set)))
== MODE_INT)
&& SUBREG_REG (SET_DEST (set)) == x))
&& basic_induction_var (SET_SRC (set),
(GET_MODE (SET_SRC (set)) == VOIDmode
? GET_MODE (x)
: GET_MODE (SET_SRC (set))),
dest_reg, insn,
inc_val, mult_val, location))
return 1;
dest = SET_DEST (set);
if (dest == x
|| (GET_CODE (dest) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD)
&& (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
&& SUBREG_REG (dest) == x))
return basic_induction_var (SET_SRC (set),
(GET_MODE (SET_SRC (set)) == VOIDmode
? GET_MODE (x)
: GET_MODE (SET_SRC (set))),
dest_reg, insn,
inc_val, mult_val, location);
while (GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == ZERO_EXTRACT
|| GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (dest == x)
break;
}
/* ... fall through ... */
@ -8155,6 +8193,40 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
bl->nonneg = 1;
}
/* No insn may reference both the reversed and another biv or it
will fail (see comment near the top of the loop reversal
code).
Earlier on, we have verified that the biv has no use except
counting, or it is the only biv in this function.
However, the code that computes no_use_except_counting does
not verify reg notes. It's possible to have an insn that
references another biv, and has a REG_EQUAL note with an
expression based on the reversed biv. To avoid this case,
remove all REG_EQUAL notes based on the reversed biv
here. */
for (p = loop_start; p != loop_end; p = NEXT_INSN (p))
if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
{
rtx *pnote;
rtx set = single_set (p);
/* If this is a set of a GIV based on the reversed biv, any
REG_EQUAL notes should still be correct. */
if (! set
|| GET_CODE (SET_DEST (set)) != REG
|| (size_t) REGNO (SET_DEST (set)) >= reg_iv_type->num_elements
|| REG_IV_TYPE (REGNO (SET_DEST (set))) != GENERAL_INDUCT
|| REG_IV_INFO (REGNO (SET_DEST (set)))->src_reg != bl->biv->src_reg)
for (pnote = &REG_NOTES (p); *pnote;)
{
if (REG_NOTE_KIND (*pnote) == REG_EQUAL
&& reg_mentioned_p (regno_reg_rtx[bl->regno],
XEXP (*pnote, 0)))
*pnote = XEXP (*pnote, 1);
else
pnote = &XEXP (*pnote, 1);
}
}
/* Mark that this biv has been reversed. Each giv which depends
on this biv, and which is also live past the end of the loop
will have to be fixed up. */
@ -9314,6 +9386,7 @@ instrument_loop_bct (loop_start, loop_end, loop_num_iterations)
emit_jump_insn_before (gen_decrement_and_branch_on_count (counter_reg,
start_label),
loop_end);
JUMP_LABEL (prev_nonnote_insn (loop_end)) = start_label;
LABEL_NUSES (start_label)++;
}

View File

@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
{".m", {"@objective-c"}},
{"@objective-c",
#if USE_CPPLIB
{"%{E|M|MM:cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
{"%{E|M|MM:cpp0 -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-D__OBJC__ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\
@ -55,7 +55,7 @@ Boston, MA 02111-1307, USA. */
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
%{!pipe:%g.s} %A\n }}}}"}
#else /* ! USE_CPPLIB */
{"cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
{"cpp0 -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-D__OBJC__ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\

View File

@ -2887,8 +2887,14 @@ emit_libcall_block (insns, target, result, equiv)
rtx result;
rtx equiv;
{
rtx final_dest = target;
rtx prev, next, first, last, insn;
/* If this is a reg with REG_USERVAR_P set, then it could possibly turn
into a MEM later. Protect the libcall block from this change. */
if (! REG_P (target) || REG_USERVAR_P (target))
target = gen_reg_rtx (GET_MODE (target));
/* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
reg note to indicate that this call cannot throw. (Unless there is
already a REG_EH_REGION note.) */
@ -2952,6 +2958,9 @@ emit_libcall_block (insns, target, result, equiv)
!= CODE_FOR_nothing)
set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
if (final_dest != target)
emit_move_insn (final_dest, target);
if (prev == 0)
first = get_insns ();
else

View File

@ -296,7 +296,7 @@ extern rtx find_equiv_reg PROTO((rtx, rtx, enum reg_class, int, short *,
int, enum machine_mode));
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
extern int regno_clobbered_p PROTO((int, rtx));
extern int regno_clobbered_p PROTO((int, rtx, enum machine_mode, int));
/* Functions in reload1.c: */
@ -342,3 +342,5 @@ extern void save_call_clobbered_regs PROTO((void));
/* Replace (subreg (reg)) with the appropriate (reg) for any operands. */
extern void cleanup_subreg_operands PROTO ((rtx));
extern int earlyclobber_operand_p PROTO((rtx));

View File

@ -420,9 +420,13 @@ static void clear_reload_reg_in_use PROTO((int, int, enum reload_type,
enum machine_mode));
static int reload_reg_free_p PROTO((int, int, enum reload_type));
static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx, rtx, int, int));
static int free_for_value_p PROTO((int, enum machine_mode, int,
enum reload_type, rtx, rtx,
int, int));
static int reload_reg_reaches_end_p PROTO((int, int, enum reload_type));
static int allocate_reload_reg PROTO((struct insn_chain *, int, int,
int));
static int conflicts_with_override PROTO((rtx));
static void choose_reload_regs PROTO((struct insn_chain *));
static void merge_assigned_reloads PROTO((rtx));
static void emit_reload_insns PROTO((struct insn_chain *));
@ -4518,7 +4522,10 @@ forget_old_reloads_1 (x, ignored)
reload reg in the current instruction. */
if (n_reloads == 0
|| ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
{
CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
spill_reg_store[regno + i] = 0;
}
}
/* Since value of X has changed,
@ -4577,6 +4584,8 @@ reload_reg_class_lower (r1p, r2p)
/* The following HARD_REG_SETs indicate when each hard register is
used for a reload of various parts of the current insn. */
/* If reg is unavailable for all reloads. */
static HARD_REG_SET reload_reg_unavailable;
/* If reg is in use as a reload reg for a RELOAD_OTHER reload. */
static HARD_REG_SET reload_reg_used;
/* If reg is in use for a RELOAD_FOR_INPUT_ADDRESS reload for operand I. */
@ -4799,8 +4808,8 @@ reload_reg_free_p (regno, opnum, type)
{
int i;
/* In use for a RELOAD_OTHER means it's not available for anything. */
if (TEST_HARD_REG_BIT (reload_reg_used, regno))
if (TEST_HARD_REG_BIT (reload_reg_used, regno)
|| TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
return 0;
switch (type)
@ -5133,7 +5142,7 @@ reloads_conflict (r1, r2)
return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT
|| ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS
|| r2_type == RELOAD_FOR_OUTADDR_ADDRESS)
&& r2_opnum >= r1_opnum));
&& r2_opnum <= r1_opnum));
case RELOAD_FOR_INSN:
return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT
@ -5171,25 +5180,8 @@ rtx reload_override_in[MAX_RELOADS];
or -1 if we did not need a register for this reload. */
int reload_spill_index[MAX_RELOADS];
/* Return 1 if the value in reload reg REGNO, as used by a reload
needed for the part of the insn specified by OPNUM and TYPE,
may be used to load VALUE into it.
/* Subroutine of free_for_value_p, used to check a single register. */
Other read-only reloads with the same value do not conflict
unless OUT is non-zero and these other reloads have to live while
output reloads live.
If OUT is CONST0_RTX, this is a special case: it means that the
test should not be for using register REGNO as reload register, but
for copying from register REGNO into the reload register.
RELOADNUM is the number of the reload we want to load this value for;
a reload does not conflict with itself.
When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
reloads that load an address for the very reload we are considering.
The caller has to make sure that there is no conflict with the return
register. */
static int
reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
ignore_address_reloads)
@ -5201,6 +5193,10 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
int ignore_address_reloads;
{
int time1;
/* Set if we see an input reload that must not share its reload register
with any new earlyclobber, but might otherwise share the reload
register with an output or input-output reload. */
int check_earlyclobber = 0;
int i;
int copy = 0;
@ -5208,7 +5204,7 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
available as spill registers, including hard registers that are
earlyclobbered in asms. As a temporary measure, reject anything
in reload_reg_used. */
if (TEST_HARD_REG_BIT (reload_reg_used, regno))
if (TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
return 0;
if (out == const0_rtx)
@ -5235,7 +5231,8 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
switch (type)
{
case RELOAD_FOR_OTHER_ADDRESS:
time1 = 0;
/* RELOAD_FOR_OTHER_ADDRESS conflicts with RELOAD_OTHER reloads. */
time1 = copy ? 0 : 1;
break;
case RELOAD_OTHER:
time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5;
@ -5327,6 +5324,7 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
break;
case RELOAD_FOR_INPUT:
time2 = reload_opnum[i] * 4 + 4;
check_earlyclobber = 1;
break;
/* reload_opnum[i] * 4 + 4 <= (MAX_RECOG_OPERAND - 1) * 4 + 4
== MAX_RECOG_OPERAND * 4 */
@ -5339,6 +5337,7 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
break;
case RELOAD_FOR_OPERAND_ADDRESS:
time2 = MAX_RECOG_OPERANDS * 4 + 2;
check_earlyclobber = 1;
break;
case RELOAD_FOR_INSN:
time2 = MAX_RECOG_OPERANDS * 4 + 3;
@ -5367,6 +5366,9 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
if (! reload_in[i] || rtx_equal_p (reload_in[i], value))
{
time2 = MAX_RECOG_OPERANDS * 4 + 4;
/* Earlyclobbered outputs must conflict with inputs. */
if (earlyclobber_operand_p (reload_out[i]))
time2 = MAX_RECOG_OPERANDS * 4 + 3;
break;
}
time2 = 1;
@ -5389,9 +5391,71 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
}
}
}
/* Earlyclobbered outputs must conflict with inputs. */
if (check_earlyclobber && out && earlyclobber_operand_p (out))
return 0;
return 1;
}
/* Return 1 if the value in reload reg REGNO, as used by a reload
needed for the part of the insn specified by OPNUM and TYPE,
may be used to load VALUE into it.
MODE is the mode in which the register is used, this is needed to
determine how many hard regs to test.
Other read-only reloads with the same value do not conflict
unless OUT is non-zero and these other reloads have to live while
output reloads live.
If OUT is CONST0_RTX, this is a special case: it means that the
test should not be for using register REGNO as reload register, but
for copying from register REGNO into the reload register.
RELOADNUM is the number of the reload we want to load this value for;
a reload does not conflict with itself.
When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
reloads that load an address for the very reload we are considering.
The caller has to make sure that there is no conflict with the return
register. */
static int
free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
ignore_address_reloads)
int regno;
enum machine_mode mode;
int opnum;
enum reload_type type;
rtx value, out;
int reloadnum;
int ignore_address_reloads;
{
int nregs = HARD_REGNO_NREGS (regno, mode);
while (nregs-- > 0)
if (! reload_reg_free_for_value_p (regno + nregs, opnum, type, value, out,
reloadnum, ignore_address_reloads))
return 0;
return 1;
}
/* Determine whether the reload reg X overlaps any rtx'es used for
overriding inheritance. Return nonzero if so. */
static int
conflicts_with_override (x)
rtx x;
{
int i;
for (i = 0; i < n_reloads; i++)
if (reload_override_in[i]
&& reg_overlap_mentioned_p (x, reload_override_in[i]))
return 1;
return 0;
}
/* Find a spill register to use as a reload register for reload R.
LAST_RELOAD is non-zero if this is the last reload for the insn being
processed.
@ -5472,11 +5536,10 @@ allocate_reload_reg (chain, r, last_reload, noerror)
/* We check reload_reg_used to make sure we
don't clobber the return register. */
&& ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
&& reload_reg_free_for_value_p (regnum,
reload_opnum[r],
reload_when_needed[r],
reload_in[r],
reload_out[r], r, 1)))
&& free_for_value_p (regnum, reload_mode[r],
reload_opnum[r],
reload_when_needed[r],
reload_in[r], reload_out[r], r, 1)))
&& TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
&& HARD_REGNO_MODE_OK (regnum, reload_mode[r])
/* Look first for regs to share, then for unshared. But
@ -5669,7 +5732,7 @@ choose_reload_regs (chain)
CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
}
IOR_COMPL_HARD_REG_SET (reload_reg_used, chain->used_spill_regs);
COMPL_HARD_REG_SET (reload_reg_unavailable, chain->used_spill_regs);
#if 0 /* Not needed, now that we can always retry without inheritance. */
/* See if we have more mandatory reloads than spill regs.
@ -5931,10 +5994,9 @@ choose_reload_regs (chain)
&& (reload_nregs[r] == max_group_size
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
i))
&& reload_reg_free_for_value_p (i, reload_opnum[r],
reload_when_needed[r],
reload_in[r],
const0_rtx, r, 1))
&& free_for_value_p (i, reload_mode[r], reload_opnum[r],
reload_when_needed[r], reload_in[r],
const0_rtx, r, 1))
{
/* If a group is needed, verify that all the subsequent
registers still have their values intact. */
@ -5968,9 +6030,11 @@ choose_reload_regs (chain)
break;
if (i1 != n_earlyclobbers
|| ! (reload_reg_free_for_value_p
(i, reload_opnum[r], reload_when_needed[r],
reload_in[r], reload_out[r], r, 1))
|| ! (free_for_value_p (i, reload_mode[r],
reload_opnum[r],
reload_when_needed[r],
reload_in[r],
reload_out[r], r, 1))
/* Don't use it if we'd clobber a pseudo reg. */
|| (TEST_HARD_REG_BIT (reg_used_in_insn, i)
&& reload_out[r]
@ -5992,9 +6056,12 @@ choose_reload_regs (chain)
&& rtx_equal_p (reload_out[r],
reload_reg_rtx[r])))
{
reload_override_in[r] = last_reg;
reload_inheritance_insn[r]
= reg_reloaded_insn[i];
if (! reload_optional[r])
{
reload_override_in[r] = last_reg;
reload_inheritance_insn[r]
= reg_reloaded_insn[i];
}
}
else
{
@ -6072,10 +6139,11 @@ choose_reload_regs (chain)
and of the desired class. */
if (equiv != 0
&& ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
&& ! reload_reg_free_for_value_p (regno, reload_opnum[r],
reload_when_needed[r],
reload_in[r],
reload_out[r], r, 1))
&& ! free_for_value_p (regno, reload_mode[r],
reload_opnum[r],
reload_when_needed[r],
reload_in[r], reload_out[r], r,
1))
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
regno)))
equiv = 0;
@ -6093,7 +6161,8 @@ choose_reload_regs (chain)
if (reg_overlap_mentioned_for_reload_p (equiv,
reload_earlyclobbers[i]))
{
reload_override_in[r] = equiv;
if (! reload_optional[r])
reload_override_in[r] = equiv;
equiv = 0;
break;
}
@ -6104,7 +6173,8 @@ choose_reload_regs (chain)
In particular, we then can't use EQUIV for a
RELOAD_FOR_OUTPUT_ADDRESS reload. */
if (equiv != 0 && regno_clobbered_p (regno, insn))
if (equiv != 0 && regno_clobbered_p (regno, insn,
reload_mode[r], 0))
{
switch (reload_when_needed[r])
{
@ -6116,13 +6186,32 @@ choose_reload_regs (chain)
case RELOAD_OTHER:
case RELOAD_FOR_INPUT:
case RELOAD_FOR_OPERAND_ADDRESS:
reload_override_in[r] = equiv;
if (! reload_optional[r])
reload_override_in[r] = equiv;
/* Fall through. */
default:
equiv = 0;
break;
}
}
else if (regno_clobbered_p (regno, insn, reload_mode[r], 1))
switch (reload_when_needed[r])
{
case RELOAD_FOR_OTHER_ADDRESS:
case RELOAD_FOR_INPADDR_ADDRESS:
case RELOAD_FOR_INPUT_ADDRESS:
case RELOAD_FOR_OPADDR_ADDR:
case RELOAD_FOR_OPERAND_ADDRESS:
case RELOAD_FOR_INPUT:
break;
case RELOAD_OTHER:
if (! reload_optional[r])
reload_override_in[r] = equiv;
/* Fall through. */
default:
equiv = 0;
break;
}
/* If we found an equivalent reg, say no code need be generated
to load it, and use it as our reload reg. */
@ -6283,13 +6372,12 @@ choose_reload_regs (chain)
check_reg = reload_override_in[r];
else
continue;
if (! reload_reg_free_for_value_p (true_regnum (check_reg),
reload_opnum[r],
reload_when_needed[r],
reload_in[r],
(reload_inherited[r]
? reload_out[r] : const0_rtx),
r, 1))
if (! free_for_value_p (true_regnum (check_reg), reload_mode[r],
reload_opnum[r], reload_when_needed[r],
reload_in[r],
(reload_inherited[r]
? reload_out[r] : const0_rtx),
r, 1))
{
if (pass)
continue;
@ -6646,10 +6734,10 @@ emit_reload_insns (chain)
/* Don't use OLDEQUIV if any other reload changes it at an
earlier stage of this insn or at this stage. */
if (! reload_reg_free_for_value_p (regno, reload_opnum[j],
reload_when_needed[j],
reload_in[j], const0_rtx, j,
0))
if (! free_for_value_p (regno, reload_mode[j],
reload_opnum[j],
reload_when_needed[j],
reload_in[j], const0_rtx, j, 0))
oldequiv = 0;
/* If it is no cheaper to copy from OLDEQUIV into the
@ -6799,11 +6887,10 @@ emit_reload_insns (chain)
&& dead_or_set_p (insn, old)
/* This is unsafe if some other reload
uses the same reg first. */
&& reload_reg_free_for_value_p (REGNO (reloadreg),
reload_opnum[j],
reload_when_needed[j],
old, reload_out[j],
j, 0))
&& ! conflicts_with_override (reloadreg)
&& free_for_value_p (REGNO (reloadreg), reload_mode[j],
reload_opnum[j], reload_when_needed[j],
old, reload_out[j], j, 0))
{
rtx temp = PREV_INSN (insn);
while (temp && GET_CODE (temp) == NOTE)
@ -7112,7 +7199,8 @@ emit_reload_insns (chain)
/* We don't need to test full validity of last_regno for
inherit here; we only want to know if the store actually
matches the pseudo. */
if (reg_reloaded_contents[last_regno] == pseudo_no
if (TEST_HARD_REG_BIT (reg_reloaded_valid, last_regno)
&& reg_reloaded_contents[last_regno] == pseudo_no
&& spill_reg_store[last_regno]
&& rtx_equal_p (pseudo, spill_reg_stored_to[last_regno]))
delete_output_reload (insn, j, last_regno);
@ -7288,7 +7376,7 @@ emit_reload_insns (chain)
|| !(set = single_set (insn))
|| rtx_equal_p (old, SET_DEST (set))
|| !reg_mentioned_p (old, SET_SRC (set))
|| !regno_clobbered_p (REGNO (old), insn))
|| !regno_clobbered_p (REGNO (old), insn, reload_mode[j], 0))
gen_reload (old, reloadreg, reload_opnum[j],
reload_when_needed[j]);
}

View File

@ -1084,6 +1084,7 @@ extern int for_each_rtx PROTO((rtx *, rtx_function, void *));
extern rtx regno_use_in PROTO((int, rtx));
extern int auto_inc_p PROTO((rtx));
extern void remove_node_from_expr_list PROTO((rtx, rtx *));
extern int insns_safe_to_move_p PROTO((rtx, rtx, rtx *));
/* flow.c */

View File

@ -2289,3 +2289,82 @@ auto_inc_p (x)
}
return 0;
}
/* Return 1 if the sequence of instructions beginning with FROM and up
to and including TO is safe to move. If NEW_TO is non-NULL, and
the sequence is not already safe to move, but can be easily
extended to a sequence which is safe, then NEW_TO will point to the
end of the extended sequence.
For now, this function only checks that the region contains whole
exception regiongs, but it could be extended to check additional
conditions as well. */
int
insns_safe_to_move_p (from, to, new_to)
rtx from;
rtx to;
rtx *new_to;
{
int eh_region_count = 0;
int past_to_p = 0;
rtx r = from;
/* By default, assume the end of the region will be what was
suggested. */
if (new_to)
*new_to = to;
while (r)
{
if (GET_CODE (r) == NOTE)
{
switch (NOTE_LINE_NUMBER (r))
{
case NOTE_INSN_EH_REGION_BEG:
++eh_region_count;
break;
case NOTE_INSN_EH_REGION_END:
if (eh_region_count == 0)
/* This sequence of instructions contains the end of
an exception region, but not he beginning. Moving
it will cause chaos. */
return 0;
--eh_region_count;
break;
default:
break;
}
}
else if (past_to_p)
/* If we've passed TO, and we see a non-note instruction, we
can't extend the sequence to a movable sequence. */
return 0;
if (r == to)
{
if (!new_to)
/* It's OK to move the sequence if there were matched sets of
exception region notes. */
return eh_region_count == 0;
past_to_p = 1;
}
/* It's OK to move the sequence if there were matched sets of
exception region notes. */
if (past_to_p && eh_region_count == 0)
{
*new_to = r;
return 1;
}
/* Go to the next instruction. */
r = NEXT_INSN (r);
}
return 0;
}

View File

@ -1351,7 +1351,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
}
else
{
output_rtx[i] = assign_temp (type, 0, 0, 0);
output_rtx[i] = assign_temp (type, 0, 0, 1);
TREE_VALUE (tail) = make_tree (type, output_rtx[i]);
}

View File

@ -1 +1 @@
char *version_string = "2.95.2 19991024 (release)";
char *version_string = "2.95.3 20010101 (prerelease)";