OSDN Git Service

* rtl.h (REG_VTABLE_REF): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Oct 2001 18:48:42 +0000 (18:48 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Oct 2001 18:48:42 +0000 (18:48 +0000)
        * rtl.c (reg_note_name): Add it.
        * combine.c (distribute_notes): Handle it.
        * final.c (final_scan_insn): Handle it.
        * tree.def (VTABLE_REF): New.
        * expr.c (expand_expr): Handle it.
        * varasm.c (assemble_vtable_entry, assemble_vtable_inherit): New.
        * output.h: Declare them.
cp/
        * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
        of an asm statement.
        (build_vtbl_ref_1): Split out from build_vtbl_ref.
        (build_vfn_ref): Use it to handle vtable descriptors before
        calling build_vtable_entry_ref.
        * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit.
testsuite/
        * g++.old-deja/g++.other/crash18.C: Add -S to options.

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

14 files changed:
gcc/ChangeLog
gcc/combine.c
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl2.c
gcc/expr.c
gcc/final.c
gcc/output.h
gcc/rtl.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.other/crash18.C
gcc/tree.def
gcc/varasm.c

index 7d8a498..7c75167 100644 (file)
@@ -1,5 +1,16 @@
 2001-10-11  Richard Henderson  <rth@redhat.com>
 
+       * rtl.h (REG_VTABLE_REF): New.
+       * rtl.c (reg_note_name): Add it.
+       * combine.c (distribute_notes): Handle it.
+       * final.c (final_scan_insn): Handle it.
+       * tree.def (VTABLE_REF): New.
+       * expr.c (expand_expr): Handle it.
+       * varasm.c (assemble_vtable_entry, assemble_vtable_inherit): New.
+       * output.h: Declare them.
+
+2001-10-11  Richard Henderson  <rth@redhat.com>
+
        * dwarf2out.c (rtl_for_decl_location): If no DECL_RTL, look
        for a DECL_INITIAL.
 
index 12225db..e16cb4d 100644 (file)
@@ -11952,6 +11952,12 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
          place = i3;
          break;
 
+       case REG_VTABLE_REF:
+         /* ??? Should remain with *a particular* memory load.  Given the
+            nature of vtable data, the last insn seems relatively safe.  */
+         place = i3;
+         break;
+
        case REG_NON_LOCAL_GOTO:
          if (GET_CODE (i3) == JUMP_INSN)
            place = i3;
index 8d867bb..06806fc 100644 (file)
@@ -1,3 +1,12 @@
+2001-10-11  Richard Henderson  <rth@redhat.com>
+
+       * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
+       of an asm statement.
+       (build_vtbl_ref_1): Split out from build_vtbl_ref.
+       (build_vfn_ref): Use it to handle vtable descriptors before
+       calling build_vtable_entry_ref.
+       * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit.
+
 2001-10-10  Richard Henderson  <rth@redhat.com>
 
         * parse.y (asm_operand): Allow named operands.
index 97a3597..305bde1 100644 (file)
@@ -134,7 +134,8 @@ static tree add_implicitly_declared_members PARAMS ((tree, int, int, int));
 static tree fixed_type_or_null PARAMS ((tree, int *, int *));
 static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
                                                          int, int, tree));
-static void build_vtable_entry_ref PARAMS ((tree, tree));
+static tree build_vtable_entry_ref PARAMS ((tree, tree, tree));
+static tree build_vtbl_ref_1 PARAMS ((tree, tree));
 static tree build_vtbl_initializer PARAMS ((tree, tree, tree, tree, int *));
 static int count_fields PARAMS ((tree));
 static int add_fields_to_vec PARAMS ((tree, tree, int));
@@ -424,38 +425,31 @@ build_vbase_path (code, type, expr, path, nonnull)
 \f
 /* Virtual function things.  */
 
-/* We want to give the assembler the vtable identifier as well as
-   the offset to the function pointer.  So we generate
+static tree
+build_vtable_entry_ref (array_ref, instance, idx)
+     tree array_ref, instance, idx;
+{
+  tree i, i2, vtable, first_fn, basetype;
 
-   __asm__ __volatile__ (".vtable_entry %c0, %c1"
-      : : "s"(&class_vtable),
-          "i"((long)&vtbl[idx].pfn - (long)&vtbl[0])); */
+  basetype = TREE_TYPE (instance);
+  if (TREE_CODE (basetype) == REFERENCE_TYPE)
+    basetype = TREE_TYPE (basetype);
 
