Bug target/61997
[gcc.git] / gcc / dwarf2cfi.c
index 29779d6ad6a731ee1b0ac8df531c7a10c1271d82..f2d628cbe7ac39578be5e6c0493a846c726d4af1 100644 (file)
@@ -1,5 +1,5 @@
 /* Dwarf2 Call Frame Information helper routines.
-   Copyright (C) 1992-2013 Free Software Foundation, Inc.
+   Copyright (C) 1992-2014 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -24,8 +24,16 @@ along with GCC; see the file COPYING3.  If not see
 #include "version.h"
 #include "flags.h"
 #include "rtl.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "machmode.h"
+#include "hard-reg-set.h"
+#include "input.h"
 #include "function.h"
-#include "basic-block.h"
+#include "cfgbuild.h"
 #include "dwarf2.h"
 #include "dwarf2out.h"
 #include "dwarf2asm.h"
@@ -98,7 +106,7 @@ typedef struct GTY(()) reg_saved_in_data_struct {
 typedef struct
 {
   /* The insn that begins the trace.  */
-  rtx head;
+  rtx_insn *head;
 
   /* The row state at the beginning and end of the trace.  */
   dw_cfi_row *beg_row, *end_row;
@@ -111,7 +119,7 @@ typedef struct
   HOST_WIDE_INT beg_delay_args_size, end_delay_args_size;
 
   /* The first EH insn in the trace, where beg_delay_args_size must be set.  */
-  rtx eh_head;
+  rtx_insn *eh_head;
 
   /* The following variables contain data used in interpreting frame related
      expressions.  These are not part of the "real" row state as defined by
@@ -180,7 +188,7 @@ trace_info_hasher::equal (const value_type *a, const compare_type *b)
 /* The variables making up the pseudo-cfg, as described above.  */
 static vec<dw_trace_info> trace_info;
 static vec<dw_trace_info_ref> trace_work_list;
-static hash_table <trace_info_hasher> trace_index;
+static hash_table<trace_info_hasher> *trace_index;
 
 /* A vector of call frame insns for the CIE.  */
 cfi_vec cie_cfi_vec;
@@ -242,11 +250,12 @@ expand_builtin_dwarf_sp_column (void)
    which has mode MODE.  Initialize column C as a return address column.  */
 
 static void
-init_return_column_size (enum machine_mode mode, rtx mem, unsigned int c)
+init_return_column_size (machine_mode mode, rtx mem, unsigned int c)
 {
   HOST_WIDE_INT offset = c * GET_MODE_SIZE (mode);
   HOST_WIDE_INT size = GET_MODE_SIZE (Pmode);
-  emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
+  emit_move_insn (adjust_address (mem, mode, offset),
+                 gen_int_mode (size, mode));
 }
 
 /* Generate code to initialize the register size table.  */
