OSDN Git Service

2006-01-27 Daniel Berlin <dberlin@dberlin.org>
authorzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Jan 2006 22:23:32 +0000 (22:23 +0000)
committerzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Jan 2006 22:23:32 +0000 (22:23 +0000)
    Kenneth Zadeck <zadeck@naturalbridge.com>

PR rtl-optimization/24762
* doc/tm.texi: Added TARGET_EXTRA_LIVE_ON_ENTRY.
* targhooks.c (hook_void_bitmap): New hook prototype.
* targhoohs.h (hook_void_bitmap): Ditto.
* bitmap.h (bitmap_head_def): Moved to coretypes.h.
* coretypes.h (bitmap_head_def): Moved from bitmap.h.
* target.h (live_on_entry): New function pointer.
* df-scan.c (df_all_hard_regs): Removed.
(df_scan_dump, df_hard_reg_init): Removed df_all_hard_regs.
(df_scan_free_internal): Added df->entry_block_defs.
(df_scan_alloc): Ditto.
(df_scan_dump): Ditto.
(df_uses_record): Plumbed flag field properly thru calls.
Record EH_RETURN_DATA_REGNO in eh blocks unconditionally.
This part fixes PR24762.
(df_bb_refs_record): Added code to make the frame and arg
pointers live in EH blocks.
(df_refs_record): Added call to df_record_entry_block_defs.
(df_record_entry_block_defs): New function.
* df-core.c: Added comments to describe new artifical defs.
* df.h (DF_REF_DIES_AFTER_THIS_USE): New flag in enum df_ref_flags.
(entry_block_defs): New field in struct df.
(df_all_hard_regs): Deleted.
* target-def.h: Added TARGET_EXTRA_LIVE_ON_ENTRY.
* df-problems.c (df_ru_bb_local_compute_process_def):
Added code to handle artifical defs in the entry to a function.
(df_ru_bb_local_compute): Ditto.
(df_rd_bb_local_compute_process_def):  Ditto.
(df_rd_bb_local_compute): Ditto.
(df_lr_bb_local_compute): Ditto.
(df_ur_bb_local_compute): Ditto.
(df_urec_bb_local_compute):  Ditto.
(df_chain_create_bb):  Ditto.
(df_ur_local_finalize): Removed entry.
(df_urec_init): Ditto.
(df_urec_local_finalize): Ditto.
(df_ri_bb_compute): Added detection of last use of pseudos.
* Makefile.in (df-scan.o): Updated dependencies.
* config/mips/mips-protos.h (mips_set_live_on_entry): Added.
* config/mips/mips.c (mips_set_live_on_entry): Added.
* config/mips/mips.c (TARGET_EXTRA_LIVE_ON_ENTRY): Added value
for target hook.
* dce.c (marked_insn_p): Added code to handle artifical defs.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110312 138bc75d-0d04-0410-961f-82ee72b054a4

15 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/bitmap.h
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/coretypes.h
gcc/df-core.c
gcc/df-problems.c
gcc/df-scan.c
gcc/df.h
gcc/doc/tm.texi
gcc/target-def.h
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h

index 7990d2f..867b674 100644 (file)
@@ -1,3 +1,50 @@
+2006-01-27  Daniel Berlin  <dberlin@dberlin.org>
+           Kenneth Zadeck <zadeck@naturalbridge.com>
+
+       PR rtl-optimization/24762 
+       * doc/tm.texi: Added TARGET_EXTRA_LIVE_ON_ENTRY.
+       * targhooks.c (hook_void_bitmap): New hook prototype.
+       * targhoohs.h (hook_void_bitmap): Ditto.
+       * bitmap.h (bitmap_head_def): Moved to coretypes.h.
+       * coretypes.h (bitmap_head_def): Moved from bitmap.h.
+       * target.h (live_on_entry): New function pointer.
+       * df-scan.c (df_all_hard_regs): Removed.
+       (df_scan_dump, df_hard_reg_init): Removed df_all_hard_regs.
+       (df_scan_free_internal): Added df->entry_block_defs.
+       (df_scan_alloc): Ditto.
+       (df_scan_dump): Ditto.
+       (df_uses_record): Plumbed flag field properly thru calls.
+       Record EH_RETURN_DATA_REGNO in eh blocks unconditionally.
+       This part fixes PR24762.
+       (df_bb_refs_record): Added code to make the frame and arg
+       pointers live in EH blocks.
+       (df_refs_record): Added call to df_record_entry_block_defs.
+       (df_record_entry_block_defs): New function.
+       * df-core.c: Added comments to describe new artifical defs.
+       * df.h (DF_REF_DIES_AFTER_THIS_USE): New flag in enum df_ref_flags.
+       (entry_block_defs): New field in struct df.
+       (df_all_hard_regs): Deleted.
+       * target-def.h: Added TARGET_EXTRA_LIVE_ON_ENTRY.
+       * df-problems.c (df_ru_bb_local_compute_process_def):
+       Added code to handle artifical defs in the entry to a function.
+       (df_ru_bb_local_compute): Ditto.
+       (df_rd_bb_local_compute_process_def):  Ditto.
+       (df_rd_bb_local_compute): Ditto.
+       (df_lr_bb_local_compute): Ditto.
+       (df_ur_bb_local_compute): Ditto.
+       (df_urec_bb_local_compute):  Ditto.
+       (df_chain_create_bb):  Ditto.
+       (df_ur_local_finalize): Removed entry.
+       (df_urec_init): Ditto.
+       (df_urec_local_finalize): Ditto.
+       (df_ri_bb_compute): Added detection of last use of pseudos.
+       * Makefile.in (df-scan.o): Updated dependencies.
+       * config/mips/mips-protos.h (mips_set_live_on_entry): Added.
+       * config/mips/mips.c (mips_set_live_on_entry): Added.
+       * config/mips/mips.c (TARGET_EXTRA_LIVE_ON_ENTRY): Added value
+       for target hook.
+       * dce.c (marked_insn_p): Added code to handle artifical defs.
+
 2006-01-27  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/emmintrin.h (_mm_cvtsd_f64): Add missing Intel