-static void
-build_vtable_entry_ref (basetype, idx)
-     tree basetype, idx;
-{
-  static const char asm_stmt[] = ".vtable_entry %c0, %c1";
-  tree s, i, i2;
-  tree vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
-  tree first_fn = TYPE_BINFO_VTABLE (basetype);
+  vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
+  first_fn = TYPE_BINFO_VTABLE (basetype);
 
-  s = build_unary_op (ADDR_EXPR, vtable, 0);
-  s = build_tree_list (build_string (1, "s"), s);
+  i = fold (build_array_ref (first_fn, idx));
+  i = fold (build_c_cast (ptrdiff_type_node,
+                         build_unary_op (ADDR_EXPR, i, 0)));
+  i2 = fold (build_array_ref (vtable, build_int_2 (0,0)));
+  i2 = fold (build_c_cast (ptrdiff_type_node,
+                          build_unary_op (ADDR_EXPR, i2, 0)));
+  i = fold (cp_build_binary_op (MINUS_EXPR, i, i2));
 
-  i = build_array_ref (first_fn, idx);
-  /* We must not convert to ptrdiff_type node here, since this could widen
-     from a partial to an integral node, which would create a
-     convert_expression that would be in the way of any simplifications.  */
-  i = build_c_cast (string_type_node, build_unary_op (ADDR_EXPR, i, 0));
-  i2 = build_array_ref (vtable, build_int_2 (0,0));
-  i2 = build_c_cast (string_type_node, build_unary_op (ADDR_EXPR, i2, 0));
-  i = cp_build_binary_op (MINUS_EXPR, i, i2);
-  i = build_tree_list (build_string (1, "i"), i);
+  if (TREE_CODE (i) != INTEGER_CST)
+    abort ();
 
-  finish_asm_stmt (ridpointers[RID_VOLATILE],
-                  build_string (sizeof(asm_stmt)-1, asm_stmt),
-                  NULL_TREE, chainon (s, i), NULL_TREE);
+  return build (VTABLE_REF, TREE_TYPE (array_ref), array_ref, vtable, i);
 }
 
 /* Given an object INSTANCE, return an expression which yields the
@@ -463,8 +457,8 @@ build_vtable_entry_ref (basetype, idx)
    cases for INSTANCE which we take care of here, mainly to avoid
    creating extra tree nodes when we don't have to.  */
 
-tree
-build_vtbl_ref (instance, idx)
+static tree
+build_vtbl_ref_1 (instance, idx)
      tree instance, idx;
 {
   tree vtbl, aref;
@@ -535,14 +529,23 @@ build_vtbl_ref (instance, idx)
 
   assemble_external (vtbl);
 
-  if (flag_vtable_gc)
-    build_vtable_entry_ref (basetype, idx);
-
   aref = build_array_ref (vtbl, idx);
 
   return aref;
 }
 
+tree
+build_vtbl_ref (instance, idx)
+     tree instance, idx;
+{
+  tree aref = build_vtbl_ref_1 (instance, idx);
+
+  if (flag_vtable_gc)
+    aref = build_vtable_entry_ref (aref, instance, idx);
+
+  return aref;
+}
+
 /* Given an object INSTANCE, return an expression which yields a
    function pointer corresponding to vtable element INDEX.  */
 
