diff --git a/gdb/frame.c b/gdb/frame.c
index ad0cb92..a74deef 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1017,16 +1017,14 @@ do_frame_register_read (void *src, int regnum, gdb_byte *buf)
     return REG_VALID;
 }
 
-struct regcache *
+std::unique_ptr<struct regcache>
 frame_save_as_regcache (struct frame_info *this_frame)
 {
   struct address_space *aspace = get_frame_address_space (this_frame);
-  struct regcache *regcache = new regcache (get_frame_arch (this_frame),
-					    aspace);
-  struct cleanup *cleanups = make_cleanup_regcache_xfree (regcache);
+  std::unique_ptr<struct regcache> regcache
+    (new struct regcache (get_frame_arch (this_frame), aspace));
 
-  regcache_save (regcache, do_frame_register_read, this_frame);
-  discard_cleanups (cleanups);
+  regcache_save (regcache.get (), do_frame_register_read, this_frame);
   return regcache;
 }
 
@@ -1034,8 +1032,6 @@ void
 frame_pop (struct frame_info *this_frame)
 {
   struct frame_info *prev_frame;
-  struct regcache *scratch;
-  struct cleanup *cleanups;
 
   if (get_frame_type (this_frame) == DUMMY_FRAME)
     {
@@ -1062,8 +1058,8 @@ frame_pop (struct frame_info *this_frame)
      Save them in a scratch buffer so that there isn't a race between
      trying to extract the old values from the current regcache while
      at the same time writing new values into that same cache.  */
-  scratch = frame_save_as_regcache (prev_frame);
-  cleanups = make_cleanup_regcache_xfree (scratch);
+  std::unique_ptr<struct regcache> scratch
+    = frame_save_as_regcache (prev_frame);
 
   /* FIXME: cagney/2003-03-16: It should be possible to tell the
      target's register cache that it is about to be hit with a burst
@@ -1075,8 +1071,7 @@ frame_pop (struct frame_info *this_frame)
      (arguably a bug in the target code mind).  */
   /* Now copy those saved registers into the current regcache.
      Here, regcache_cpy() calls regcache_restore().  */
-  regcache_cpy (get_current_regcache (), scratch);
-  do_cleanups (cleanups);
+  regcache_cpy (get_current_regcache (), scratch.get ());
 
   /* We've made right mess of GDB's local state, just discard
      everything.  */
diff --git a/gdb/frame.h b/gdb/frame.h
index 3b00d36..0249857 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -679,7 +679,8 @@ extern void *frame_obstack_zalloc (unsigned long size);
   ((TYPE *) frame_obstack_zalloc ((NUMBER) * sizeof (TYPE)))
 
 /* Create a regcache, and copy the frame's registers into it.  */
-struct regcache *frame_save_as_regcache (struct frame_info *this_frame);
+std::unique_ptr<struct regcache> frame_save_as_regcache
+    (struct frame_info *this_frame);
 
 extern const struct block *get_frame_block (struct frame_info *,
 					    CORE_ADDR *addr_in_block);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index c06ef18..5e71949 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1031,22 +1031,20 @@ mi_cmd_data_list_register_names (const char *command, char **argv, int argc)
 void
 mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc)
 {
-  static struct regcache *this_regs = NULL;
+  static std::unique_ptr<struct regcache> this_regs;
   struct ui_out *uiout = current_uiout;
-  struct regcache *prev_regs;
+  std::unique_ptr<struct regcache> prev_regs;
   struct gdbarch *gdbarch;
   int regnum, numregs, changed;
   int i;
-  struct cleanup *cleanup;
 
   /* The last time we visited this function, the current frame's
      register contents were saved in THIS_REGS.  Move THIS_REGS over
      to PREV_REGS, and refresh THIS_REGS with the now-current register
      contents.  */
 
-  prev_regs = this_regs;
+  prev_regs = std::move (this_regs);
   this_regs = frame_save_as_regcache (get_selected_frame (NULL));
-  cleanup = make_cleanup_regcache_xfree (prev_regs);
 
   /* Note that the test for a valid register must include checking the
      gdbarch_register_name because gdbarch_num_regs may be allocated
@@ -1055,7 +1053,7 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc)
      will change depending upon the particular processor being
      debugged.  */
 
-  gdbarch = get_regcache_arch (this_regs);
+  gdbarch = get_regcache_arch (this_regs.get ());
   numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
 
   ui_out_emit_list list_emitter (uiout, "changed-registers");
@@ -1070,7 +1068,8 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc)
 	  if (gdbarch_register_name (gdbarch, regnum) == NULL
 	      || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
 	    continue;
-	  changed = register_changed_p (regnum, prev_regs, this_regs);
+	  changed = register_changed_p (regnum, prev_regs.get (),
+					this_regs.get ());
 	  if (changed < 0)
 	    error (_("-data-list-changed-registers: "
 		     "Unable to read register contents."));
@@ -1089,7 +1088,8 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc)
 	  && gdbarch_register_name (gdbarch, regnum) != NULL
 	  && *gdbarch_register_name (gdbarch, regnum) != '\000')
 	{
-	  changed = register_changed_p (regnum, prev_regs, this_regs);
+	  changed = register_changed_p (regnum, prev_regs.get (),
+					this_regs.get ());
 	  if (changed < 0)
 	    error (_("-data-list-changed-registers: "
 		     "Unable to read register contents."));
@@ -1099,7 +1099,6 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc)
       else
 	error (_("bad register number"));
     }
