This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patches] Re: ARM libstdc++ failure fix
Hi,
here is the updated version. I am starting the ppc testing.
It contains updated comment about the abort at code label hopefully
explaining about what is going on.
Sun Jul 29 22:27:06 CEST 2001 Jan Hubicka <jh@suse.cz>
* rtlanal.c (parms_set, find_first_parameter_load): Break out from...;
handle multiple sets.
* except.c (sjlj_mark_call_sites): .... here.
* gcse.c (insert_insn_end_bb): Use find_first_parameter_load.
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.176
diff -c -3 -p -r1.176 except.c
*** except.c 2001/07/29 17:01:52 1.176
--- except.c 2001/07/29 20:25:32
*************** sjlj_mark_call_sites (lp_info)
*** 2083,2133 ****
/* Don't separate a call from it's argument loads. */
before = insn;
if (GET_CODE (insn) == CALL_INSN)
! {
! HARD_REG_SET parm_regs;
! int nparm_regs;
!
! /* Since different machines initialize their parameter registers
! in different orders, assume nothing. Collect the set of all
! parameter registers. */
! CLEAR_HARD_REG_SET (parm_regs);
! nparm_regs = 0;
! for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
! if (GET_CODE (XEXP (p, 0)) == USE
! && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
! {
! if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
! abort ();
!
! /* We only care about registers which can hold function
! arguments. */
! if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
! continue;
!
! SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0)));
! nparm_regs++;
! }
!
! /* Search backward for the first set of a register in this set. */
! while (nparm_regs)
! {
! before = PREV_INSN (before);
!
! /* Given that we've done no other optimizations yet,
! the arguments should be immediately available. */
! if (GET_CODE (before) == CODE_LABEL)
! abort ();
!
! p = single_set (before);
! if (p && GET_CODE (SET_DEST (p)) == REG
! && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
! && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
! {
! CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
! nparm_regs--;
! }
! }
! }
start_sequence ();
emit_move_insn (mem, GEN_INT (this_call_site));
--- 2083,2089 ----
/* Don't separate a call from it's argument loads. */
before = insn;
if (GET_CODE (insn) == CALL_INSN)
! before = find_first_parameter_load (insn, NULL_RTX);
start_sequence ();
emit_move_insn (mem, GEN_INT (this_call_site));
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcse.c,v
retrieving revision 1.140
diff -c -3 -p -r1.140 gcse.c
*** gcse.c 2001/07/23 21:35:26 1.140
--- gcse.c 2001/07/29 20:25:33
*************** insert_insn_end_bb (expr, bb, pre)
*** 4649,4686 ****
/* Since different machines initialize their parameter registers
in different orders, assume nothing. Collect the set of all
parameter registers. */
! CLEAR_HARD_REG_SET (parm_regs);
! nparm_regs = 0;
! for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
! if (GET_CODE (XEXP (p, 0)) == USE
! && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
! {
! if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
! abort ();
- /* We only care about registers which can hold function
- arguments. */
- if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
- continue;
-
- SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0)));
- nparm_regs++;
- }
-
- /* Search backward for the first set of a register in this set. */
- while (nparm_regs && bb->head != insn)
- {
- insn = PREV_INSN (insn);
- p = single_set (insn);
- if (p && GET_CODE (SET_DEST (p)) == REG
- && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
- && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
- {
- CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
- nparm_regs--;
- }
- }
-
/* If we found all the parameter loads, then we want to insert
before the first parameter load.
--- 4649,4656 ----
/* Since different machines initialize their parameter registers
in different orders, assume nothing. Collect the set of all
parameter registers. */
! insn = find_first_parameter_load (insn, bb->head);
/* If we found all the parameter loads, then we want to insert
before the first parameter load.
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.281
diff -c -3 -p -r1.281 rtl.h
*** rtl.h 2001/07/29 19:44:42 1.281
--- rtl.h 2001/07/29 20:25:34
*************** extern int auto_inc_p PARAMS ((rtx));
*** 1432,1437 ****
--- 1432,1438 ----
extern void remove_node_from_expr_list PARAMS ((rtx, rtx *));
extern int insns_safe_to_move_p PARAMS ((rtx, rtx, rtx *));
extern int loc_mentioned_in_p PARAMS ((rtx *, rtx));
+ extern rtx find_first_parameter_load PARAMS ((rtx, rtx));
/* flow.c */
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtlanal.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 rtlanal.c
*** rtlanal.c 2001/07/29 19:44:42 1.103
--- rtlanal.c 2001/07/29 20:25:35
*************** static void set_of_1 PARAMS ((rtx, rtx,
*** 31,36 ****
--- 31,37 ----
static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
static int computed_jump_p_1 PARAMS ((rtx));
static int operand_preference PARAMS ((rtx));
+ static void parms_set PARAMS ((rtx, rtx, void *));
/* Bit flags that specify the machine subtype we are compiling for.
Bits are tested using macros TARGET_... defined in the tm.h file
*************** subreg_regno (x)
*** 2787,2790 ****
--- 2788,2864 ----
GET_MODE (x));
return ret;
+ }
+ struct parms_set_data
+ {
+ int nregs;
+ HARD_REG_SET regs;
+ };
+
+ /* Helper function for noticing stores to parameter registers. */
+ static void
+ parms_set (x, pat, data)
+ rtx x, pat ATTRIBUTE_UNUSED;
+ void *data;
+ {
+ struct parms_set_data *d = data;
+ if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
+ && TEST_HARD_REG_BIT (d->regs, REGNO (x)))
+ {
+ CLEAR_HARD_REG_BIT (d->regs, REGNO (x));
+ d->nregs--;
+ }
+ }
+
+ /* Look backward for first parameter to be loaded.
+ Do not skip BOUNDARY. */
+ rtx
+ find_first_parameter_load (call_insn, boundary)
+ rtx call_insn, boundary;
+ {
+ struct parms_set_data parm;
+ rtx p, before;
+
+ /* Since different machines initialize their parameter registers
+ in different orders, assume nothing. Collect the set of all
+ parameter registers. */
+ CLEAR_HARD_REG_SET (parm.regs);
+ parm.nregs = 0;
+ for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
+ if (GET_CODE (XEXP (p, 0)) == USE
+ && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
+ {
+ if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
+ abort ();
+
+ /* We only care about registers which can hold function
+ arguments. */
+ if (!FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
+ continue;
+
+ SET_HARD_REG_BIT (parm.regs, REGNO (XEXP (XEXP (p, 0), 0)));
+ parm.nregs++;
+ }
+ before = call_insn;
+
+ /* Search backward for the first set of a register in this set. */
+ while (parm.nregs && before != boundary)
+ {
+ before = PREV_INSN (before);
+
+ /* It is possible that some loads got CSEed from one call to
+ another. Stop in that case. */
+ if (GET_CODE (before) == CALL_INSN)
+ break;
+
+ /* Our caller needs eighter ensure, that we will find all sets
+ (in case code has not been optimized yet), or take care
+ for possible labels in a way by setting boundary to preceeding
+ CODE_LABEL. */
+ if (GET_CODE (before) == CODE_LABEL && before != boundary)
+ abort ();
+
+ note_stores (PATTERN (before), parms_set, &parm);
+ }
+ return before;
}