]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport RTL sharing fixes
authorBernd Schmidt <bernds@redhat.co.uk>
Thu, 25 Jan 2001 13:12:20 +0000 (13:12 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Thu, 25 Jan 2001 13:12:20 +0000 (13:12 +0000)
From-SVN: r39263

gcc/ChangeLog
gcc/emit-rtl.c
gcc/function.c
gcc/rtl.h
gcc/toplev.c
gcc/tree.h

index 42c6103f310c3b8c77b95aa500a35b4f16c8e977..a0908c97565dc88a5a88ca256097d9645b9d4566 100644 (file)
@@ -4,6 +4,33 @@
        constant pool, also put it on forced_labels list so that it won't
        be deleted.
 
+       2000-05-25  Alexandre Oliva  <aoliva@cygnus.com>
+       * emit-rtl.c (reset_used_decls): New function.
+       (unshare_all_rtl_again): Call it.
+
+       2000-05-24  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+       * emit-rtl.c (unshare_all_decls): New function.
+       (unshare_all_rtl): Call it.
+
+       2000-05-20  Alexandre Oliva  <aoliva@cygnus.com>
+       * emit-rtl.c (unshare_all_rtl): Store the copied rtx.
+
+       2000-04-15  Richard Earnshaw (rearnsah@arm.com)
+       * emit-rtl.c (unshare_all_rtl_again): Unmark everything, then
+       call unshare_all_rtl.
+
+       2000-01-27  Geoffrey Keating  <geoffk@cygnus.com>
+       * emit-rtl.c (unshare_all_rtl): Unshare virtual parameters too.
+       Use unshare_all_rtl_1.
+       (unshare_all_rtl_again): New function.
+       (unshare_all_rtl_1): New function split out of unshare_all_rtl.
+       * function.c (purge_addressof_1): Use unshare_all_rtl_again
+       rather than resetting the 'used' flags ourself.
+       * toplev.c (rest_of_compilation): Add current_function_decl
+       to the unshare_all_rtl call.
+       * tree.h: Prototype unshare_all_rtl.
+       * rtl.h: Prototype unshare_all_rtl_again here.
+
 2001-01-12  Bernd Schmidt  <bernds@redhat.co.uk>
 
        * version.c: Bump.
index 54cee163738a0f38f37850ec4ac82597ca8e1545..58029ab87b9ac17808699c785af41787fa93e43c 100644 (file)
@@ -248,6 +248,9 @@ extern int emit_lineno;
 static rtx make_jump_insn_raw          PROTO((rtx));
 static rtx make_call_insn_raw          PROTO((rtx));
 static rtx find_line_note              PROTO((rtx));
+static void unshare_all_rtl_1          PROTO((rtx));
+static void unshare_all_decls          PROTO((tree));
+static void reset_used_decls           PROTO((tree));
 \f
 rtx
 gen_rtx_CONST_INT (mode, arg)
@@ -1767,23 +1770,29 @@ restore_emit_status (p)
   free_insn = 0;
 }
 \f
-/* Go through all the RTL insn bodies and copy any invalid shared structure.
-   It does not work to do this twice, because the mark bits set here
-   are not cleared afterwards.  */
+/* Go through all the RTL insn bodies and copy any invalid shared 
+   structure.  This routine should only be called once.  */
 
 void
-unshare_all_rtl (insn)
-     register rtx insn;
+unshare_all_rtl (fndecl, insn)
+     tree fndecl;
+     rtx insn;
 {
-  for (; insn; insn = NEXT_INSN (insn))
-    if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-       || GET_CODE (insn) == CALL_INSN)
-      {
-       PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
-       REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
-       LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
-      }
+  tree decl;
+
+  /* Make sure that virtual stack slots are not shared.  */
+  reset_used_decls (DECL_INITIAL (current_function_decl));
+
+  /* Make sure that virtual parameters are not shared.  */
+  for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
+    DECL_RTL (decl) = copy_rtx_if_shared (DECL_RTL (decl));
 
+  /* Make sure that virtual stack slots are not shared.  */
+  unshare_all_decls (DECL_INITIAL (fndecl));
+
+  /* Unshare just about everything else.  */
+  unshare_all_rtl_1 (insn);
+  
   /* Make sure the addresses of stack slots found outside the insn chain
      (such as, in DECL_RTL of a variable) are not shared
      with the insn chain.
@@ -1791,8 +1800,76 @@ unshare_all_rtl (insn)
      This special care is necessary when the stack slot MEM does not
      actually appear in the insn chain.  If it does appear, its address
      is unshared from all else at that point.  */