index 257fc6a..e28677c 100644 (file)
@@ -2337,9 +2337,9 @@ df-problems.o : df-problems.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) \
    $(FLAGS_H) output.h
 df-scan.o : df-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
-   insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h hard-reg-set.h \
-   $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) $(FLAGS_H) \
-   output.h
+   insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
+   hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) \
+   $(FLAGS_H) $(TARGET_H) $(TARGET_DEF_H) $(TREE_H) output.h tree-pass.h 
 var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \
    $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
index fb56e4e..216616d 100644 (file)
@@ -77,8 +77,6 @@ typedef struct bitmap_head_def GTY(()) {
 } bitmap_head;
 
 
-typedef struct bitmap_head_def *bitmap;
-
 /* Global data */
 extern bitmap_element bitmap_zero_bits;        /* Zero bitmap element */
 extern bitmap_obstack bitmap_default_obstack;   /* Default bitmap obstack */
index 9481b08..59dbc64 100644 (file)
@@ -119,6 +119,7 @@ extern bool mips_legitimate_address_p (enum machine_mode, rtx, int);
 extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
 extern bool mips_legitimize_address (rtx *, enum machine_mode);
 extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
+extern void mips_set_live_on_entry (void *);
 
 extern int m16_uimm3_b (rtx, enum machine_mode);
 extern int m16_simm4_1 (rtx, enum machine_mode);
index 5a655f6..fea14a7 100644 (file)
@@ -56,6 +56,7 @@ Boston, MA 02110-1301, USA.  */
 #include "cfglayout.h"
 #include "sched-int.h"
 #include "tree-gimple.h"
+#include "bitmap.h"
 
 /* True if X is an unspec wrapper around a SYMBOL_REF or LABEL_REF.  */
 #define UNSPEC_ADDRESS_P(X)                                    \
@@ -407,6 +408,7 @@ static rtx mips_expand_builtin_compare (enum mips_builtin_type,
                                        rtx, tree);
 static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
 static void mips_encode_section_info (tree, rtx, int);
+static void mips_extra_live_on_entry (bitmap);
 
 /* Structure to be filled in by compute_frame_size with register
    save masks, and offsets for the current function.  */
@@ -1160,6 +1162,12 @@ static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE mips_attribute_table
 
+#undef TARGET_EXTRA_LIVE_ON_ENTRY
+/* With -mabicalls (which is the default on GNU/Linux),
+   PIC_FUNCTION_ADDR_REGNUM is live on function entry and is to
+   initialize $28, which is PIC_OFFSET_TABLE_REGNUM.  */
+#define TARGET_EXTRA_LIVE_ON_ENTRY mips_extra_live_on_entry
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF.  */
@@ -10764,5 +10772,16 @@ mips_encode_section_info (tree decl, rtx rtl, int first)
       SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL;
     }
 }
+
+/* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  TARGET_ABICALLS makes
+   PIC_FUNCTION_ADDR_REGNUM live on entry to a function.  */
+
+static void
+mips_extra_live_on_entry (bitmap regs)
+{
+  if (!TARGET_ABICALLS)
+    bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);
+}
+
 \f
 #include "gt-mips.h"
index 7942459..6173bd8 100644 (file)
@@ -37,6 +37,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 
 #ifndef USED_FOR_TARGET
 
+struct bitmap_head_def;
+typedef struct bitmap_head_def *bitmap;
 struct rtx_def;
 typedef struct rtx_def *rtx;
 struct rtvec_def;
index a0ed23c..416406b 100644 (file)
@@ -205,18 +205,23 @@ There are 4 ways to obtain access to refs:
    defs and uses are only there if DF_HARD_REGS was specified when the
    df instance was created.
  
-   Artificial defs and uses occur at the beginning blocks that are the
-   destination of eh edges.  The defs come from the registers
-   specified in EH_RETURN_DATA_REGNO and the uses come from the
-   registers specified in ED_USES.  Logically these defs and uses
-   should really occur along the eh edge, but there is no convienent
-   way to do this.  Artificial edges that occur at the beginning of
-   the block have the DF_REF_AT_TOP flag set.
-   
-   Artificial uses also occur at the end of all blocks.  These arise
-   from the hard registers that are always live, such as the stack
-   register and are put there to keep the code from forgetting about
-   them.
+   Artificial defs and uses occur both at the beginning and ends of blocks.
+
+     For blocks that area at the destination of eh edges, the
+     artificial uses and defs occur at the beginning.  The defs relate
+     to the registers specified in EH_RETURN_DATA_REGNO and the uses
+     relate to the registers specified in ED_USES.  Logically these
+     defs and uses should really occur along the eh edge, but there is
+     no convenient way to do this.  Artificial edges that occur at the
+     beginning of the block have the DF_REF_AT_TOP flag set.
+
+     Artificial uses occur at the end of all blocks.  These arise from
+     the hard registers that are always live, such as the stack
+     register and are put there to keep the code from forgetting about
+     them.
+
+     Artifical defs occur at the end of the entry block.  These arise
+     from registers that are live at entry to the function.
 
 2) All of the uses and defs associated with each pseudo or hard
    register are linked in a bidirectional chain.  These are called
index fdba180..2d3fc10 100644 (file)
@@ -298,7 +298,7 @@ struct df_ru_problem_data
   unsigned int use_sites_size;  /* Size of use_sites.  */
   /* The set of defs to regs invalidated by call.  */
   bitmap sparse_invalidated_by_call;  
-  /* The set of defs to regs invalidate by call for ru.  */  
+  /* The set of defs to regs invalidated by call for ru.  */  
   bitmap dense_invalidated_by_call;   
 };
 
