]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rtl.h (initialize_uninitialized_subregs): New prototype.
authorAndrew MacLeod <amacleod@redhat.com>
Wed, 5 Dec 2001 01:39:41 +0000 (01:39 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Wed, 5 Dec 2001 01:39:41 +0000 (01:39 +0000)
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

gcc/ChangeLog
gcc/flow.c
gcc/rtl.h
gcc/toplev.c

index 7996d8b354b3a0d1ea5a5d3d9b06fae7d404033d..b39061469319309b6fdefc25b30505ed62ae8477 100644 (file)
@@ -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.
index fdf4df29b1be13b183dc92f05b340868f703adfa..cf7d4a0fda8f0ff9d99cd185653e668d29628543 100644 (file)
@@ -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);
 }
+
+\f
+/* 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;
+}
+
 \f
 /* Subroutines of life analysis.  */
 
index baafcdce2b50ac238b842c213ee54768030cb51f..b76376ac5c61331eb201c4c77b04cf1369dabbc8 100644 (file)
--- 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 */
index 54582dc4784042bd6cf7fd9d4f97296ddff03106..fc2e8b6cdabb69d4442385af47e5c32b93d00282 100644 (file)
@@ -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 ();