+  stack_slot_list = copy_rtx_if_shared (stack_slot_list);
+}
+
+/* Go through all the RTL insn bodies and copy any invalid shared 
+   structure, again.  This is a fairly expensive thing to do so it
+   should be done sparingly.  */
+
+void
+unshare_all_rtl_again (insn)
+     rtx insn;
+{
+  rtx p;
+  for (p = insn; p; p = NEXT_INSN (p))
+    if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
+      {
+       reset_used_flags (PATTERN (p));
+       reset_used_flags (REG_NOTES (p));
+       reset_used_flags (LOG_LINKS (p));
+      }
+  unshare_all_rtl_1 (insn);
+}
+
+/* Go through all the RTL insn bodies and copy any invalid shared structure.
+   Assumes the mark bits are cleared at entry.  */
+
+static void
+unshare_all_rtl_1 (insn)
+     rtx insn;
+{
+  for (; insn; insn = NEXT_INSN (insn))
+    if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+      {
+       PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
+       REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
+       LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
+      }
+}
+
+/* Go through all virtual stack slots of a function and copy any
+   shared structure.  */
+static void
+unshare_all_decls (blk)
+     tree blk;
+{
+  tree t;
+
+  /* Copy shared decls.  */
+  for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
+    DECL_RTL (t)  = copy_rtx_if_shared (DECL_RTL (t));
+
+  /* Now process sub-blocks.  */
+  for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
+    unshare_all_decls (t);
+}
+
+/* Go through all virtual stack slots of a function and mark them as
+   not shared. */
+static void
+reset_used_decls (blk)
+     tree blk;
+{
+  tree t;
+
+  /* Mark decls.  */
+  for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
+    reset_used_flags (DECL_RTL (t));
 
-  copy_rtx_if_shared (stack_slot_list);
+  /* Now process sub-blocks.  */
+  for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
+    reset_used_decls (t);
 }
 
 /* Mark ORIG as in use, and return a copy of it if it was already in use.
index a4033a9a6b836e9231fb7122666a17ba8ab8b547..1bcb3060a9935abe62219170e2ac4f4ee0c92ed2 100644 (file)
@@ -3221,13 +3221,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
 
                  /* Make sure to unshare any shared rtl that store_bit_field
                     might have created.  */
-                 for (p = get_insns(); p; p = NEXT_INSN (p))
-                   {
-                     reset_used_flags (PATTERN (p));
-                     reset_used_flags (REG_NOTES (p));
-                     reset_used_flags (LOG_LINKS (p));
-                   }
-                 unshare_all_rtl (get_insns ());
+                 unshare_all_rtl_again (get_insns ());
 
                  seq = gen_sequence ();
                  end_sequence ();
@@ -3479,6 +3473,20 @@ purge_addressof (insns)
   hash_table_free (&ht);
   purge_bitfield_addressof_replacements = 0;
   purge_addressof_replacements = 0;
+
+  /* REGs are shared.  purge_addressof will destructively replace a REG
+     with a MEM, which creates shared MEMs.
+
+     Unfortunately, the children of put_reg_into_stack assume that MEMs
+     referring to the same stack slot are shared (fixup_var_refs and
+     the associated hash table code).
+
+     So, we have to do another unsharing pass after we have flushed any
+     REGs that had their address taken into the stack.
+
+     It may be worth tracking whether or not we converted any REGs into
+     MEMs to avoid this overhead when it is not needed.  */
+  unshare_all_rtl_again (get_insns ());
 }
 \f
 /* Pass through the INSNS of function FNDECL and convert virtual register
index 0f43e87dc751339fd3bc23400e172432b0519b1d..377dc54e8b5846da16c5003ab1bab3d7adcf999f 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1391,7 +1391,7 @@ extern int subreg_realpart_p                      PROTO ((rtx));
 extern void reverse_comparison                 PROTO ((rtx));
 extern void set_new_first_and_last_insn                PROTO ((rtx, rtx));
 extern void set_new_first_and_last_label_num   PROTO ((int, int));
-extern void unshare_all_rtl                    PROTO ((rtx));
+extern void unshare_all_rtl_again              PROTO ((rtx));
 extern void set_last_insn                      PROTO ((rtx));
 extern void link_cc0_insns                     PROTO ((rtx));
 extern void add_insn                           PROTO ((rtx));
index 242a73cb86089d0a1924869434183e7f8e559181..b50288e80305b9403dda6b0040e4da14939162fa 100644 (file)
@@ -3816,7 +3816,7 @@ rest_of_compilation (decl)
 
   /* Copy any shared structure that should not be shared.  */
 
-  unshare_all_rtl (insns);
+  unshare_all_rtl (current_function_decl, insns);
 
 #ifdef SETJMP_VIA_SAVE_AREA
   /* This must be performed before virutal register instantiation.  */
index 0d7ea84aafc423889b0867cf333c3f19932a01a2..1a916e2047f5acfde4601be999b2a3e7d55acd60 100644 (file)
@@ -2207,6 +2207,7 @@ extern tree reorder_blocks                PROTO ((tree *, tree,
                                                struct rtx_def *));
 extern void free_temps_for_rtl_expr    PROTO ((tree));
 extern void instantiate_virtual_regs   PROTO ((tree, struct rtx_def *));
+extern void unshare_all_rtl            PROTO ((tree, struct rtx_def *));
 extern int max_parm_reg_num            PROTO ((void));
 extern void push_function_context      PROTO ((void));
 extern void pop_function_context       PROTO ((void));