@@ -429,37 +429,41 @@ df_ru_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
 static void
 df_ru_bb_local_compute_process_def (struct dataflow *dflow,
                                    struct df_ru_bb_info *bb_info, 
-                                   struct df_ref *def)
+                                   struct df_ref *def,
+                                   enum df_ref_flags top_flag)
 {
   struct df *df = dflow->df;
   while (def)
     {
-      unsigned int regno = DF_REF_REGNO (def);
-      unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
-      unsigned int n_uses = DF_REG_USE_GET (df, regno)->n_refs;
-      if (!bitmap_bit_p (seen_in_block, regno))
+      if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
        {
-         /* The first def for regno, causes the kill info to be
-            generated and the gen information to cleared.  */
-         if (!bitmap_bit_p (seen_in_insn, regno))
+         unsigned int regno = DF_REF_REGNO (def);
+         unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
+         unsigned int n_uses = DF_REG_USE_GET (df, regno)->n_refs;
+         if (!bitmap_bit_p (seen_in_block, regno))
            {
-             if (n_uses > DF_SPARSE_THRESHOLD)
-               {
-                 bitmap_set_bit (bb_info->sparse_kill, regno);
-                 bitmap_clear_range (bb_info->gen, begin, n_uses);
-               }
-             else
+             /* The first def for regno, causes the kill info to be
+                generated and the gen information to cleared.  */
+             if (!bitmap_bit_p (seen_in_insn, regno))
                {
-                 struct df_ru_problem_data *problem_data =
-                   (struct df_ru_problem_data *) dflow->problem_data;
-                 bitmap uses = 
-                   df_ref_bitmap (problem_data->use_sites, regno, 
-                                  begin, n_uses);
-                 bitmap_ior_into (bb_info->kill, uses);
-                 bitmap_and_compl_into (bb_info->gen, uses);
+                 if (n_uses > DF_SPARSE_THRESHOLD)
+                   {
+                     bitmap_set_bit (bb_info->sparse_kill, regno);
+                     bitmap_clear_range (bb_info->gen, begin, n_uses);
+                   }
+                 else
+                   {
+                     struct df_ru_problem_data * problem_data =
+                       (struct df_ru_problem_data *)dflow->problem_data;
+                     bitmap uses = 
+                       df_ref_bitmap (problem_data->use_sites, regno, 
+                                      begin, n_uses);
+                     bitmap_ior_into (bb_info->kill, uses);
+                     bitmap_and_compl_into (bb_info->gen, uses);
+                   }
                }
+             bitmap_set_bit (seen_in_insn, regno);
            }
-         bitmap_set_bit (seen_in_insn, regno);
        }
       def = def->next_ref;
     }
@@ -508,11 +512,9 @@ df_ru_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
                                      df_get_artificial_uses (df, bb_index),
                                      DF_REF_AT_TOP);
 #endif
-
-  /* Process the artificial defs first since these are at the top of
-     the block.  */
   df_ru_bb_local_compute_process_def (dflow, bb_info, 
-                                     df_get_artificial_defs (df, bb_index));
+                                     df_get_artificial_defs (df, bb_index),
+                                     DF_REF_AT_TOP);
 
   FOR_BB_INSNS (bb, insn)
     {
@@ -521,7 +523,7 @@ df_ru_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
        continue;
 
       df_ru_bb_local_compute_process_def (dflow, bb_info, 
-                                         DF_INSN_UID_GET (df, uid)->defs);
+                                         DF_INSN_UID_GET (df, uid)->defs, 0);
 
       /* The use processing must happen after the defs processing even
         though the uses logically happen first since the defs clear
@@ -537,6 +539,9 @@ df_ru_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
   /* Process the hardware registers that are always live.  */
   df_ru_bb_local_compute_process_use (bb_info, 
                                      df_get_artificial_uses (df, bb_index), 0);
+
+  df_ru_bb_local_compute_process_def (dflow, bb_info, 
+                                     df_get_artificial_defs (df, bb_index), 0);
 }
 
 
