+2016-12-08 David Malcolm <dmalcolm@redhat.com>
+
+ * emit-rtl.c (gen_reg_rtx): Move regno_pointer_align and
+ regno_reg_rtx resizing logic to...
+ (emit_status::ensure_regno_capacity): ...this new method,
+ and ensure that the buffers are large enough.
+ (init_emit): Allocate regno_reg_rtx using ggc_cleared_vec_alloc
+ rather than ggc_vec_alloc.
+ * function.h (emit_status::ensure_regno_capacity): New method.
+
2016-12-08 Dmitry Vyukov <dvyukov@google.com>
* opts.c (finish_options): Enable
/* Do not call gen_reg_rtx with uninitialized crtl. */
gcc_assert (crtl->emit.regno_pointer_align_length);
- /* Make sure regno_pointer_align, and regno_reg_rtx are large
- enough to have an element for this pseudo reg number. */
+ crtl->emit.ensure_regno_capacity ();
+ gcc_assert (reg_rtx_no < crtl->emit.regno_pointer_align_length);
- if (reg_rtx_no == crtl->emit.regno_pointer_align_length)
- {
- int old_size = crtl->emit.regno_pointer_align_length;
- char *tmp;
- rtx *new1;
+ val = gen_raw_REG (mode, reg_rtx_no);
+ regno_reg_rtx[reg_rtx_no++] = val;
+ return val;
+}
- tmp = XRESIZEVEC (char, crtl->emit.regno_pointer_align, old_size * 2);
- memset (tmp + old_size, 0, old_size);
- crtl->emit.regno_pointer_align = (unsigned char *) tmp;
+/* Make sure m_regno_pointer_align, and regno_reg_rtx are large
+ enough to have elements in the range 0 <= idx <= reg_rtx_no. */
- new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, old_size * 2);
- memset (new1 + old_size, 0, old_size * sizeof (rtx));
- regno_reg_rtx = new1;
+void
+emit_status::ensure_regno_capacity ()
+{
+ int old_size = regno_pointer_align_length;
- crtl->emit.regno_pointer_align_length = old_size * 2;
- }
+ if (reg_rtx_no < old_size)
+ return;
- val = gen_raw_REG (mode, reg_rtx_no);
- regno_reg_rtx[reg_rtx_no++] = val;
- return val;
+ int new_size = old_size * 2;
+ while (reg_rtx_no >= new_size)
+ new_size *= 2;
+
+ char *tmp = XRESIZEVEC (char, regno_pointer_align, new_size);
+ memset (tmp + old_size, 0, new_size - old_size);
+ regno_pointer_align = (unsigned char *) tmp;
+
+ rtx *new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, new_size);
+ memset (new1 + old_size, 0, (new_size - old_size) * sizeof (rtx));
+ regno_reg_rtx = new1;
+
+ crtl->emit.regno_pointer_align_length = new_size;
}
/* Return TRUE if REG is a PARM_DECL, FALSE otherwise. */
crtl->emit.regno_pointer_align
= XCNEWVEC (unsigned char, crtl->emit.regno_pointer_align_length);
- regno_reg_rtx = ggc_vec_alloc<rtx> (crtl->emit.regno_pointer_align_length);
+ regno_reg_rtx
+ = ggc_cleared_vec_alloc<rtx> (crtl->emit.regno_pointer_align_length);
/* Put copies of all the hard registers into regno_reg_rtx. */
memcpy (regno_reg_rtx,