+2012-07-31  Steven Bosscher  <steven@gcc.gnu.org>
+
+       PR pch/53880
+       * gengtype.c (struct walk_type_data): Add have_this_obj field.
+       (walk_type): For functions that take a this_obj argument and
+       that process fields with a GTY((length)) argument, write the
+       test that write_types_local_process_field will write also at the
+       head of the loop, effectively unswitching the loop.
+       (write_func_for_structure, write_local_func_for_structure): Clear
+       have_this_obj before calling walk_type.
+       (write_local_func_for_structure): Set have_this_obj before walk_type.
+       (write_array): Set have_this_obj for output of local pointer walking
+       functions but not for marker functions.
+       (write_types_local_process_field): Assert have_this_obj is set.
+
+       * rtl.h (simplify_using_condition): Adjust prototype using bitmap
+       from coretypes.h.
+
 2012-07-30  Nathan Froyd  <froydnj@gcc.gnu.org>
 
 
 
   bool fn_wants_lvalue;
   bool in_record_p;
   int loopcounter;
+  bool have_this_obj;
 };
 
 /* Print a mangled name representing T to OF.  */
              output_escaped_param (d, length, "length");
            else
              oprintf (d->of, "l%d", loopcounter);
+           if (d->have_this_obj)
+             /* Try to unswitch loops (see PR53880).  */
+             oprintf (d->of, ") && ((void *)%s == this_obj", oldval);
            oprintf (d->of, "); i%d++) {\n", loopcounter);
            d->indent += 2;
            d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
   d.prev_val[1] = "not valid postage"; /* Guarantee an error.  */
   d.prev_val[3] = "x";
   d.val = "(*x)";
+  d.have_this_obj = false;
 
   oprintf (d.of, "\n");
   oprintf (d.of, "void\n");
 static void
 write_types_local_process_field (type_p f, const struct walk_type_data *d)
 {
+  gcc_assert (d->have_this_obj);
   switch (f->kind)
     {
     case TYPE_POINTER:
           s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
           s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
   d.indent = 2;
+  d.have_this_obj = true;
   walk_type (s, &d);
   oprintf (d.of, "}\n");
 }
       oprintf (d.of, "{\n");
       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
       d.process_field = write_types_local_process_field;
+      d.have_this_obj = true;
       walk_type (v->type, &d);
       oprintf (f, "}\n\n");
     }
   oprintf (f, "{\n");
   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
   d.process_field = write_types_process_field;
+  d.have_this_obj = false;
   walk_type (v->type, &d);
   free (prevval3);
   oprintf (f, "}\n\n");
 
 
 /* In loop-iv.c  */
 extern rtx canon_condition (rtx);
-extern void simplify_using_condition (rtx, rtx *, struct bitmap_head_def *);
+extern void simplify_using_condition (rtx, rtx *, bitmap);
 
 /* In final.c  */
 extern unsigned int compute_alignments (void);