@@ -948,45 +953,49 @@ df_rd_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
 static void
 df_rd_bb_local_compute_process_def (struct dataflow *dflow,
                                    struct df_rd_bb_info *bb_info, 
-                                   struct df_ref *def)
+                                   struct df_ref *def,
+                                   enum df_ref_flags top_flag)
 {
   struct df *df = dflow->df;
   while (def)
     {
-      unsigned int regno = DF_REF_REGNO (def);
-      unsigned int begin = DF_REG_DEF_GET (df, regno)->begin;
-      unsigned int n_defs = DF_REG_DEF_GET (df, regno)->n_refs;
-      
-      /* Only the last def(s) for a regno in the block has any
-        effect.  */ 
-      if (!bitmap_bit_p (seen_in_block, regno))
+      if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
        {
-         /* The first def for regno in insn gets to knock out the
-            defs from other instructions.  */
-         if (!bitmap_bit_p (seen_in_insn, regno))
+         unsigned int regno = DF_REF_REGNO (def);
+         unsigned int begin = DF_REG_DEF_GET (df, regno)->begin;
+         unsigned int n_defs = DF_REG_DEF_GET (df, regno)->n_refs;
+         
+         /* Only the last def(s) for a regno in the block has any
+            effect.  */ 
+         if (!bitmap_bit_p (seen_in_block, regno))
            {
-             if (n_defs > DF_SPARSE_THRESHOLD)
-               {
-                 bitmap_set_bit (bb_info->sparse_kill, regno);
-                 bitmap_clear_range (bb_info->gen, begin, n_defs);
-               }
-             else
+             /* The first def for regno in insn gets to knock out the
+                defs from other instructions.  */
+             if (!bitmap_bit_p (seen_in_insn, regno))
                {
-                 struct df_rd_problem_data *problem_data =
-                   (struct df_rd_problem_data *) dflow->problem_data;
-                 bitmap defs = 
-                   df_ref_bitmap (problem_data->def_sites, regno, 
-                                  begin, n_defs);
-                 bitmap_ior_into (bb_info->kill, defs);
-                 bitmap_and_compl_into (bb_info->gen, defs);
+                 if (n_defs > DF_SPARSE_THRESHOLD)
+                   {
+                     bitmap_set_bit (bb_info->sparse_kill, regno);
+                     bitmap_clear_range(bb_info->gen, begin, n_defs);
+                   }
+                 else
+                   {
+                     struct df_rd_problem_data * problem_data =
+                       (struct df_rd_problem_data *)dflow->problem_data;
+                     bitmap defs = 
+                       df_ref_bitmap (problem_data->def_sites, regno, 
+                                      begin, n_defs);
+                     bitmap_ior_into (bb_info->kill, defs);
+                     bitmap_and_compl_into (bb_info->gen, defs);
+                   }
                }
+             
+             bitmap_set_bit (seen_in_insn, regno);
+             /* All defs for regno in the instruction may be put into
+                the gen set.  */
+             if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+               bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
            }
-         
-         bitmap_set_bit (seen_in_insn, regno);
-         /* All defs for regno in the instruction may be put into
-            the gen set.  */
-         if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
-           bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
        }
       def = def->next_ref;
     }
@@ -1005,6 +1014,9 @@ df_rd_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
   bitmap_clear (seen_in_block);
   bitmap_clear (seen_in_insn);
 
+  df_rd_bb_local_compute_process_def (dflow, bb_info, 
+                                     df_get_artificial_defs (df, bb_index), 0);
+
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
@@ -1013,7 +1025,7 @@ df_rd_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
        continue;
 
       df_rd_bb_local_compute_process_def (dflow, bb_info, 
-                                         DF_INSN_UID_GET (df, uid)->defs);
+                                         DF_INSN_UID_GET (df, uid)->defs, 0);
 
       /* This complex dance with the two bitmaps is required because
         instructions can assign twice to the same pseudo.  This
@@ -1025,10 +1037,12 @@ df_rd_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
       bitmap_clear (seen_in_insn);
     }
 
-  /* Process the artificial defs last since we are going backwards
-     thur the block and these are logically at the start.  */
+  /* Process the artificial defs at the top of the block last since we
+     are going backwards through the block and these are logically at
+     the start.  */
   df_rd_bb_local_compute_process_def (dflow, bb_info, 
-                                     df_get_artificial_defs (df, bb_index));
+                                     df_get_artificial_defs (df, bb_index),
+                                     DF_REF_AT_TOP);
 }
 
 
@@ -1395,6 +1409,15 @@ df_lr_bb_local_compute (struct dataflow *dflow,
   struct df_ref *def;
   struct df_ref *use;
 
+  /* Process the registers set in an exception handler.  */
+  for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+      {
+       unsigned int dregno = DF_REF_REGNO (def);
+       bitmap_set_bit (bb_info->def, dregno);
+       bitmap_clear_bit (bb_info->use, dregno);
+      }
+
   /* Process the hardware registers that are always live.  */
   for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
     /* Add use to set of uses in this BB.  */
@@ -1455,12 +1478,13 @@ df_lr_bb_local_compute (struct dataflow *dflow,
 
   /* Process the registers set in an exception handler.  */
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    {
-      unsigned int dregno = DF_REF_REGNO (def);
-      bitmap_set_bit (bb_info->def, dregno);
-      bitmap_clear_bit (bb_info->use, dregno);
-    }
-
+    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+      {
+       unsigned int dregno = DF_REF_REGNO (def);
+       bitmap_set_bit (bb_info->def, dregno);
+       bitmap_clear_bit (bb_info->use, dregno);
+      }
+  
 #ifdef EH_USES
   /* Process the uses that are live into an exception handler.  */
   for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
@@ -1783,6 +1807,17 @@ df_ur_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
   bitmap_clear (seen_in_block);
   bitmap_clear (seen_in_insn);
 
+  for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+      {
+       unsigned int regno = DF_REF_REGNO (def);
+       if (!bitmap_bit_p (seen_in_block, regno))
+         {
+           bitmap_set_bit (seen_in_block, regno);
+           bitmap_set_bit (bb_info->gen, regno);
+         }
+      }
+
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
@@ -1808,14 +1843,15 @@ df_ur_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
     }
 
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    {
-      unsigned int regno = DF_REF_REGNO (def);
-      if (!bitmap_bit_p (seen_in_block, regno))
-       {
-         bitmap_set_bit (seen_in_block, regno);
-         bitmap_set_bit (bb_info->gen, regno);
-       }
-    }
+    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+      {
+       unsigned int regno = DF_REF_REGNO (def);
+       if (!bitmap_bit_p (seen_in_block, regno))
+         {
+           bitmap_set_bit (seen_in_block, regno);
+           bitmap_set_bit (bb_info->gen, regno);
+         }
+      }
 }
 
 
@@ -1875,9 +1911,6 @@ df_ur_local_finalize (struct dataflow *dflow, bitmap all_blocks)
       struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
       struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (lr_dflow, bb_index);
       
-      bitmap_ior_into (bb_info->in, df_all_hard_regs);
-      bitmap_ior_into (bb_info->out, df_all_hard_regs);
-
       /* No register may reach a location where it is not used.  Thus
         we trim the rr result to the places where it is used.  */
       bitmap_and_into (bb_info->in, bb_lr_info->in);
@@ -2336,11 +2369,12 @@ df_urec_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
   struct df_ref *def;
 
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    {
-      unsigned int regno = DF_REF_REGNO (def);
-      bitmap_set_bit (bb_info->gen, regno);
-    }
-
+    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+      {
+       unsigned int regno = DF_REF_REGNO (def);
+       bitmap_set_bit (bb_info->gen, regno);
+      }
+  
   FOR_BB_INSNS (bb, insn)
     {
       if (INSN_P (insn))
@@ -2357,6 +2391,14 @@ df_urec_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
            }
        }
     }