-  do_cleanups (cleanup);
 }
 
 static int
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 2faee42..5f313f8 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1363,13 +1363,12 @@ ppu2spu_sniffer (const struct frame_unwind *self,
 	    = FRAME_OBSTACK_CALLOC (1, struct ppu2spu_cache);
 
 	  struct address_space *aspace = get_frame_address_space (this_frame);
-	  struct regcache *regcache = new regcache (data.gdbarch, aspace);
-	  struct cleanup *cleanups = make_cleanup_regcache_xfree (regcache);
-	  regcache_save (regcache, ppu2spu_unwind_register, &data);
-	  discard_cleanups (cleanups);
+	  std::unique_ptr<struct regcache> regcache
+	    (new struct regcache (data.gdbarch, aspace));
+	  regcache_save (regcache.get (), ppu2spu_unwind_register, &data);
 
 	  cache->frame_id = frame_id_build (base, func);
-	  cache->regcache = regcache;
+	  cache->regcache = regcache.release ();
 	  *this_prologue_cache = cache;
 	  return 1;
 	}
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 54aed6c..ab6a651 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -241,18 +241,6 @@ regcache_get_ptid (const struct regcache *regcache)
   return regcache->ptid ();
 }
 
-static void
-do_regcache_xfree (void *data)
-{
-  delete (struct regcache *) data;
-}
-
-struct cleanup *
-make_cleanup_regcache_xfree (struct regcache *regcache)
-{
-  return make_cleanup (do_regcache_xfree, regcache);
-}
-
 /* Cleanup routines for invalidating a register.  */
 
 struct register_to_invalidate
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 4a430ae..3ecdb3b 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -35,8 +35,6 @@ extern struct regcache *get_thread_arch_aspace_regcache (ptid_t,
 							 struct gdbarch *,
 							 struct address_space *);
 
-struct cleanup *make_cleanup_regcache_xfree (struct regcache *regcache);
-
 /* Return REGCACHE's ptid.  */
 
 extern ptid_t regcache_get_ptid (const struct regcache *regcache);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index f77e37f..6d7a35e 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1267,7 +1267,7 @@ spu2ppu_sniffer (const struct frame_unwind *self,
 
       if (fi)
 	{
-	  cache->regcache = frame_save_as_regcache (fi);
+	  cache->regcache = frame_save_as_regcache (fi).release ();
 	  *this_prologue_cache = cache;
 	  return 1;
 	}