@@ -255,7 +264,7 @@ void
 expand_builtin_init_dwarf_reg_sizes (tree address)
 {
   unsigned int i;
-  enum machine_mode mode = TYPE_MODE (char_type_node);
+  machine_mode mode = TYPE_MODE (char_type_node);
   rtx addr = expand_normal (address);
   rtx mem = gen_rtx_MEM (BLKmode, addr);
   bool wrote_return_column = false;
@@ -268,11 +277,9 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
       if (rnum < DWARF_FRAME_REGISTERS)
        {
          HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (mode);
-         enum machine_mode save_mode = reg_raw_mode[i];
          HOST_WIDE_INT size;
+         machine_mode save_mode = targetm.dwarf_frame_reg_mode (i);
 
-         if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
-           save_mode = choose_hard_reg_mode (i, 1, true);
          if (dnum == DWARF_FRAME_RETURN_COLUMN)
            {
              if (save_mode == VOIDmode)
@@ -300,15 +307,15 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
 
 \f
 static dw_trace_info *
-get_trace_info (rtx insn)
+get_trace_info (rtx_insn *insn)
 {
   dw_trace_info dummy;
   dummy.head = insn;
-  return trace_index.find_with_hash (&dummy, INSN_UID (insn));
+  return trace_index->find_with_hash (&dummy, INSN_UID (insn));
 }
 
 static bool
-save_point_p (rtx insn)
+save_point_p (rtx_insn *insn)
 {
   /* Labels, except those that are really jump tables.  */
   if (LABEL_P (insn))
@@ -353,7 +360,7 @@ need_data_align_sf_opcode (HOST_WIDE_INT off)
 static inline dw_cfi_ref
 new_cfi (void)
 {
-  dw_cfi_ref cfi = ggc_alloc_dw_cfi_node ();
+  dw_cfi_ref cfi = ggc_alloc<dw_cfi_node> ();
 
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0;
   cfi->dw_cfi_oprnd2.dw_cfi_reg_num = 0;
@@ -366,7 +373,7 @@ new_cfi (void)
 static dw_cfi_row *
 new_cfi_row (void)
 {
-  dw_cfi_row *row = ggc_alloc_cleared_dw_cfi_row ();
+  dw_cfi_row *row = ggc_cleared_alloc<dw_cfi_row> ();
 
   row->cfa.reg = INVALID_REGNUM;
 
@@ -378,7 +385,7 @@ new_cfi_row (void)
 static dw_cfi_row *
 copy_cfi_row (dw_cfi_row *src)
 {
-  dw_cfi_row *dst = ggc_alloc_dw_cfi_row ();
+  dw_cfi_row *dst = ggc_alloc<dw_cfi_row> ();
 
   *dst = *src;
   dst->reg_save = vec_safe_copy (src->reg_save);
@@ -457,9 +464,9 @@ update_row_reg_save (dw_cfi_row *row, unsigned column, dw_cfi_ref cfi)
    descriptor sequence.  */
 
 static void
-get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_struct *loc)
+get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_node *loc)
 {
-  struct dw_loc_descr_struct *ptr;
+  struct dw_loc_descr_node *ptr;
   cfa->offset = 0;
   cfa->base_offset = 0;
   cfa->indirect = 0;
@@ -752,7 +759,7 @@ def_cfa_0 (dw_cfa_location *old_cfa, dw_cfa_location *new_cfa)
       /* Construct a DW_CFA_def_cfa_expression instruction to
         calculate the CFA using a full location expression since no
         register-offset pair is available.  */
-      struct dw_loc_descr_struct *loc_list;
+      struct dw_loc_descr_node *loc_list;
 
       cfi->dw_cfi_opc = DW_CFA_def_cfa_expression;
       loc_list = build_cfa_loc (new_cfa, 0);
@@ -873,7 +880,7 @@ notice_args_size (rtx insn)
    data within the trace related to EH insns and args_size.  */
 
 static void
-notice_eh_throw (rtx insn)
+notice_eh_throw (rtx_insn *insn)
 {
   HOST_WIDE_INT args_size;
 
@@ -903,6 +910,7 @@ notice_eh_throw (rtx insn)
 static inline unsigned
 dwf_regno (const_rtx reg)
 {
+  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
   return DWARF_FRAME_REGNUM (REGNO (reg));
 }
 
@@ -1145,18 +1153,15 @@ dwarf2out_frame_debug_cfa_offset (rtx set)
   else
     {
       /* We have a PARALLEL describing where the contents of SRC live.
-        Queue register saves for each piece of the PARALLEL.  */
-      int par_index;
-      int limit;
+        Adjust the offset for each piece of the PARALLEL.  */
       HOST_WIDE_INT span_offset = offset;
 
       gcc_assert (GET_CODE (span) == PARALLEL);
 
-      limit = XVECLEN (span, 0);
-      for (par_index = 0; par_index < limit; par_index++)
+      const int par_len = XVECLEN (span, 0);
+      for (int par_index = 0; par_index < par_len; par_index++)
        {
          rtx elem = XVECEXP (span, 0, par_index);
-
          sregno = dwf_regno (src);
          reg_save (sregno, INVALID_REGNUM, span_offset);
          span_offset += GET_MODE_SIZE (GET_MODE (elem));
@@ -1225,10 +1230,31 @@ dwarf2out_frame_debug_cfa_expression (rtx set)
 static void
 dwarf2out_frame_debug_cfa_restore (rtx reg)
 {
-  unsigned int regno = dwf_regno (reg);
+  gcc_assert (REG_P (reg));
 
-  add_cfi_restore (regno);
-  update_row_reg_save (cur_row, regno, NULL);
+  rtx span = targetm.dwarf_register_span (reg);
+  if (!span)
+    {
+      unsigned int regno = dwf_regno (reg);
+      add_cfi_restore (regno);
+      update_row_reg_save (cur_row, regno, NULL);
+    }
+  else
+    {
+      /* We have a PARALLEL describing where the contents of REG live.
+        Restore the register for each piece of the PARALLEL.  */
+      gcc_assert (GET_CODE (span) == PARALLEL);
+
+      const int par_len = XVECLEN (span, 0);
+      for (int par_index = 0; par_index < par_len; par_index++)
+       {
+         reg = XVECEXP (span, 0, par_index);
+         gcc_assert (REG_P (reg));
+         unsigned int regno = dwf_regno (reg);
+         add_cfi_restore (regno);
+         update_row_reg_save (cur_row, regno, NULL);
+       }
+    }
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_WINDOW_SAVE.
@@ -1880,23 +1906,23 @@ dwarf2out_frame_debug_expr (rtx expr)
            }
        }
 
-      span = NULL;
       if (REG_P (src))
        span = targetm.dwarf_register_span (src);
+      else
+       span = NULL;
+
       if (!span)
        queue_reg_save (src, NULL_RTX, offset);
       else
        {
          /* We have a PARALLEL describing where the contents of SRC live.
             Queue register saves for each piece of the PARALLEL.  */
-         int par_index;
-         int limit;
          HOST_WIDE_INT span_offset = offset;
 
          gcc_assert (GET_CODE (span) == PARALLEL);
 
-         limit = XVECLEN (span, 0);
-         for (par_index = 0; par_index < limit; par_index++)
+         const int par_len = XVECLEN (span, 0);
+         for (int par_index = 0; par_index < par_len; par_index++)
            {
              rtx elem = XVECEXP (span, 0, par_index);
              queue_reg_save (elem, NULL_RTX, span_offset);
@@ -1915,16 +1941,16 @@ dwarf2out_frame_debug_expr (rtx expr)
    register to the stack.  */
 
 static void
-dwarf2out_frame_debug (rtx insn)
+dwarf2out_frame_debug (rtx_insn *insn)
 {
-  rtx note, n;
+  rtx note, n, pat;
   bool handled_one = false;
 
   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
     switch (REG_NOTE_KIND (note))
       {
       case REG_FRAME_RELATED_EXPR:
-       insn = XEXP (note, 0);
+       pat = XEXP (note, 0);
        goto do_frame_expr;
 
       case REG_CFA_DEF_CFA:
@@ -2016,14 +2042,14 @@ dwarf2out_frame_debug (rtx insn)
 
   if (!handled_one)
     {
-      insn = PATTERN (insn);
+      pat = PATTERN (insn);
     do_frame_expr:
-      dwarf2out_frame_debug_expr (insn);
+      dwarf2out_frame_debug_expr (pat);
 
       /* Check again.  A parallel can save and update the same register.
          We could probably check just once, here, but this is safer than
          removing the check at the start of the function.  */
-      if (clobbers_queued_reg_save (insn))
+      if (clobbers_queued_reg_save (pat))
        dwarf2out_flush_queued_reg_saves ();
     }
 }
@@ -2110,7 +2136,7 @@ static void
 add_cfis_to_fde (void)
 {
   dw_fde_ref fde = cfun->fde;
-  rtx insn, next;
+  rtx_insn *insn, *next;
   /* We always start with a function_begin label.  */
   bool first = false;
 
@@ -2175,7 +2201,7 @@ add_cfis_to_fde (void)
    trace from CUR_TRACE and CUR_ROW.  */
 
 static void
-maybe_record_trace_start (rtx start, rtx origin)
+maybe_record_trace_start (rtx_insn *start, rtx_insn *origin)
 {
   dw_trace_info *ti;
   HOST_WIDE_INT args_size;
@@ -2226,7 +2252,7 @@ maybe_record_trace_start (rtx start, rtx origin)
    and non-local goto edges.  */
 
 static void
-maybe_record_trace_start_abnormal (rtx start, rtx origin)
+maybe_record_trace_start_abnormal (rtx_insn *start, rtx_insn *origin)
 {
   HOST_WIDE_INT save_args_size, delta;
   dw_cfa_location save_cfa;
@@ -2262,34 +2288,33 @@ maybe_record_trace_start_abnormal (rtx start, rtx origin)
 /* ??? Sadly, this is in large part a duplicate of make_edges.  */
 
 static void
-create_trace_edges (rtx insn)
+create_trace_edges (rtx_insn *insn)
 {
-  rtx tmp, lab;
+  rtx tmp;
   int i, n;
 
   if (JUMP_P (insn))
     {
+      rtx_jump_table_data *table;
+
       if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
        return;
 
-      if (tablejump_p (insn, NULL, &tmp))
+      if (tablejump_p (insn, NULL, &table))
        {
-         rtvec vec;
-
-         tmp = PATTERN (tmp);
-         vec = XVEC (tmp, GET_CODE (tmp) == ADDR_DIFF_VEC);
+         rtvec vec = table->get_labels ();
 
          n = GET_NUM_ELEM (vec);
          for (i = 0; i < n; ++i)
            {
-             lab = XEXP (RTVEC_ELT (vec, i), 0);
+             rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0));
              maybe_record_trace_start (lab, insn);
            }
        }
       else if (computed_jump_p (insn))
        {
-         for (lab = forced_labels; lab; lab = XEXP (lab, 1))
-           maybe_record_trace_start (XEXP (lab, 0), insn);
+         for (rtx_insn_list *lab = forced_labels; lab; lab = lab->next ())
+           maybe_record_trace_start (lab->insn (), insn);
        }
       else if (returnjump_p (insn))
        ;
@@ -2298,13 +2323,14 @@ create_trace_edges (rtx insn)
          n = ASM_OPERANDS_LABEL_LENGTH (tmp);
          for (i = 0; i < n; ++i)
            {
-             lab = XEXP (ASM_OPERANDS_LABEL (tmp, i), 0);
+             rtx_insn *lab =
+               as_a <rtx_insn *> (XEXP (ASM_OPERANDS_LABEL (tmp, i), 0));
              maybe_record_trace_start (lab, insn);
            }
        }
       else
        {
-         lab = JUMP_LABEL (insn);
+         rtx_insn *lab = JUMP_LABEL_AS_INSN (insn);
          gcc_assert (lab != NULL);
          maybe_record_trace_start (lab, insn);
        }
@@ -2317,15 +2343,16 @@ create_trace_edges (rtx insn)
 
       /* Process non-local goto edges.  */
       if (can_nonlocal_goto (insn))
-       for (lab = nonlocal_goto_handler_labels; lab; lab = XEXP (lab, 1))
-         maybe_record_trace_start_abnormal (XEXP (lab, 0), insn);
+       for (rtx_insn_list *lab = nonlocal_goto_handler_labels;
+            lab;
+            lab = lab->next ())
+         maybe_record_trace_start_abnormal (lab->insn (), insn);
     }
-  else if (GET_CODE (PATTERN (insn)) == SEQUENCE)
+  else if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
     {
-      rtx seq = PATTERN (insn);
-      int i, n = XVECLEN (seq, 0);
+      int i, n = seq->len ();
       for (i = 0; i < n; ++i)
-       create_trace_edges (XVECEXP (seq, 0, i));
+       create_trace_edges (seq->insn (i));
       return;
     }
 
@@ -2341,7 +2368,7 @@ create_trace_edges (rtx insn)
 /* A subroutine of scan_trace.  Do what needs to be done "after" INSN.  */
 
 static void
-scan_insn_after (rtx insn)
+scan_insn_after (rtx_insn *insn)
 {
   if (RTX_FRAME_RELATED_P (insn))
     dwarf2out_frame_debug (insn);
@@ -2354,7 +2381,7 @@ scan_insn_after (rtx insn)
 static void
 scan_trace (dw_trace_info *trace)
 {
-  rtx prev, insn = trace->head;
+  rtx_insn *prev, *insn = trace->head;
   dw_cfa_location this_cfa;
 
   if (dump_file)
@@ -2375,7 +2402,7 @@ scan_trace (dw_trace_info *trace)
        insn;
        prev = insn, insn = NEXT_INSN (insn))
     {
-      rtx control;
+      rtx_insn *control;
 
       /* Do everything that happens "before" the insn.  */
       add_cfi_insn = prev;
@@ -2400,12 +2427,12 @@ scan_trace (dw_trace_info *trace)
 
       /* Handle all changes to the row state.  Sequences require special
         handling for the positioning of the notes.  */
-      if (GET_CODE (PATTERN (insn)) == SEQUENCE)
+      if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
        {
-         rtx elt, pat = PATTERN (insn);
-         int i, n = XVECLEN (pat, 0);
+         rtx_insn *elt;
+         int i, n = pat->len ();
 
-         control = XVECEXP (pat, 0, 0);
+         control = pat->insn (0);
          if (can_throw_internal (control))
            notice_eh_throw (control);
          dwarf2out_flush_queued_reg_saves ();
@@ -2417,7 +2444,7 @@ scan_trace (dw_trace_info *trace)
              gcc_assert (!RTX_FRAME_RELATED_P (control));
              gcc_assert (!find_reg_note (control, REG_ARGS_SIZE, NULL));
 
-             elt = XVECEXP (pat, 0, 1);
+             elt = pat->insn (1);
 
              if (INSN_FROM_TARGET_P (elt))
                {
@@ -2472,7 +2499,7 @@ scan_trace (dw_trace_info *trace)
 
          for (i = 1; i < n; ++i)
            {
-             elt = XVECEXP (pat, 0, i);
+             elt = pat->insn (i);
              scan_insn_after (elt);
            }
 
@@ -2554,10 +2581,10 @@ create_cfi_notes (void)
 
 /* Return the insn before the first NOTE_INSN_CFI after START.  */
 
-static rtx
-before_next_cfi_note (rtx start)
+static rtx_insn *
+before_next_cfi_note (rtx_insn *start)
 {
-  rtx prev = start;
+  rtx_insn *prev = start;
   while (start)
     {
       if (NOTE_P (start) && NOTE_KIND (start) == NOTE_INSN_CFI)
@@ -2652,7 +2679,7 @@ connect_traces (void)
 
       if (dump_file && add_cfi_insn != ti->head)
        {
-         rtx note;
+         rtx_insn *note;
 
          fprintf (dump_file, "Fixup between trace %u and %u:\n",
                   prev_ti->id, ti->id);
@@ -2703,7 +2730,7 @@ create_pseudo_cfg (void)
 {
   bool saw_barrier, switch_sections;
   dw_trace_info ti;
-  rtx insn;
+  rtx_insn *insn;
   unsigned i;
 
   /* The first trace begins at the start of the function,
@@ -2742,7 +2769,7 @@ create_pseudo_cfg (void)
          memset (&ti, 0, sizeof (ti));
          ti.head = insn;
          ti.switch_sections = switch_sections;
-         ti.id = trace_info.length () - 1;
+         ti.id = trace_info.length ();
          trace_info.safe_push (ti);
 
          saw_barrier = false;
@@ -2752,18 +2779,19 @@ create_pseudo_cfg (void)
 
   /* Create the trace index after we've finished building trace_info,
      avoiding stale pointer problems due to reallocation.  */
-  trace_index.create (trace_info.length ());
+  trace_index
+    = new hash_table<trace_info_hasher> (trace_info.length ());
   dw_trace_info *tp;
   FOR_EACH_VEC_ELT (trace_info, i, tp)
     {
       dw_trace_info **slot;
 
       if (dump_file)
-       fprintf (dump_file, "Creating trace %u : start at %s %d%s\n", i,
+       fprintf (dump_file, "Creating trace %u : start at %s %d%s\n", tp->id,
                 rtx_name[(int) GET_CODE (tp->head)], INSN_UID (tp->head),
                 tp->switch_sections ? " (section switch)" : "");
 
-      slot = trace_index.find_slot_with_hash (tp, INSN_UID (tp->head), INSERT);
+      slot = trace_index->find_slot_with_hash (tp, INSN_UID (tp->head), INSERT);
       gcc_assert (*slot == NULL);
       *slot = tp;
     }
@@ -2840,14 +2868,14 @@ create_cie_data (void)
   dw_stack_pointer_regnum = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM);
   dw_frame_pointer_regnum = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);
 
-  memset (&cie_trace, 0, sizeof(cie_trace));
+  memset (&cie_trace, 0, sizeof (cie_trace));
   cur_trace = &cie_trace;
 
   add_cfi_vec = &cie_cfi_vec;
   cie_cfi_row = cur_row = new_cfi_row ();
 
   /* On entry, the Canonical Frame Address is at SP.  */
-  memset(&loc, 0, sizeof (loc));
+  memset (&loc, 0, sizeof (loc));
   loc.reg = dw_stack_pointer_regnum;
   loc.offset = INCOMING_FRAME_SP_OFFSET;
   def_cfa_1 (&loc);
@@ -2870,7 +2898,7 @@ create_cie_data (void)
        case 0:
          break;
        case 1:
-         cie_return_save = ggc_alloc_reg_saved_in_data ();
+         cie_return_save = ggc_alloc<reg_saved_in_data> ();
          *cie_return_save = cie_trace.regs_saved_in_regs[0];
          cie_trace.regs_saved_in_regs.release ();
          break;
@@ -2914,7 +2942,8 @@ execute_dwarf2_frame (void)
   }
   trace_info.release ();
 
-  trace_index.dispose ();
+  delete trace_index;
+  trace_index = NULL;
 
   return 0;
 }
@@ -3267,7 +3296,7 @@ dump_cfi_row (FILE *f, dw_cfi_row *row)
   if (!cfi)
     {
       dw_cfa_location dummy;
-      memset(&dummy, 0, sizeof(dummy));
+      memset (&dummy, 0, sizeof (dummy));
       dummy.reg = INVALID_REGNUM;
       cfi = def_cfa_0 (&dummy, &row->cfa);
     }
@@ -3355,8 +3384,36 @@ dwarf2out_do_cfi_asm (void)
   return true;
 }
 
-static bool
-gate_dwarf2_frame (void)
+namespace {
+
+const pass_data pass_data_dwarf2_frame =
+{
+  RTL_PASS, /* type */
+  "dwarf2", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_FINAL, /* tv_id */
+  0, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_dwarf2_frame : public rtl_opt_pass
+{
+public:
+  pass_dwarf2_frame (gcc::context *ctxt)
+    : rtl_opt_pass (pass_data_dwarf2_frame, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual bool gate (function *);
+  virtual unsigned int execute (function *) { return execute_dwarf2_frame (); }
+
+}; // class pass_dwarf2_frame
+
+bool
+pass_dwarf2_frame::gate (function *)
 {
 #ifndef HAVE_prologue
   /* Targets which still implement the prologue in assembler text
@@ -3370,24 +3427,12 @@ gate_dwarf2_frame (void)
   return dwarf2out_do_frame ();
 }
 
-struct rtl_opt_pass pass_dwarf2_frame =
-{
- {
-  RTL_PASS,
-  "dwarf2",                    /* name */
-  OPTGROUP_NONE,                /* optinfo_flags */
-  gate_dwarf2_frame,           /* gate */
-  execute_dwarf2_frame,                /* execute */
-  NULL,                                /* sub */
-  NULL,                                /* next */
-  0,                           /* static_pass_number */
-  TV_FINAL,                    /* tv_id */
-  0,                           /* properties_required */
-  0,                           /* properties_provided */
-  0,                           /* properties_destroyed */
-  0,                           /* todo_flags_start */
-  0                            /* todo_flags_finish */
- }
-};
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_dwarf2_frame (gcc::context *ctxt)
+{
+  return new pass_dwarf2_frame (ctxt);
+}
 
 #include "gt-dwarf2cfi.h"