+
+  for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+      {
+       unsigned int regno = DF_REF_REGNO (def);
+       bitmap_set_bit (bb_info->gen, regno);
+      }
+
 }
 
 
@@ -2424,32 +2466,8 @@ df_urec_init (struct dataflow *dflow, bitmap all_blocks)
     {
       struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
 
-      /* FIXME: This is a hack, it has been copied over from
-        make_accurate_live_analysis by Vlad.  Most likely it is necessary
-        because the generation of gen and kill information for hardware
-        registers in ur is a subset of what is really necessary and what
-        is done for the lr problem.  */
-      
-      /* Inside the register allocator, partial availability is only
-        allowed for the psuedo registers.  To implement this, the rr is
-        initially iored with a mask ones for the hard registers and zeros
-        for the pseudos before being iterated.  This means that each
-        hardware register will be live unless explicitly killed by some
-        statement.  Eventually most of these bit will die because the
-        results of rr are anded with the results of lr before being used.
-        Outside of register allocation, a more conservative strategy of
-        completely ignoring the unintialized registers is imployed in the
-        finalizer function.  */
-      if (df_state & DF_SCAN_GLOBAL)
-       {
-         bitmap_ior (bb_info->out, bb_info->gen, df_all_hard_regs);
-         bitmap_copy (bb_info->in, df_all_hard_regs);
-       }
-      else
-       {
-         bitmap_copy (bb_info->out, bb_info->gen);
-         bitmap_clear (bb_info->in);
-       }
+      bitmap_copy (bb_info->out, bb_info->gen);
+      bitmap_clear (bb_info->in);
     }
 }
 
@@ -2489,12 +2507,6 @@ df_urec_local_finalize (struct dataflow *dflow, bitmap all_blocks)
 #endif
        }
 
-      if (!(df_state & DF_SCAN_GLOBAL))
-       {
-         bitmap_ior_into (bb_info->in, df_all_hard_regs);
-         bitmap_ior_into (bb_info->out, df_all_hard_regs);
-       }
-
       /* No register may reach a location where it is not used.  Thus
         we trim the rr result to the places where it is used.  */
       bitmap_and_into (bb_info->in, bb_lr_info->in);
