aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2001-12-05 01:39:41 +0000
committerAndrew Macleod <amacleod@gcc.gnu.org>2001-12-05 01:39:41 +0000
commit0626ef8add9823d3f8714e3a00d6372ba4f4ff4a (patch)
treec7ac63b712fa3bf7681fd15b7941fa3e71cdc688
parentee0a48c5e8998fba3a4050c77794ef234793a1d2 (diff)
downloadgcc-0626ef8add9823d3f8714e3a00d6372ba4f4ff4a.zip
gcc-0626ef8add9823d3f8714e3a00d6372ba4f4ff4a.tar.gz
gcc-0626ef8add9823d3f8714e3a00d6372ba4f4ff4a.tar.bz2
rtl.h (initialize_uninitialized_subregs): New prototype.
2001-12-04 Andrew MacLeod <amacleod@redhat.com> * 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. From-SVN: r47644
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/flow.c108
-rw-r--r--gcc/rtl.h7
-rw-r--r--gcc/toplev.c11
4 files changed, 132 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7996d8b..b390614 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2001-12-04 Andrew MacLeod <amacleod@redhat.com>
+
+ * 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.
+
2001-12-04 Phil Edwards <pme@gcc.gnu.org>
* Makefile.in: Add INSTALL_SCRIPT using INSTALL definition.
diff --git a/gcc/flow.c b/gcc/flow.c
index fdf4df2..cf7d4a0 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -306,6 +306,8 @@ static void mark_set_regs PARAMS ((struct propagate_block_info *,
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));
@@ -1290,6 +1292,112 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
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, &param);
+ 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. */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index baafcdc..b76376a 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1903,10 +1903,11 @@ extern void move_by_pieces PARAMS ((rtx, rtx,
unsigned int));
/* In flow.c */
-extern void recompute_reg_usage PARAMS ((rtx, int));
+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 *));
+extern void print_rtl_with_bb PARAMS ((FILE *, rtx));
+extern void dump_flow_info PARAMS ((FILE *));
#endif
/* In expmed.c */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 54582dc..fc2e8b6 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -3017,6 +3017,17 @@ rest_of_compilation (decl)
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 | PROP_DEATH_NOTES));
+ }
+ }
+
close_dump_file (DFI_life, print_rtl_with_bb, insns);
ggc_collect ();