@@ -550,14 +553,17 @@ tree
 build_vfn_ref (instance, idx)
      tree instance, idx;
 {
-  tree aref = build_vtbl_ref (instance, idx);
+  tree aref = build_vtbl_ref_1 (instance, idx);
 
   /* When using function descriptors, the address of the
      vtable entry is treated as a function pointer.  */
   if (TARGET_VTABLE_USES_DESCRIPTORS)
-    return build1 (NOP_EXPR, TREE_TYPE (aref),
+    aref = build1 (NOP_EXPR, TREE_TYPE (aref),
                   build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
 
+  if (flag_vtable_gc)
+    aref = build_vtable_entry_ref (aref, instance, idx);
+
   return aref;
 }
 
index 0ab9299..8c5dba1 100644 (file)
@@ -2406,23 +2406,23 @@ output_vtable_inherit (vars)
      tree vars;
 {
   tree parent;
-  rtx op[2];
+  rtx child_rtx, parent_rtx;
 
-  op[0] = XEXP (DECL_RTL (vars), 0);     /* strip the mem ref  */
+  child_rtx = XEXP (DECL_RTL (vars), 0);         /* strip the mem ref  */
 
   parent = binfo_for_vtable (vars);
 
   if (parent == TYPE_BINFO (DECL_CONTEXT (vars)))
-    op[1] = const0_rtx;
+    parent_rtx = const0_rtx;
   else if (parent)
     {
       parent = get_vtbl_decl_for_binfo (TYPE_BINFO (BINFO_TYPE (parent)));
-      op[1] = XEXP (DECL_RTL (parent), 0);  /* strip the mem ref  */
+      parent_rtx = XEXP (DECL_RTL (parent), 0);  /* strip the mem ref  */
     }
   else
     my_friendly_abort (980826);
 
-  output_asm_insn (".vtable_inherit %c0, %c1", op);
+  assemble_vtable_inherit (child_rtx, parent_rtx);
 }
 
 static int
index 9457e8f..1c81f73 100644 (file)
@@ -7211,6 +7211,43 @@ expand_expr (exp, target, tmode, modifier)
        return target;
       }
 
+    case VTABLE_REF:
+      {
+       rtx insn, before = get_last_insn (), vtbl_ref;
+
+       /* Evaluate the interior expression.  */
+       subtarget = expand_expr (TREE_OPERAND (exp, 0), target,
+                                tmode, modifier);
+
+       /* Get or create an instruction off which to hang a note.  */
+       if (REG_P (subtarget))
+         {
+           target = subtarget;
+           insn = get_last_insn ();
+           if (insn == before)
+             abort ();
+           if (! INSN_P (insn))
+             insn = prev_nonnote_insn (insn);
+         }
+       else
+         {
+           target = gen_reg_rtx (GET_MODE (subtarget));
+           insn = emit_move_insn (target, subtarget);
+         }
+
+       /* Collect the data for the note.  */
+       vtbl_ref = XEXP (DECL_RTL (TREE_OPERAND (exp, 1)), 0);
+       vtbl_ref = plus_constant (vtbl_ref,
+                                 tree_low_cst (TREE_OPERAND (exp, 2), 0));
+       /* Discard the initial CONST that was added.  */
+       vtbl_ref = XEXP (vtbl_ref, 0);
+
+       REG_NOTES (insn)
+         = gen_rtx_EXPR_LIST (REG_VTABLE_REF, vtbl_ref, REG_NOTES (insn));
+
+       return target;
+      }
+
       /* Intended for a reference to a buffer of a file-object in Pascal.
         But it's not certain that a special tree code will really be
         necessary for these.  INDIRECT_REF might work for them.  */
index 28f756d..5884382 100644 (file)
@@ -2375,9 +2375,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        rtx body = PATTERN (insn);
        int insn_code_number;
        const char *template;
-#ifdef HAVE_cc0
        rtx note;
-#endif
 
        /* An INSN, JUMP_INSN or CALL_INSN.
           First check for special kinds that recog doesn't recognize.  */
@@ -2799,7 +2797,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
            if (next != 0 && next != NEXT_INSN (insn))
              {
                rtx prev = PREV_INSN (insn);
-               rtx note;
 
                for (note = NEXT_INSN (insn); note != next;
                     note = NEXT_INSN (note))
@@ -2953,6 +2950,12 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        INSN_DELETED_P (insn) = 1;
 #endif
 
+       /* Emit information for vtable gc.  */
+       note = find_reg_note (insn, REG_VTABLE_REF, NULL_RTX);
+       if (note)
+         assemble_vtable_entry (XEXP (XEXP (note, 0), 0),
+                                INTVAL (XEXP (XEXP (note, 0), 1)));
+
        current_output_insn = debug_insn = 0;
       }
     }