@@ -2830,7 +2842,7 @@ df_chain_create_bb_process_use (struct dataflow *dflow,
   
   while (use)
     {
-      /* Do not want to go thur this for an uninitialized var.  */
+      /* Do not want to go through this for an uninitialized var.  */
       unsigned int uregno = DF_REF_REGNO (use);
       int count = DF_REG_DEF_GET (df, uregno)->n_refs;
       if (count)
@@ -2891,14 +2903,15 @@ df_chain_create_bb (struct dataflow *dflow,
 #endif
 
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    {
-      unsigned int dregno = DF_REF_REGNO (def);
-      bitmap_clear_range (cpy, 
-                         DF_REG_DEF_GET (df, dregno)->begin, 
-                         DF_REG_DEF_GET (df, dregno)->n_refs);
-      if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
-       bitmap_set_bit (cpy, DF_REF_ID (def));
-    }
+    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+      {
+       unsigned int dregno = DF_REF_REGNO (def);
+       bitmap_clear_range (cpy, 
+                           DF_REG_DEF_GET (df, dregno)->begin, 
+                           DF_REG_DEF_GET (df, dregno)->n_refs);
+       if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+         bitmap_set_bit (cpy, DF_REF_ID (def));
+      }
   
   /* Process the regular instructions next.  */
   FOR_BB_INSNS (bb, insn)
@@ -3136,8 +3149,14 @@ df_ri_bb_compute (struct dataflow *dflow, unsigned int bb_index, bitmap live)
        {
          unsigned int uregno = DF_REF_REGNO (use);
 
-         /* This register is now live.  */
-         bitmap_set_bit (live, uregno);
+         if (!bitmap_bit_p (live, uregno))
+           {
+             use->flags |= DF_REF_DIES_AFTER_THIS_USE;
+             /* This register is now live.  */
+             bitmap_set_bit (live, uregno);
+           }
+         else
+           use->flags &= ~DF_REF_DIES_AFTER_THIS_USE;
        }
 
       /* Increment lifetimes of all live registers.  */
index bba89e7..affc6df 100644 (file)
@@ -46,6 +46,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "sbitmap.h"
 #include "bitmap.h"
 #include "timevar.h"
+#include "tree.h"
+#include "target.h"
+#include "target-def.h"
 #include "df.h"
 
 #ifndef HAVE_epilogue
@@ -82,8 +85,6 @@ bitmap df_invalidated_by_call = NULL;
 /* Initialize ur_in and ur_out as if all hard registers were partially
    available.  */
 
-bitmap df_all_hard_regs = NULL;
-
 static void df_ref_record (struct dataflow *, rtx, rtx *, 
                           basic_block, rtx, enum df_ref_type,
                           enum df_ref_flags, bool record_live);
@@ -99,6 +100,7 @@ static void df_refs_record (struct dataflow *, bitmap);
 static struct df_ref *df_ref_create_structure (struct dataflow *, rtx, rtx *, 
                                               basic_block, rtx, enum df_ref_type, 
                                               enum df_ref_flags);
+static void df_record_entry_block_defs (struct dataflow *);
 static void df_record_exit_block_uses (struct dataflow *);
 static void df_grow_reg_info (struct dataflow *, struct df_ref_info *);
 static void df_grow_ref_info (struct df_ref_info *, unsigned int);
@@ -148,6 +150,7 @@ df_scan_free_internal (struct dataflow *dflow)
   dflow->block_info_size = 0;
 
   BITMAP_FREE (df->hardware_regs_used);
+  BITMAP_FREE (df->entry_block_defs);
   BITMAP_FREE (df->exit_block_uses);
 
   free_alloc_pool (dflow->block_pool);
@@ -252,6 +255,7 @@ df_scan_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
     }
 
   df->hardware_regs_used = BITMAP_ALLOC (NULL);
+  df->entry_block_defs = BITMAP_ALLOC (NULL);
   df->exit_block_uses = BITMAP_ALLOC (NULL);
 }
 
@@ -284,12 +288,12 @@ df_scan_dump (struct dataflow *dflow ATTRIBUTE_UNUSED, FILE *file ATTRIBUTE_UNUS
   struct df *df = dflow->df;
   int i;
 
-  fprintf (file, "  all hard regs \t");
-  dump_bitmap (file, df_all_hard_regs);
   fprintf (file, "  invalidated by call \t");
   dump_bitmap (file, df_invalidated_by_call);
   fprintf (file, "  hardware regs used \t");
   dump_bitmap (file, df->hardware_regs_used);
+  fprintf (file, "  entry block uses \t");
+  dump_bitmap (file, df->entry_block_defs);
   fprintf (file, "  exit block uses \t");
   dump_bitmap (file, df->exit_block_uses);
   fprintf (file, "  regs ever live \t");
@@ -1247,7 +1251,7 @@ df_uses_record (struct dataflow *dflow, rtx *loc, enum df_ref_type ref_type,
       {
        rtx dst = SET_DEST (x);
        gcc_assert (!(flags & DF_REF_IN_NOTE));
-       df_uses_record (dflow, &SET_SRC (x), DF_REF_REG_USE, bb, insn, 0);
+       df_uses_record (dflow, &SET_SRC (x), DF_REF_REG_USE, bb, insn, flags);
 
        switch (GET_CODE (dst))
          {
@@ -1256,7 +1260,7 @@ df_uses_record (struct dataflow *dflow, rtx *loc, enum df_ref_type ref_type,
                {
                  df_uses_record (dflow, &SUBREG_REG (dst), 
                                  DF_REF_REG_USE, bb,
-                                 insn, DF_REF_READ_WRITE);
+                                 insn, flags | DF_REF_READ_WRITE);
                  break;
                }
              /* Fall through.  */
@@ -1269,7 +1273,7 @@ df_uses_record (struct dataflow *dflow, rtx *loc, enum df_ref_type ref_type,
            case MEM:
              df_uses_record (dflow, &XEXP (dst, 0),
                              DF_REF_REG_MEM_STORE,
-                             bb, insn, 0);
+                             bb, insn, flags);
              break;
            case STRICT_LOW_PART:
              {
@@ -1290,9 +1294,9 @@ df_uses_record (struct dataflow *dflow, rtx *loc, enum df_ref_type ref_type,
                              DF_REF_REG_USE, bb, insn,
                              DF_REF_READ_WRITE);
              df_uses_record (dflow, &XEXP (dst, 1), 
-                             DF_REF_REG_USE, bb, insn, 0);
+                             DF_REF_REG_USE, bb, insn, flags);
              df_uses_record (dflow, &XEXP (dst, 2), 
-                             DF_REF_REG_USE, bb, insn, 0);
+                             DF_REF_REG_USE, bb, insn, flags);
              dst = XEXP (dst, 0);
              break;
            default:
@@ -1342,7 +1346,7 @@ df_uses_record (struct dataflow *dflow, rtx *loc, enum df_ref_type ref_type,
 
            for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
              df_uses_record (dflow, &ASM_OPERANDS_INPUT (x, j),
-                             DF_REF_REG_USE, bb, insn, 0);
+                             DF_REF_REG_USE, bb, insn, flags);
            return;
          }
        break;
@@ -1355,8 +1359,9 @@ df_uses_record (struct dataflow *dflow, rtx *loc, enum df_ref_type ref_type,
     case PRE_MODIFY:
     case POST_MODIFY:
       /* Catch the def of the register being modified.  */
+      flags |= DF_REF_READ_WRITE;
       df_ref_record (dflow, XEXP (x, 0), &XEXP (x, 0), bb, insn, 
-                    DF_REF_REG_DEF, DF_REF_READ_WRITE, true);
+                    DF_REF_REG_DEF, flags, true);
 
       /* ... Fall through to handle uses ...  */
 
@@ -1562,41 +1567,65 @@ df_bb_refs_record (struct dataflow *dflow, basic_block bb)
     {
       unsigned int i;
       /* Mark the registers that will contain data for the handler.  */
-      if (current_function_calls_eh_return)
-       for (i = 0; ; ++i)
-         {
-           unsigned regno = EH_RETURN_DATA_REGNO (i);
-           if (regno == INVALID_REGNUM)
-             break;
-           df_ref_record (dflow, regno_reg_rtx[i], &regno_reg_rtx[i], bb, NULL, 
-                          DF_REF_REG_DEF, DF_REF_ARTIFICIAL | DF_REF_AT_TOP, false);
-         }
+      for (i = 0; ; ++i)
+       {
+         unsigned regno = EH_RETURN_DATA_REGNO (i);
+         if (regno == INVALID_REGNUM)
+           break;
+         df_ref_record (dflow, regno_reg_rtx[i], &regno_reg_rtx[i], bb, NULL,
+                        DF_REF_REG_DEF, DF_REF_ARTIFICIAL | DF_REF_AT_TOP,
+                        false);
+       }
     }
 #endif
 
-#ifdef EH_USES
-  /*  This code is putting in a artificial ref for the use at the TOP
-      of the block that receives the exception.  It is too cumbersome
-      to actually put the ref on the edge.  We could either model this
-      at the top of the receiver block or the bottom of the sender
-      block.
-
-      The bottom of the sender block is problematic because not all
-      out-edges of the a block are eh-edges.  However, it is true that
-      all edges into a block are either eh-edges or none of them are
-      eh-edges.  Thus, we can model this at the top of the eh-receiver
-      for all of the edges at once. */
+
   if ((df->flags & DF_HARD_REGS)
       && df_has_eh_preds (bb))
     {
+#ifdef EH_USES
       unsigned int i;
+      /* This code is putting in a artificial ref for the use at the
+        TOP of the block that receives the exception.  It is too
+        cumbersome to actually put the ref on the edge.  We could
+        either model this at the top of the receiver block or the
+        bottom of the sender block.
+
+         The bottom of the sender block is problematic because not all
+         out-edges of the a block are eh-edges.  However, it is true
+         that all edges into a block are either eh-edges or none of
+         them are eh-edges.  Thus, we can model this at the top of the
+         eh-receiver for all of the edges at once. */
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (EH_USES (i))
          df_uses_record (dflow, &regno_reg_rtx[i], 
-                                  DF_REF_REG_USE, EXIT_BLOCK_PTR, NULL,
-                                  DF_REF_ARTIFICIAL | DF_REF_AT_TOP);
-    }
+                         DF_REF_REG_USE, EXIT_BLOCK_PTR, NULL,
+                         DF_REF_ARTIFICIAL | DF_REF_AT_TOP);
+#endif
+
+      /* The following code (down thru the arg_pointer seting APPEARS
+        to be necessary because there is nothing that actually
+        describes what the exception handling code may actually need
+        to keep alive.  */
+      if (reload_completed)
+       {
+         if (frame_pointer_needed)
+           {
+             df_uses_record (dflow, &regno_reg_rtx[FRAME_POINTER_REGNUM],
+                             DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+             df_uses_record (dflow, &regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
+                             DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
+#endif
+           }
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+         if (fixed_regs[ARG_POINTER_REGNUM])
+           df_uses_record (dflow, &regno_reg_rtx[ARG_POINTER_REGNUM],
+                           DF_REF_REG_USE, bb, NULL, 
+                           DF_REF_ARTIFICIAL);
 #endif
+       }
+    }
 
   if ((df->flags & DF_HARD_REGS) 
       && bb->index >= NUM_FIXED_BLOCKS)
@@ -1652,6 +1681,9 @@ df_refs_record (struct dataflow *dflow, bitmap blocks)
 
   if (bitmap_bit_p (blocks, EXIT_BLOCK))
     df_record_exit_block_uses (dflow);
+
+  if (bitmap_bit_p (blocks, ENTRY_BLOCK))
+    df_record_entry_block_defs (dflow);
 }
 
 
@@ -1679,6 +1711,108 @@ df_mark_reg (rtx reg, void *vset)
     }
 }
 
