Another NaT bit propagation bug.
Andrew Macleod
amacleod@cygnus.com
Sun Nov 4 22:53:00 GMT 2001
>> > >> life.c?
>> >
>> > OK, I can create it.
>>
>> Ug. I actaully meant flow.c, with the existing life routines.
doh. easily fixed.
>> > Anyway, thats the logic I used to insert it at the beginning. Should
>> > I change that? Or is this sufficient for now?
>>
>> Sufficient for now.
cool.
>> > * toplev.c (rest_of_compilation): Call initialize_uninitialized_subregs
>> > when optimization is on.
>>
>> Eh? Isn't this a correctness issue for ia64? I.e. it
>> should happen with no optimization a well?
Yes, its a correctness issue. However, without optimization, every case I look
at (or construct) either uses a register which is loaded from memory first and
then manipulated, or the value is stored directly to memory. It doesn't *appear*
to be an issue without optimization. Not that I've found yet anyway.
Anyway, here's the flow.c version :-) Its running now...
* rtl.h (initialize_uninitialized_subregs): New prototype.
* toplev.c (rest_of_compilation): Call initialize_uninitialized_subregs
when optimization is on.
* flow.c (find_regno_partial): Find subregs within an expression.
(initialize_uninitialized_subregs): Initialize live on entry registers
which are used in subreg expressions.
Index: gcc/rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.309
diff -c -p -r1.309 rtl.h
*** rtl.h 2001/10/25 12:55:16 1.309
--- rtl.h 2001/11/16 15:00:58
*************** extern void move_by_pieces PARAMS ((rtx
*** 1892,1901 ****
unsigned int));
/* In flow.c */
! extern void recompute_reg_usage PARAMS ((rtx, int));
#ifdef BUFSIZ
! extern void print_rtl_with_bb PARAMS ((FILE *, rtx));
! extern void dump_flow_info PARAMS ((FILE *));
#endif
/* In expmed.c */
--- 1892,1902 ----
unsigned int));
/* In flow.c */
! extern void recompute_reg_usage PARAMS ((rtx, int));
! extern int initialize_uninitialized_subregs PARAMS ((void));
#ifdef BUFSIZ
! extern void print_rtl_with_bb PARAMS ((FILE *, rtx));
! extern void dump_flow_info PARAMS ((FILE *));
#endif
/* In expmed.c */
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.525
diff -c -p -r1.525 toplev.c
*** toplev.c 2001/10/23 13:34:23 1.525
--- toplev.c 2001/11/16 15:01:03
*************** rest_of_compilation (decl)
*** 3280,3285 ****
--- 3280,3296 ----
setjmp_args_warning ();
}
+ if (optimize)
+ {
+ if (initialize_uninitialized_subregs ())
+ {
+ /* Insns were inserted, so things might look a bit different. */
+ insns = get_insns();
+ life_analysis (insns, rtl_dump_file,
+ (PROP_LOG_LINKS | PROP_REG_INFO));
+ }
+ }
+
close_dump_file (DFI_life, print_rtl_with_bb, insns);
ggc_collect ();
Index: gcc/flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.486
diff -c -p -r1.486 flow.c
*** flow.c 2001/10/22 07:09:53 1.486
--- flow.c 2001/11/16 15:01:07
*************** static void mark_set_regs PARAMS ((stru
*** 306,311 ****
--- 306,313 ----
static void mark_set_1 PARAMS ((struct propagate_block_info *,
enum rtx_code, rtx, rtx,
rtx, int));
+ static int find_regno_partial PARAMS ((rtx *, void *));
+
#ifdef HAVE_conditional_execution
static int mark_regno_cond_dead PARAMS ((struct propagate_block_info *,
int, rtx));
*************** calculate_global_regs_live (blocks_in, b
*** 1291,1296 ****
--- 1293,1404 ----
free (queue);
}
+
+
+ /* This structure is used to pass parameters to an from the
+ the function find_regno_partial(). It is used to pass in the
+ register number we are looking, as well as to return any rtx
+ we find. */
+
+ typedef struct {
+ unsigned regno_to_find;
+ rtx retval;
+ } find_regno_partial_param;
+
+
+ /* Find the rtx for the reg numbers specified in 'data' if it is
+ part of an expression which only uses part of the register. Return
+ it in the structure passed in. */
+ static int
+ find_regno_partial (ptr, data)
+ rtx *ptr;
+ void *data;
+ {
+ find_regno_partial_param *param = (find_regno_partial_param *)data;
+ unsigned reg = param->regno_to_find;
+ param->retval = NULL_RTX;
+
+ if (*ptr == NULL_RTX)
+ return 0;
+
+ switch (GET_CODE (*ptr))
+ {
+ case ZERO_EXTRACT:
+ case SIGN_EXTRACT:
+ case STRICT_LOW_PART:
+ if (GET_CODE (XEXP (*ptr, 0)) == REG && REGNO (XEXP (*ptr, 0)) == reg)
+ {
+ param->retval = *ptr;
+ return 1;
+ }
+ break;
+
+ case SUBREG:
+ if (GET_CODE (SUBREG_REG (*ptr)) == REG
+ && REGNO (SUBREG_REG (*ptr)) == reg)
+ {
+ param->retval = *ptr;
+ return 1;
+ }
+ break;
+ }
+
+ return 0;
+ }
+
+ /* Process all immediate successors of the entry block looking for pseudo
+ registers which are live on entry. Find all of those whose first
+ instance is a partial register reference of some kind, and initialize
+ them to 0 after the entry block. This will prevent bit sets within
+ registers whose value is unknown, and may contain some kind of sticky
+ bits we don't want. */
+
+ int
+ initialize_uninitialized_subregs ()
+ {
+ rtx insn;
+ edge e;
+ int reg, did_something = 0;
+ find_regno_partial_param param;
+
+ for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ {
+ basic_block bb = e->dest;
+ regset map = bb->global_live_at_start;
+ EXECUTE_IF_SET_IN_REG_SET (map,
+ FIRST_PSEUDO_REGISTER, reg,
+ {
+ int uid = REGNO_FIRST_UID (reg);
+ rtx i;
+
+ /* Find an insn which mentions the register we are looking for.
+ Its preferable to have an instance of the register's rtl since
+ there may be various flags set which we need to duplicate.
+ If we can't find it, its probably an automatic whose initial
+ value doesnt matter, or hopefully something we dont care about. */
+ for (i = get_insns (); i && INSN_UID (i) != uid; i = NEXT_INSN (i))
+ ;
+ if (i != NULL_RTX)
+ {
+ /* Found the insn, now get the REG rtx, if we can. */
+ param.regno_to_find = reg;
+ for_each_rtx (&i, find_regno_partial, ¶m);
+ if (param.retval != NULL_RTX)
+ {
+ insn = gen_move_insn (param.retval,
+ CONST0_RTX (GET_MODE (param.retval)));
+ insert_insn_on_edge (insn, e);
+ did_something = 1;
+ }
+ }
+ });
+ }
+
+ if (did_something)
+ commit_edge_insertions ();
+ return did_something;
+ }
+
/* Subroutines of life analysis. */
More information about the Gcc-bugs
mailing list