index 9194aea..1e97c21 100644 (file)
@@ -497,3 +497,8 @@ extern void default_named_section_asm_out_constructor PARAMS ((struct rtx_def *,
                                                               int));
 extern void default_ctor_section_asm_out_constructor PARAMS ((struct rtx_def *,
                                                              int));
+
+/* Emit data for vtable gc for GNU binutils.  */
+extern void assemble_vtable_entry PARAMS ((struct rtx_def *, HOST_WIDE_INT));
+extern void assemble_vtable_inherit PARAMS ((struct rtx_def *,
+                                            struct rtx_def *));
index bcf3005..7a07b72 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -281,7 +281,8 @@ const char * const reg_note_name[] =
   "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
   "REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION",
   "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN",
-  "REG_NON_LOCAL_GOTO", "REG_SETJMP", "REG_ALWAYS_RETURN"
+  "REG_NON_LOCAL_GOTO", "REG_SETJMP", "REG_ALWAYS_RETURN",
+  "REG_VTABLE_REF"
 };
 
 \f
index 37a204c..4c0eb2c 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -579,7 +579,11 @@ enum reg_note
   REG_SETJMP,
 
   /* Indicate calls that always returns.  */
-  REG_ALWAYS_RETURN
+  REG_ALWAYS_RETURN,
+
+  /* Indicate that the memory load references a vtable.  The expression
+     is of the form (plus (symbol_ref vtable_sym) (const_int offset)).  */
+  REG_VTABLE_REF
 };
 
 /* The base value for branch probability notes.  */
index eb25dca..d7fd68e 100644 (file)
@@ -1,3 +1,7 @@
+2001-10-11  Richard Henderson  <rth@redhat.com>
+
+       * g++.old-deja/g++.other/crash18.C: Add -S to options.
+
 2001-10-10  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
 
        * gcc.c-torture/compile/20011010-1.c: New.
index 789e316..335d8b9 100644 (file)
@@ -1,5 +1,5 @@
 // Build don't link:
-// Special g++ Options: -fvtable-gc
+// Special g++ Options: -fvtable-gc -S
 // Origin: Mark Mitchell <mitchell@codesourcery.com>
 
 struct S {
index 4b155b0..8a02e5b 100644 (file)
@@ -374,6 +374,13 @@ DEFTREECODE (ARRAY_REF, "array_ref", 'r', 2)
    of the range is taken from the type of the expression.  */
 DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 2)
 
+/* Vtable indexing.  Carries data useful for emitting information
+   for vtable garbage collection.
+   Operand 0: an array_ref (or equivalent expression)
+   Operand 1: the vtable base (must be a var_decl)
+   Operand 2: index into vtable (must be an integer_cst).  */
+DEFTREECODE (VTABLE_REF, "vtable_ref", 'r', 3)
+
 /* Constructor: return an aggregate value made from specified components.
    In C, this is used only for structure and array initializers.
    Also used for SET_TYPE in Chill (and potentially Pascal).
index 3123875..0d6dc76 100644 (file)
@@ -5297,3 +5297,32 @@ default_pe_asm_named_section (name, flags)
               (flags & SECTION_CODE ? "discard" : "same_size"));
     }
 }
+\f
+/* Used for vtable gc in GNU binutils.  Record that the pointer at OFFSET
+   from SYMBOL is used in all classes derived from SYMBOL.  */
+
+void
+assemble_vtable_entry (symbol, offset)
+     rtx symbol;
+     HOST_WIDE_INT offset;
+{
+  fputs ("\t.vtable_entry ", asm_out_file);
+  output_addr_const (asm_out_file, symbol);
+  fputs (", ", asm_out_file);
+  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, offset);
+  fputc ('\n', asm_out_file);
+}
+
+/* Used for vtable gc in GNU binutils.  Record the class heirarchy by noting
+   that the vtable symbol CHILD is derived from the vtable symbol PARENT.  */
+
+void
+assemble_vtable_inherit (child, parent)
+     rtx child, parent;
+{
+  fputs ("\t.vtable_inherit ", asm_out_file);
+  output_addr_const (asm_out_file, child);
+  fputs (", ", asm_out_file);
+  output_addr_const (asm_out_file, parent);
+  fputc ('\n', asm_out_file);
+}