+
+/* Record the (conservative) set of hard registers that are defined on
+   entry to the function.  */
+
+static void
+df_record_entry_block_defs (struct dataflow * dflow)
+{
+  unsigned int i; 
+  bitmap_iterator bi;
+  rtx r;
+  struct df * df = dflow->df;
+
+  bitmap_clear (df->entry_block_defs);
+
+  if (! (df->flags & DF_HARD_REGS))
+    return;
+
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    {
+      if (FUNCTION_ARG_REGNO_P (i))
+#ifdef INCOMING_REGNO
+       bitmap_set_bit (df->entry_block_defs, INCOMING_REGNO (i));
+#else
+       bitmap_set_bit (df->entry_block_defs, i);
+#endif
+    }
+      
+  /* Once the prologue has been generated, all of these registers
+     should just show up in the first regular block.  */
+  if (HAVE_prologue && epilogue_completed)
+    {
+      /* Defs for the callee saved registers are inserted so that the
+        pushes have some defining location.  */
+      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+       if ((call_used_regs[i] == 0) && (regs_ever_live[i]))
+         bitmap_set_bit (df->entry_block_defs, i);
+    }
+  else
+    {
+      if (REG_P (INCOMING_RETURN_ADDR_RTX))
+       bitmap_set_bit (df->entry_block_defs, REGNO (INCOMING_RETURN_ADDR_RTX));
+            
+      /* If STATIC_CHAIN_INCOMING_REGNUM == STATIC_CHAIN_REGNUM
+        only STATIC_CHAIN_REGNUM is defined.  If they are different,
+        we only care about the STATIC_CHAIN_INCOMING_REGNUM.  */
+#ifdef STATIC_CHAIN_INCOMING_REGNUM
+      bitmap_set_bit (df->entry_block_defs, STATIC_CHAIN_INCOMING_REGNUM);
+#else 
+#ifdef STATIC_CHAIN_REGNUM
+      bitmap_set_bit (df->entry_block_defs, STATIC_CHAIN_REGNUM);
+#endif
+#endif
+      
+      r = TARGET_STRUCT_VALUE_RTX (current_function_decl, true);
+      if (r && REG_P (r))
+       bitmap_set_bit (df->entry_block_defs, REGNO (r));
+    }
+
+  /* These registers are live everywhere.  */
+  if (!reload_completed)
+    {
+      /* Any reference to any pseudo before reload is a potential
+        reference of the frame pointer.  */
+      bitmap_set_bit (df->entry_block_defs, FRAME_POINTER_REGNUM);
+
+#ifdef EH_USES
+      /* The ia-64, the only machine that uses this, does not define these 
+        until after reload.  */
+      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+       if (EH_USES (i))
+         {
+           bitmap_set_bit (df->entry_block_defs, i);
+         }
+#endif
+      
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+      /* Pseudos with argument area equivalences may require
+        reloading via the argument pointer.  */
+      if (fixed_regs[ARG_POINTER_REGNUM])
+       bitmap_set_bit (df->entry_block_defs, ARG_POINTER_REGNUM);
+#endif
+         
+#ifdef PIC_OFFSET_TABLE_REGNUM
+      /* Any constant, or pseudo with constant equivalences, may
+        require reloading from memory using the pic register.  */
+      if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
+         && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
+       bitmap_set_bit (df->entry_block_defs, PIC_OFFSET_TABLE_REGNUM);
+#endif
+    }
+
+  (*targetm.live_on_entry) (df->entry_block_defs);
+
+  EXECUTE_IF_SET_IN_BITMAP (df->entry_block_defs, 0, i, bi)
+    {
+      df_ref_record (dflow, regno_reg_rtx[i], &regno_reg_rtx[i], 
+                    ENTRY_BLOCK_PTR, NULL, 
+                    DF_REF_REG_DEF, DF_REF_ARTIFICIAL , false);
+    }
+}
+
+
 /* Record the set of hard registers that are used in the exit block.  */
 
 static void
@@ -1827,10 +1961,5 @@ df_hard_reg_init (void)
     if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
       bitmap_set_bit (df_invalidated_by_call, i);
   
-  df_all_hard_regs = BITMAP_ALLOC (&persistent_obstack);
-  
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    bitmap_set_bit (df_all_hard_regs, i);
-  
   initialized = true;
 }
index f2e7bef..8c5108e 100644 (file)
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -211,7 +211,12 @@ enum df_ref_flags
     DF_REF_IN_NOTE = 16,
 
     /* This flag is set if this ref is really a clobber, and not a def.  */
-    DF_REF_CLOBBER = 32
+    DF_REF_CLOBBER = 32,
+
+    /* True if ref is dead (i.e. the next ref is a def or clobber or
+       the end of the function.)  This is only valid the RI problem
+       has been set in this df instance.  */
+    DF_REF_DIES_AFTER_THIS_USE = 64
   };
 
 
@@ -223,7 +228,10 @@ struct df_ref
   rtx reg;                     /* The register referenced.  */
   unsigned int regno;           /* The register number referenced.  */
   basic_block bb;               /* Basic block containing the instruction. */
-  rtx insn;                    /* Insn containing ref.  NB: THIS MAY BE NULL.  */
+
+  /* Insn containing ref. This will be null if this is an artificial
+     reference.  */
+  rtx insn;
   rtx *loc;                    /* The location of the reg.  */
   struct df_link *chain;       /* Head of def-use, use-def.  */
   unsigned int id;             /* Location in table.  */
@@ -316,6 +324,7 @@ struct df
   struct df_insn_info **insns;   /* Insn table, indexed by insn UID.  */
   unsigned int insns_size;       /* Size of insn table.  */
   bitmap hardware_regs_used;     /* The set of hardware registers used.  */
+  bitmap entry_block_defs;       /* The set of hardware registers live on entry to the function.  */
   bitmap exit_block_uses;        /* The set of hardware registers used in exit block.  */
 };
 
@@ -422,8 +431,6 @@ extern bitmap df_invalidated_by_call;
 /* Initialize ur_in and ur_out as if all hard registers were partially
 available.  */
 
-extern bitmap df_all_hard_regs;
-
 /* The way that registers are processed, especially hard registers,
    changes as the compilation proceeds. These states are passed to
    df_set_state to control this processing.  */
index 7bd8522..d60fc13 100644 (file)
@@ -4481,6 +4481,15 @@ as the @code{sibcall} md pattern can not fail, or fall over to a
 may vary greatly between different architectures.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_EXTRA_LIVE_ON_ENTRY (bitmap *@var{regs})
+Add any hard registers to @var{regs} that are live on entry to the
+function.  This hook only needs to be defined to provide registers that
+cannot be found by examination of FUNCTION_ARG_REGNO_P, the callee saved
+registers, STATIC_CHAIN_INCOMING_REGNUM, STATIC_CHAIN_REGNUM,
+TARGET_STRUCT_VALUE_RTX, FRAME_POINTER_REGNUM, EH_USES,
+FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM.
+@end deftypefn
+
 @node Stack Smashing Protection
 @subsection Stack smashing protection
 @cindex stack smashing protection
index 642e970..7599101 100644 (file)
@@ -185,6 +185,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 #define TARGET_ASM_FILE_END hook_void_void
 #endif
 
+#ifndef TARGET_EXTRA_LIVE_ON_ENTRY
+#define TARGET_EXTRA_LIVE_ON_ENTRY hook_void_bitmap
+#endif
+
 #ifndef TARGET_ASM_FILE_START_APP_OFF
 #define TARGET_ASM_FILE_START_APP_OFF false
 #endif
@@ -625,6 +629,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   TARGET_INVALID_BINARY_OP,                    \
   TARGET_SECONDARY_RELOAD,                     \
   TARGET_CXX,                                  \
+  TARGET_EXTRA_LIVE_ON_ENTRY,                    \
   TARGET_UNWIND_TABLES_DEFAULT,                        \
   TARGET_HAVE_NAMED_SECTIONS,                  \
   TARGET_HAVE_CTORS_DTORS,                     \
index b32be83..36f2463 100644 (file)
@@ -703,6 +703,11 @@ struct gcc_target
        target modifications).  */
     void (*adjust_class_at_definition) (tree type);
   } cxx;
+  
+  /* For targets that need to mark extra registers as live on entry to
+     the function, they should define this target hook and set their
+     bits in the bitmap passed in. */  
+  void (*live_on_entry) (bitmap); 
 
   /* True if unwinding tables should be generated by default.  */
   bool unwind_tables_default;
index 786b152..f6289c8 100644 (file)
@@ -337,6 +337,11 @@ hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
   return 0;
 }
 
+void 
+hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)
+{
+}
+
 const char *
 hook_invalid_arg_for_unprototyped_fn (
        tree typelist ATTRIBUTE_UNUSED,
index 4439648..05d1add 100644 (file)
@@ -74,3 +74,4 @@ extern rtx default_internal_arg_pointer (void);
 extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class,
                                                enum machine_mode,
                                                secondary_reload_info *);
+extern void hook_void_bitmap (bitmap);