diff mbox

[RFC] add auto_bitmap

Message ID 1384427080-13613-1-git-send-email-tsaunders@mozilla.com
State New
Headers show

Commit Message

Trevor Saunders Nov. 14, 2013, 11:04 a.m. UTC
From: Trevor Saunders <tsaunders@mozilla.com>

Hi,

this patch adds and starts to use a class auto_bitmap, which is a very thin
wrapper around bitmap.  Its advantage is that it takes care of delocation
automatically.  So you can do things like

int
f ()
{
  auto_bitmap x;
  // do stuff with x
}

Another advantage of this class is it puts the bitmap_head struct on the stack
instead of mallocing it or using a obstack.

I Think the biggest question is if I should make auto_bitmap a full c++ified
wrapper around   bitmap or if I should contiune just taking the address of it
and passing it as a bitmap, but other comments are of course welcome too.

Trev

Comments

Richard Biener Nov. 14, 2013, 2:52 p.m. UTC | #1
On Thu, Nov 14, 2013 at 12:04 PM,  <tsaunders@mozilla.com> wrote:
> From: Trevor Saunders <tsaunders@mozilla.com>
>
> Hi,
>
> this patch adds and starts to use a class auto_bitmap, which is a very thin
> wrapper around bitmap.  Its advantage is that it takes care of delocation
> automatically.  So you can do things like
>
> int
> f ()
> {
>   auto_bitmap x;
>   // do stuff with x
> }
>
> Another advantage of this class is it puts the bitmap_head struct on the stack
> instead of mallocing it or using a obstack.

Hm, but then eventually you increase the lifetime of the bitmap
until the scope closes.

Why not give bitmap_head a constructor/destructor and allow
auto use of that.  Isn't that exactly what should get 'auto' handling
automagically?

Richard.

> I Think the biggest question is if I should make auto_bitmap a full c++ified
> wrapper around   bitmap or if I should contiune just taking the address of it
> and passing it as a bitmap, but other comments are of course welcome too.
>
> Trev
>
>
> diff --git a/gcc/bitmap.h b/gcc/bitmap.h
> index b3cb5da..78901fa 100644
> --- a/gcc/bitmap.h
> +++ b/gcc/bitmap.h
> @@ -312,6 +312,14 @@ extern hashval_t bitmap_hash (const_bitmap);
>  #define BITMAP_FREE(BITMAP) \
>         ((void) (bitmap_obstack_free ((bitmap) BITMAP), (BITMAP) = (bitmap) NULL))
>
> +/* bitmap with automatic management of resources. */
> +class auto_bitmap : public bitmap_head_def
> +{
> +public:
> +  auto_bitmap (bitmap_obstack *o = &bitmap_default_obstack) { bitmap_initialize_stat (this, o); }
> +  ~auto_bitmap () { bitmap_clear (this); }
> +};
> +
>  /* Iterator for bitmaps.  */
>
>  typedef struct
> diff --git a/gcc/bt-load.c b/gcc/bt-load.c
> index 5384d01..819bcbb 100644
> --- a/gcc/bt-load.c
> +++ b/gcc/bt-load.c
> @@ -1072,7 +1072,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
>              target registers live over the merged range.  */
>           int btr;
>           HARD_REG_SET combined_btrs_live;
> -         bitmap combined_live_range = BITMAP_ALLOC (NULL);
> +         auto_bitmap combined_live_range;
>           btr_user user;
>
>           if (other_def->live_range == NULL)
> @@ -1081,10 +1081,10 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
>               btr_def_live_range (other_def, &dummy_btrs_live_in_range);
>             }
>           COPY_HARD_REG_SET (combined_btrs_live, *btrs_live_in_range);
> -         bitmap_copy (combined_live_range, def->live_range);
> +         bitmap_copy (&combined_live_range, def->live_range);
>
>           for (user = other_def->uses; user != NULL; user = user->next)
> -           augment_live_range (combined_live_range, &combined_btrs_live,
> +           augment_live_range (&combined_live_range, &combined_btrs_live,
>                                 def->bb, user->bb,
>                                 (flag_btr_bb_exclusive
>                                  || user->insn != BB_END (def->bb)
> @@ -1121,7 +1121,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
>                                               REGNO (user->use)));
>               clear_btr_from_live_range (other_def);
>               other_def->uses = NULL;
> -             bitmap_copy (def->live_range, combined_live_range);
> +             bitmap_copy (def->live_range, &combined_live_range);
>               if (other_def->btr == btr && other_def->other_btr_uses_after_use)
>                 def->other_btr_uses_after_use = 1;
>               COPY_HARD_REG_SET (*btrs_live_in_range, combined_btrs_live);
> @@ -1130,7 +1130,6 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
>               delete_insn (other_def->insn);
>
>             }
> -         BITMAP_FREE (combined_live_range);
>         }
>      }
>  }
> diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
> index 3ff8e84..4510c0b 100644
> --- a/gcc/cfgloop.c
> +++ b/gcc/cfgloop.c
> @@ -917,7 +917,6 @@ get_loop_body_in_bfs_order (const struct loop *loop)
>  {
>    basic_block *blocks;
>    basic_block bb;
> -  bitmap visited;
>    unsigned int i = 0;
>    unsigned int vc = 1;
>
> @@ -925,7 +924,7 @@ get_loop_body_in_bfs_order (const struct loop *loop)
>    gcc_assert (loop->latch != EXIT_BLOCK_PTR);
>
>    blocks = XNEWVEC (basic_block, loop->num_nodes);
> -  visited = BITMAP_ALLOC (NULL);
> +  auto_bitmap visited;
>
>    bb = loop->header;
>    while (i < loop->num_nodes)
> @@ -933,7 +932,7 @@ get_loop_body_in_bfs_order (const struct loop *loop)
>        edge e;
>        edge_iterator ei;
>
> -      if (bitmap_set_bit (visited, bb->index))
> +      if (bitmap_set_bit (&visited, bb->index))
>         /* This basic block is now visited */
>         blocks[i++] = bb;
>
> @@ -941,7 +940,7 @@ get_loop_body_in_bfs_order (const struct loop *loop)
>         {
>           if (flow_bb_inside_loop_p (loop, e->dest))
>             {
> -             if (bitmap_set_bit (visited, e->dest->index))
> +             if (bitmap_set_bit (&visited, e->dest->index))
>                 blocks[i++] = e->dest;
>             }
>         }
> @@ -951,7 +950,6 @@ get_loop_body_in_bfs_order (const struct loop *loop)
>        bb = blocks[vc++];
>      }
>
> -  BITMAP_FREE (visited);
>    return blocks;
>  }
>
> diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
> index ae8ba3c..a512813 100644
> --- a/gcc/ipa-reference.c
> +++ b/gcc/ipa-reference.c
> @@ -960,7 +960,7 @@ ipa_reference_write_optimization_summary (void)
>    unsigned int count = 0;
>    int ltrans_statics_bitcount = 0;
>    lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
> -  bitmap ltrans_statics = BITMAP_ALLOC (NULL);
> +  auto_bitmap ltrans_statics;
>    int i;
>
>    reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
> @@ -975,7 +975,7 @@ ipa_reference_write_optimization_summary (void)
>           && referenced_from_this_partition_p (&vnode->ref_list, encoder))
>         {
>           tree decl = vnode->decl;
> -         bitmap_set_bit (ltrans_statics, DECL_UID (decl));
> +         bitmap_set_bit (&ltrans_statics, DECL_UID (decl));
>           splay_tree_insert (reference_vars_to_consider,
>                              DECL_UID (decl), (splay_tree_value)decl);
>           ltrans_statics_bitcount ++;
> @@ -988,13 +988,13 @@ ipa_reference_write_optimization_summary (void)
>        {
>         symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
>         cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
> -       if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
> +       if (cnode && write_node_summary_p (cnode, encoder, &ltrans_statics))
>           count++;
>        }
>
>    streamer_write_uhwi_stream (ob->main_stream, count);
>    if (count)
> -    stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
> +    stream_out_bitmap (ob, &ltrans_statics, &ltrans_statics,
>                        -1);
>
>    /* Process all of the functions.  */
> @@ -1003,7 +1003,7 @@ ipa_reference_write_optimization_summary (void)
>        {
>         symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
>         cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
> -       if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
> +       if (cnode && write_node_summary_p (cnode, encoder, &ltrans_statics))
>           {
>             ipa_reference_optimization_summary_t info;
>             int node_ref;
> @@ -1012,13 +1012,12 @@ ipa_reference_write_optimization_summary (void)
>             node_ref = lto_symtab_encoder_encode (encoder, snode);
>             streamer_write_uhwi_stream (ob->main_stream, node_ref);
>
> -           stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
> +           stream_out_bitmap (ob, info->statics_not_read, &ltrans_statics,
>                                ltrans_statics_bitcount);
> -           stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
> +           stream_out_bitmap (ob, info->statics_not_written, &ltrans_statics,
>                                ltrans_statics_bitcount);
>           }
>        }
> -  BITMAP_FREE (ltrans_statics);
>    lto_destroy_simple_output_block (ob);
>    splay_tree_delete (reference_vars_to_consider);
>  }
> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
> index df0a44e..d0bce24 100644
> --- a/gcc/ipa-split.c
> +++ b/gcc/ipa-split.c
> @@ -195,7 +195,7 @@ static bool
>  verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
>                      basic_block return_bb)
>  {
> -  bitmap seen = BITMAP_ALLOC (NULL);
> +  auto_bitmap seen;
>    vec<basic_block> worklist = vNULL;
>    edge e;
>    edge_iterator ei;
> @@ -206,7 +206,7 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
>         && !bitmap_bit_p (current->split_bbs, e->src->index))
>        {
>          worklist.safe_push (e->src);
> -       bitmap_set_bit (seen, e->src->index);
> +       bitmap_set_bit (&seen, e->src->index);
>        }
>
>    while (!worklist.is_empty ())
> @@ -216,7 +216,7 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
>
>        FOR_EACH_EDGE (e, ei, bb->preds)
>         if (e->src != ENTRY_BLOCK_PTR
> -           && bitmap_set_bit (seen, e->src->index))
> +           && bitmap_set_bit (&seen, e->src->index))
>           {
>             gcc_checking_assert (!bitmap_bit_p (current->split_bbs,
>                                                 e->src->index));
> @@ -274,7 +274,6 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
>         }
>      }
>  done:
> -  BITMAP_FREE (seen);
>    worklist.release ();
>    return ok;
>  }
> diff --git a/gcc/ira-color.c b/gcc/ira-color.c
> index 295cd532..c27f920 100644
> --- a/gcc/ira-color.c
> +++ b/gcc/ira-color.c
> @@ -4124,20 +4124,20 @@ ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
>    bool changed_p;
>    ira_allocno_t a;
>    HARD_REG_SET forbidden_regs;
> -  bitmap temp = BITMAP_ALLOC (NULL);
> +  auto_bitmap temp;
>
>    /* Add pseudos which conflict with pseudos already in
>       SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS.  This is preferable
>       to allocating in two steps as some of the conflicts might have
>       a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS.  */
>    for (i = 0; i < num; i++)
> -    bitmap_set_bit (temp, spilled_pseudo_regs[i]);
> +    bitmap_set_bit (&temp, spilled_pseudo_regs[i]);
>
>    for (i = 0, n = num; i < n; i++)
>      {
>        int nr, j;
>        int regno = spilled_pseudo_regs[i];
> -      bitmap_set_bit (temp, regno);
> +      bitmap_set_bit (&temp, regno);
>
>        a = ira_regno_allocno_map[regno];
>        nr = ALLOCNO_NUM_OBJECTS (a);
> @@ -4152,7 +4152,7 @@ ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
>               ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
>               if (ALLOCNO_HARD_REGNO (conflict_a) < 0
>                   && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
> -                 && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
> +                 && bitmap_set_bit (&temp, ALLOCNO_REGNO (conflict_a)))
>                 {
>                   spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
>                   /* ?!? This seems wrong.  */
> @@ -4190,7 +4190,6 @@ ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
>           changed_p = true;
>         }
>      }
> -  BITMAP_FREE (temp);
>    return changed_p;
>  }
>
> diff --git a/gcc/ira.c b/gcc/ira.c
> index 2ef69cb..c03c7ee 100644
> --- a/gcc/ira.c
> +++ b/gcc/ira.c
> @@ -3445,9 +3445,9 @@ static int
>  update_equiv_regs (void)
>  {
>    rtx insn;
> +  auto_bitmap cleared_regs;
>    basic_block bb;
>    int loop_depth;
> -  bitmap cleared_regs;
>    bool *pdx_subregs;
>
>    /* We need to keep track of whether or not we recorded a LABEL_REF so
> @@ -3757,7 +3757,6 @@ update_equiv_regs (void)
>         }
>      }
>
> -  cleared_regs = BITMAP_ALLOC (NULL);
>    /* Now scan all regs killed in an insn to see if any of them are
>       registers only used that once.  If so, see if we can replace the
>       reference with the equivalent form.  If we can, delete the
> @@ -3856,7 +3855,7 @@ update_equiv_regs (void)
>                         = XEXP (reg_equiv[regno].init_insns, 1);
>
>                       ira_reg_equiv[regno].init_insns = NULL_RTX;
> -                     bitmap_set_bit (cleared_regs, regno);
> +                     bitmap_set_bit (&cleared_regs, regno);
>                     }
>                   /* Move the initialization of the register to just before
>                      INSN.  Update the flow information.  */
> @@ -3890,23 +3889,23 @@ update_equiv_regs (void)
>
>                       ira_reg_equiv[regno].init_insns
>                         = gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
> -                     bitmap_set_bit (cleared_regs, regno);
> +                     bitmap_set_bit (&cleared_regs, regno);
>                     }
>                 }
>             }
>         }
>      }
>
> -  if (!bitmap_empty_p (cleared_regs))
> +  if (!bitmap_empty_p (&cleared_regs))
>      {
>        FOR_EACH_BB (bb)
>         {
> -         bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
> -         bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
> +         bitmap_and_compl_into (DF_LR_IN (bb), &cleared_regs);
> +         bitmap_and_compl_into (DF_LR_OUT (bb), &cleared_regs);
>           if (! df_live)
>             continue;
> -         bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
> -         bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
> +         bitmap_and_compl_into (DF_LIVE_IN (bb), &cleared_regs);
> +         bitmap_and_compl_into (DF_LIVE_OUT (bb), &cleared_regs);
>         }
>
>        /* Last pass - adjust debug insns referencing cleared regs.  */
> @@ -3918,14 +3917,12 @@ update_equiv_regs (void)
>               INSN_VAR_LOCATION_LOC (insn)
>                 = simplify_replace_fn_rtx (old_loc, NULL_RTX,
>                                            adjust_cleared_regs,
> -                                          (void *) cleared_regs);
> +                                          (void *) &cleared_regs);
>               if (old_loc != INSN_VAR_LOCATION_LOC (insn))
>                 df_insn_rescan (insn);
>             }
>      }
>
> -  BITMAP_FREE (cleared_regs);
> -
>    out:
>    /* Clean up.  */
>
> @@ -4106,8 +4103,8 @@ build_insn_chain (void)
>    basic_block bb;
>    struct insn_chain *c = NULL;
>    struct insn_chain *next = NULL;
> -  bitmap live_relevant_regs = BITMAP_ALLOC (NULL);
> -  bitmap elim_regset = BITMAP_ALLOC (NULL);
> +  auto_bitmap live_relevant_regs;
> +  auto_bitmap elim_regset;
>    /* live_subregs is a vector used to keep accurate information about
>       which hardregs are live in multiword pseudos.  live_subregs and
>       live_subregs_used are indexed by pseudo number.  The live_subreg
> @@ -4116,31 +4113,31 @@ build_insn_chain (void)
>       live_subreg[allocno] is number of bytes that the pseudo can
>       occupy.  */
>    sbitmap *live_subregs = XCNEWVEC (sbitmap, max_regno);
> -  bitmap live_subregs_used = BITMAP_ALLOC (NULL);
> +  auto_bitmap live_subregs_used;
>
>    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
>      if (TEST_HARD_REG_BIT (eliminable_regset, i))
> -      bitmap_set_bit (elim_regset, i);
> +      bitmap_set_bit (&elim_regset, i);
>    FOR_EACH_BB_REVERSE (bb)
>      {
>        bitmap_iterator bi;
>        rtx insn;
>
> -      CLEAR_REG_SET (live_relevant_regs);
> -      bitmap_clear (live_subregs_used);
> +      CLEAR_REG_SET (&live_relevant_regs);
> +      bitmap_clear (&live_subregs_used);
>
>        EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), 0, i, bi)
>         {
>           if (i >= FIRST_PSEUDO_REGISTER)
>             break;
> -         bitmap_set_bit (live_relevant_regs, i);
> +         bitmap_set_bit (&live_relevant_regs, i);
>         }
>
>        EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb),
>                                 FIRST_PSEUDO_REGISTER, i, bi)
>         {
>           if (pseudo_for_reload_consideration_p (i))
> -           bitmap_set_bit (live_relevant_regs, i);
> +           bitmap_set_bit (&live_relevant_regs, i);
>         }
>
>        FOR_BB_INSNS_REVERSE (bb, insn)
> @@ -4197,8 +4194,8 @@ build_insn_chain (void)
>                               + GET_MODE_SIZE (GET_MODE (reg));
>
>                             init_live_subregs
> -                             (bitmap_bit_p (live_relevant_regs, regno),
> -                              live_subregs, live_subregs_used, regno, reg);
> +                             (bitmap_bit_p (&live_relevant_regs, regno),
> +                              live_subregs, &live_subregs_used, regno, reg);
>
>                             if (!DF_REF_FLAGS_IS_SET
>                                 (def, DF_REF_STRICT_LOW_PART))
> @@ -4223,14 +4220,14 @@ build_insn_chain (void)
>
>                             if (bitmap_empty_p (live_subregs[regno]))
>                               {
> -                               bitmap_clear_bit (live_subregs_used, regno);
> -                               bitmap_clear_bit (live_relevant_regs, regno);
> +                               bitmap_clear_bit (&live_subregs_used, regno);
> +                               bitmap_clear_bit (&live_relevant_regs, regno);
>                               }
>                             else
>                               /* Set live_relevant_regs here because
>                                  that bit has to be true to get us to
>                                  look at the live_subregs fields.  */
> -                             bitmap_set_bit (live_relevant_regs, regno);
> +                             bitmap_set_bit (&live_relevant_regs, regno);
>                           }
>                         else
>                           {
> @@ -4241,15 +4238,15 @@ build_insn_chain (void)
>                                modeling the def as a killing def.  */
>                             if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL))
>                               {
> -                               bitmap_clear_bit (live_subregs_used, regno);
> -                               bitmap_clear_bit (live_relevant_regs, regno);
> +                               bitmap_clear_bit (&live_subregs_used, regno);
> +                               bitmap_clear_bit (&live_relevant_regs, regno);
>                               }
>                           }
>                       }
>                   }
>
> -             bitmap_and_compl_into (live_relevant_regs, elim_regset);
> -             bitmap_copy (&c->live_throughout, live_relevant_regs);
> +             bitmap_and_compl_into (&live_relevant_regs, &elim_regset);
> +             bitmap_copy (&c->live_throughout, &live_relevant_regs);
>
>               if (NONDEBUG_INSN_P (insn))
>                 for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
> @@ -4270,7 +4267,7 @@ build_insn_chain (void)
>                       continue;
>
>                     /* Add the last use of each var to dead_or_set.  */
> -                   if (!bitmap_bit_p (live_relevant_regs, regno))
> +                   if (!bitmap_bit_p (&live_relevant_regs, regno))
>                       {
>                         if (regno < FIRST_PSEUDO_REGISTER)
>                           {
> @@ -4294,8 +4291,8 @@ build_insn_chain (void)
>                               + GET_MODE_SIZE (GET_MODE (reg));
>
>                             init_live_subregs
> -                             (bitmap_bit_p (live_relevant_regs, regno),
> -                              live_subregs, live_subregs_used, regno, reg);
> +                             (bitmap_bit_p (&live_relevant_regs, regno),
> +                              live_subregs, &live_subregs_used, regno, reg);
>
>                             /* Ignore the paradoxical bits.  */
>                             if (last > SBITMAP_SIZE (live_subregs[regno]))
> @@ -4312,8 +4309,8 @@ build_insn_chain (void)
>                              effectively saying do not use the subregs
>                              because we are reading the whole
>                              pseudo.  */
> -                         bitmap_clear_bit (live_subregs_used, regno);
> -                       bitmap_set_bit (live_relevant_regs, regno);
> +                         bitmap_clear_bit (&live_subregs_used, regno);
> +                       bitmap_set_bit (&live_relevant_regs, regno);
>                       }
>                   }
>             }
> @@ -4349,7 +4346,7 @@ build_insn_chain (void)
>                  code did.  */
>               c->block = bb->index;
>               c->insn = insn;
> -             bitmap_copy (&c->live_throughout, live_relevant_regs);
> +             bitmap_copy (&c->live_throughout, &live_relevant_regs);
>             }
>           insn = PREV_INSN (insn);
>         }
> @@ -4362,9 +4359,6 @@ build_insn_chain (void)
>      if (live_subregs[i] != NULL)
>        sbitmap_free (live_subregs[i]);
>    free (live_subregs);
> -  BITMAP_FREE (live_subregs_used);
> -  BITMAP_FREE (live_relevant_regs);
> -  BITMAP_FREE (elim_regset);
>
>    if (dump_file)
>      print_insn_chains (dump_file);
> diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
> index c5d6b5a..caa2f68 100644
> --- a/gcc/loop-invariant.c
> +++ b/gcc/loop-invariant.c
> @@ -655,10 +655,10 @@ static void
>  find_defs (struct loop *loop, basic_block *body)
>  {
>    unsigned i;
> -  bitmap blocks = BITMAP_ALLOC (NULL);
> +  auto_bitmap blocks;
>
>    for (i = 0; i < loop->num_nodes; i++)
> -    bitmap_set_bit (blocks, body[i]->index);
> +    bitmap_set_bit (&blocks, body[i]->index);
>
>    if (dump_file)
>      {
> @@ -670,7 +670,7 @@ find_defs (struct loop *loop, basic_block *body)
>    df_remove_problem (df_chain);
>    df_process_deferred_rescans ();
>    df_chain_add_problem (DF_UD_CHAIN);
> -  df_set_blocks (blocks);
> +  df_set_blocks (&blocks);
>    df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
>    df_analyze ();
>    check_invariant_table_size ();
> @@ -682,8 +682,6 @@ find_defs (struct loop *loop, basic_block *body)
>                "*****ending processing of loop %d ******\n",
>                loop->num);
>      }
> -
> -  BITMAP_FREE (blocks);
>  }
>
>  /* Creates a new invariant for definition DEF in INSN, depending on invariants
> @@ -995,24 +993,20 @@ find_invariants_body (struct loop *loop, basic_block *body,
>  static void
>  find_invariants (struct loop *loop)
>  {
> -  bitmap may_exit = BITMAP_ALLOC (NULL);
> -  bitmap always_reached = BITMAP_ALLOC (NULL);
> -  bitmap has_exit = BITMAP_ALLOC (NULL);
> -  bitmap always_executed = BITMAP_ALLOC (NULL);
> +  auto_bitmap may_exit;
> +  auto_bitmap always_reached;
> +  auto_bitmap has_exit;
> +  auto_bitmap always_executed;
>    basic_block *body = get_loop_body_in_dom_order (loop);
>
> -  find_exits (loop, body, may_exit, has_exit);
> -  compute_always_reached (loop, body, may_exit, always_reached);
> -  compute_always_reached (loop, body, has_exit, always_executed);
> +  find_exits (loop, body, &may_exit, &has_exit);
> +  compute_always_reached (loop, body, &may_exit, &always_reached);
> +  compute_always_reached (loop, body, &has_exit, &always_executed);
>
>    find_defs (loop, body);
> -  find_invariants_body (loop, body, always_reached, always_executed);
> +  find_invariants_body (loop, body, &always_reached, &always_executed);
>    merge_identical_invariants ();
>
> -  BITMAP_FREE (always_reached);
> -  BITMAP_FREE (always_executed);
> -  BITMAP_FREE (may_exit);
> -  BITMAP_FREE (has_exit);
>    free (body);
>  }
>
> diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
> index e67bc35..e3187b6 100644
> --- a/gcc/lower-subreg.c
> +++ b/gcc/lower-subreg.c
> @@ -412,33 +412,27 @@ find_pseudo_copy (rtx set)
>  static void
>  propagate_pseudo_copies (void)
>  {
> -  bitmap queue, propagate;
> +  auto_bitmap queue, propagate;
>
> -  queue = BITMAP_ALLOC (NULL);
> -  propagate = BITMAP_ALLOC (NULL);
> -
> -  bitmap_copy (queue, decomposable_context);
> +  bitmap_copy (&queue, decomposable_context);
>    do
>      {
>        bitmap_iterator iter;
>        unsigned int i;
>
> -      bitmap_clear (propagate);
> +      bitmap_clear (&propagate);
>
> -      EXECUTE_IF_SET_IN_BITMAP (queue, 0, i, iter)
> +      EXECUTE_IF_SET_IN_BITMAP (&queue, 0, i, iter)
>         {
>           bitmap b = reg_copy_graph[i];
>           if (b)
> -           bitmap_ior_and_compl_into (propagate, b, non_decomposable_context);
> +           bitmap_ior_and_compl_into (&propagate, b, non_decomposable_context);
>         }
>
> -      bitmap_and_compl (queue, propagate, decomposable_context);
> -      bitmap_ior_into (decomposable_context, propagate);
> +      bitmap_and_compl (&queue, &propagate, decomposable_context);
> +      bitmap_ior_into (decomposable_context, &propagate);
>      }
> -  while (!bitmap_empty_p (queue));
> -
> -  BITMAP_FREE (queue);
> -  BITMAP_FREE (propagate);
> +  while (!bitmap_empty_p (&queue));
>  }
>
>  /* A pointer to one of these values is passed to
> diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
> index 08fdc77..4d6223f 100644
> --- a/gcc/sel-sched.c
> +++ b/gcc/sel-sched.c
> @@ -7269,11 +7269,11 @@ static void
>  sel_region_target_finish (bool reset_sched_cycles_p)
>  {
>    int i;
> -  bitmap scheduled_blocks = BITMAP_ALLOC (NULL);
> +  auto_bitmap scheduled_blocks;
>
>    for (i = 0; i < current_nr_blocks; i++)
>      {
> -      if (bitmap_bit_p (scheduled_blocks, i))
> +      if (bitmap_bit_p (&scheduled_blocks, i))
>         continue;
>
>        /* While pipelining outer loops, skip bundling for loop
> @@ -7281,7 +7281,7 @@ sel_region_target_finish (bool reset_sched_cycles_p)
>        if (sel_is_loop_preheader_p (EBB_FIRST_BB (i)))
>         continue;
>
> -      find_ebb_boundaries (EBB_FIRST_BB (i), scheduled_blocks);
> +      find_ebb_boundaries (EBB_FIRST_BB (i), &scheduled_blocks);
>
>        if (no_real_insns_p (current_sched_info->head, current_sched_info->tail))
>         continue;
> @@ -7303,8 +7303,6 @@ sel_region_target_finish (bool reset_sched_cycles_p)
>           sched_extend_luids ();
>         }
>      }
> -
> -  BITMAP_FREE (scheduled_blocks);
>  }
>
>  /* Free the scheduling data for the current region.  When RESET_SCHED_CYCLES_P
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index 601efd6..4a7007d 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -7515,7 +7515,6 @@ remove_edge_and_dominated_blocks (edge e)
>  {
>    vec<basic_block> bbs_to_remove = vNULL;
>    vec<basic_block> bbs_to_fix_dom = vNULL;
> -  bitmap df, df_idom;
>    edge f;
>    edge_iterator ei;
>    bool none_removed = false;
> @@ -7557,11 +7556,10 @@ remove_edge_and_dominated_blocks (edge e)
>         }
>      }
>
> -  df = BITMAP_ALLOC (NULL);
> -  df_idom = BITMAP_ALLOC (NULL);
> +  auto_bitmap df, df_idom;
>
>    if (none_removed)
> -    bitmap_set_bit (df_idom,
> +    bitmap_set_bit (&df_idom,
>                     get_immediate_dominator (CDI_DOMINATORS, e->dest)->index);
>    else
>      {
> @@ -7571,16 +7569,16 @@ remove_edge_and_dominated_blocks (edge e)
>           FOR_EACH_EDGE (f, ei, bb->succs)
>             {
>               if (f->dest != EXIT_BLOCK_PTR)
> -               bitmap_set_bit (df, f->dest->index);
> +               bitmap_set_bit (&df, f->dest->index);
>             }
>         }
>        FOR_EACH_VEC_ELT (bbs_to_remove, i, bb)
> -       bitmap_clear_bit (df, bb->index);
> +       bitmap_clear_bit (&df, bb->index);
>
> -      EXECUTE_IF_SET_IN_BITMAP (df, 0, i, bi)
> +      EXECUTE_IF_SET_IN_BITMAP (&df, 0, i, bi)
>         {
>           bb = BASIC_BLOCK (i);
> -         bitmap_set_bit (df_idom,
> +         bitmap_set_bit (&df_idom,
>                           get_immediate_dominator (CDI_DOMINATORS, bb)->index);
>         }
>      }
> @@ -7589,7 +7587,7 @@ remove_edge_and_dominated_blocks (edge e)
>      {
>        /* Record the set of the altered basic blocks.  */
>        bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
> -      bitmap_ior_into (cfgcleanup_altered_bbs, df);
> +      bitmap_ior_into (cfgcleanup_altered_bbs, &df);
>      }
>
>    /* Remove E and the cancelled blocks.  */
> @@ -7615,7 +7613,7 @@ remove_edge_and_dominated_blocks (edge e)
>       removed, and let W = F->dest.  Before removal, idom(W) = Y (since Y
>       dominates W, and because of P, Z does not dominate W), and W belongs to
>       the dominance frontier of E.  Therefore, Y belongs to DF_IDOM.  */
> -  EXECUTE_IF_SET_IN_BITMAP (df_idom, 0, i, bi)
> +  EXECUTE_IF_SET_IN_BITMAP (&df_idom, 0, i, bi)
>      {
>        bb = BASIC_BLOCK (i);
>        for (dbb = first_dom_son (CDI_DOMINATORS, bb);
> @@ -7626,8 +7624,6 @@ remove_edge_and_dominated_blocks (edge e)
>
>    iterate_fix_dominators (CDI_DOMINATORS, bbs_to_fix_dom, true);
>
> -  BITMAP_FREE (df);
> -  BITMAP_FREE (df_idom);
>    bbs_to_remove.release ();
>    bbs_to_fix_dom.release ();
>  }
> diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
> index 3ca84c5..e6ccbae 100644
> --- a/gcc/tree-cfgcleanup.c
> +++ b/gcc/tree-cfgcleanup.c
> @@ -532,19 +532,18 @@ fixup_noreturn_call (gimple stmt)
>           bitmap_iterator bi;
>           unsigned int bb_index;
>
> -         bitmap blocks = BITMAP_ALLOC (NULL);
> +         auto_bitmap blocks;
>
>            FOR_EACH_IMM_USE_STMT (use_stmt, iter, op)
>             {
>               if (gimple_code (use_stmt) != GIMPLE_PHI)
> -               bitmap_set_bit (blocks, gimple_bb (use_stmt)->index);
> +               bitmap_set_bit (&blocks, gimple_bb (use_stmt)->index);
>               else
>                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
>                   SET_USE (use_p, error_mark_node);
>             }
> -         EXECUTE_IF_SET_IN_BITMAP (blocks, 0, bb_index, bi)
> +         EXECUTE_IF_SET_IN_BITMAP (&blocks, 0, bb_index, bi)
>             delete_basic_block (BASIC_BLOCK (bb_index));
> -         BITMAP_FREE (blocks);
>           release_ssa_name (op);
>         }
>        update_stmt (stmt);
> @@ -717,14 +716,13 @@ cleanup_tree_cfg_noloop (void)
>  static void
>  repair_loop_structures (void)
>  {
> -  bitmap changed_bbs;
>    unsigned n_new_loops;
>
>    calculate_dominance_info (CDI_DOMINATORS);
>
>    timevar_push (TV_REPAIR_LOOPS);
> -  changed_bbs = BITMAP_ALLOC (NULL);
> -  n_new_loops = fix_loop_structure (changed_bbs);
> +  auto_bitmap changed_bbs;
> +  n_new_loops = fix_loop_structure (&changed_bbs);
>
>    /* This usually does nothing.  But sometimes parts of cfg that originally
>       were inside a loop get out of it due to edge removal (since they
> @@ -732,11 +730,9 @@ repair_loop_structures (void)
>       irreducible loop can become reducible - in this case force a full
>       rewrite into loop-closed SSA form.  */
>    if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
> -    rewrite_into_loop_closed_ssa (n_new_loops ? NULL : changed_bbs,
> +    rewrite_into_loop_closed_ssa (n_new_loops ? NULL : &changed_bbs,
>                                   TODO_update_ssa);
>
> -  BITMAP_FREE (changed_bbs);
> -
>  #ifdef ENABLE_CHECKING
>    verify_loop_structure ();
>  #endif
> diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
> index a489b61..3c2a75a 100644
> --- a/gcc/tree-eh.c
> +++ b/gcc/tree-eh.c
> @@ -4100,7 +4100,6 @@ cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
>    gimple_stmt_iterator ngsi, ogsi;
>    edge_iterator ei;
>    edge e;
> -  bitmap ophi_handled;
>
>    /* The destination block must not be a regular successor for any
>       of the preds of the landing pad.  Thus, avoid turning
> @@ -4121,7 +4120,7 @@ cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
>    FOR_EACH_EDGE (e, ei, old_bb->preds)
>      redirect_edge_var_map_clear (e);
>
> -  ophi_handled = BITMAP_ALLOC (NULL);
> +  auto_bitmap ophi_handled;
>
>    /* First, iterate through the PHIs on NEW_BB and set up the edge_var_map
>       for the edges we're going to move.  */
> @@ -4161,7 +4160,7 @@ cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
>                     goto fail;
>                 }
>             }
> -         bitmap_set_bit (ophi_handled, SSA_NAME_VERSION (nop));
> +         bitmap_set_bit (&ophi_handled, SSA_NAME_VERSION (nop));
>           FOR_EACH_EDGE (e, ei, old_bb->preds)
>             {
>               location_t oloc;
> @@ -4193,7 +4192,7 @@ cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
>      {
>        gimple ophi = gsi_stmt (ogsi);
>        tree oresult = gimple_phi_result (ophi);
> -      if (!bitmap_bit_p (ophi_handled, SSA_NAME_VERSION (oresult)))
> +      if (!bitmap_bit_p (&ophi_handled, SSA_NAME_VERSION (oresult)))
>         goto fail;
>      }
>
> @@ -4223,13 +4222,11 @@ cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
>      else
>        ei_next (&ei);
>
> -  BITMAP_FREE (ophi_handled);
>    return true;
>
>   fail:
>    FOR_EACH_EDGE (e, ei, old_bb->preds)
>      redirect_edge_var_map_clear (e);
> -  BITMAP_FREE (ophi_handled);
>    return false;
>  }
>
> diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
> index 576dcb7..44e2f53 100644
> --- a/gcc/tree-object-size.c
> +++ b/gcc/tree-object-size.c
> @@ -35,7 +35,7 @@ along with GCC; see the file COPYING3.  If not see
>  struct object_size_info
>  {
>    int object_size_type;
> -  bitmap visited, reexamine;
> +  auto_bitmap visited, reexamine;
>    int pass;
>    bool changed;
>    unsigned int *depths;
> @@ -514,8 +514,6 @@ compute_builtin_object_size (tree ptr, int object_size_type)
>               fprintf (dump_file, ":\n");
>             }
>
> -         osi.visited = BITMAP_ALLOC (NULL);
> -         osi.reexamine = BITMAP_ALLOC (NULL);
>           osi.object_size_type = object_size_type;
>           osi.depths = NULL;
>           osi.stack = NULL;
> @@ -532,9 +530,9 @@ compute_builtin_object_size (tree ptr, int object_size_type)
>           /* Second pass: keep recomputing object sizes of variables
>              that need reexamination, until no object sizes are
>              increased or all object sizes are computed.  */
> -         if (! bitmap_empty_p (osi.reexamine))
> +         if (! bitmap_empty_p (&osi.reexamine))
>             {
> -             bitmap reexamine = BITMAP_ALLOC (NULL);
> +             auto_bitmap reexamine;
>
>               /* If looking for minimum instead of maximum object size,
>                  detect cases where a pointer is increased in a loop.
> @@ -550,9 +548,9 @@ compute_builtin_object_size (tree ptr, int object_size_type)
>                   osi.pass = 1;
>                   /* collect_object_sizes_for is changing
>                      osi.reexamine bitmap, so iterate over a copy.  */
> -                 bitmap_copy (reexamine, osi.reexamine);
> -                 EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
> -                   if (bitmap_bit_p (osi.reexamine, i))
> +                 bitmap_copy (&reexamine, &osi.reexamine);
> +                 EXECUTE_IF_SET_IN_BITMAP (&reexamine, 0, i, bi)
> +                   if (bitmap_bit_p (&osi.reexamine, i))
>                       check_for_plus_in_loops (&osi, ssa_name (i));
>
>                   free (osi.depths);
> @@ -568,9 +566,9 @@ compute_builtin_object_size (tree ptr, int object_size_type)
>                   osi.changed = false;
>                   /* collect_object_sizes_for is changing
>                      osi.reexamine bitmap, so iterate over a copy.  */
> -                 bitmap_copy (reexamine, osi.reexamine);
> -                 EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
> -                   if (bitmap_bit_p (osi.reexamine, i))
> +                 bitmap_copy (&reexamine, &osi.reexamine);
> +                 EXECUTE_IF_SET_IN_BITMAP (&reexamine, 0, i, bi)
> +                   if (bitmap_bit_p (&osi.reexamine, i))
>                       {
>                         collect_object_sizes_for (&osi, ssa_name (i));
>                         if (dump_file && (dump_flags & TDF_DETAILS))
> @@ -583,16 +581,14 @@ compute_builtin_object_size (tree ptr, int object_size_type)
>                       }
>                 }
>               while (osi.changed);
> -
> -             BITMAP_FREE (reexamine);
>             }
> -         EXECUTE_IF_SET_IN_BITMAP (osi.reexamine, 0, i, bi)
> +         EXECUTE_IF_SET_IN_BITMAP (&osi.reexamine, 0, i, bi)
>             bitmap_set_bit (computed[object_size_type], i);
>
>           /* Debugging dumps.  */
>           if (dump_file)
>             {
> -             EXECUTE_IF_SET_IN_BITMAP (osi.visited, 0, i, bi)
> +             EXECUTE_IF_SET_IN_BITMAP (&osi.visited, 0, i, bi)
>                 if (object_sizes[object_size_type][i]
>                     != unknown[object_size_type])
>                   {
> @@ -606,9 +602,6 @@ compute_builtin_object_size (tree ptr, int object_size_type)
>                              object_sizes[object_size_type][i]);
>                   }
>             }
> -
> -         BITMAP_FREE (osi.reexamine);
> -         BITMAP_FREE (osi.visited);
>         }
>
>        return object_sizes[object_size_type][SSA_NAME_VERSION (ptr)];
> @@ -756,7 +749,7 @@ merge_object_sizes (struct object_size_info *osi, tree dest, tree orig,
>           osi->changed = true;
>         }
>      }
> -  return bitmap_bit_p (osi->reexamine, SSA_NAME_VERSION (orig));
> +  return bitmap_bit_p (&osi->reexamine, SSA_NAME_VERSION (orig));
>  }
>
>
> @@ -898,7 +891,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
>
>    if (osi->pass == 0)
>      {
> -      if (bitmap_set_bit (osi->visited, varno))
> +      if (bitmap_set_bit (&osi->visited, varno))
>         {
>           object_sizes[object_size_type][varno]
>             = (object_size_type & 2) ? -1 : 0;
> @@ -907,7 +900,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
>         {
>           /* Found a dependency loop.  Mark the variable for later
>              re-examination.  */
> -         bitmap_set_bit (osi->reexamine, varno);
> +         bitmap_set_bit (&osi->reexamine, varno);
>           if (dump_file && (dump_flags & TDF_DETAILS))
>             {
>               fprintf (dump_file, "Found a dependency loop at ");
> @@ -1011,11 +1004,11 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
>        || object_sizes[object_size_type][varno] == unknown[object_size_type])
>      {
>        bitmap_set_bit (computed[object_size_type], varno);
> -      bitmap_clear_bit (osi->reexamine, varno);
> +      bitmap_clear_bit (&osi->reexamine, varno);
>      }
>    else
>      {
> -      bitmap_set_bit (osi->reexamine, varno);
> +      bitmap_set_bit (&osi->reexamine, varno);
>        if (dump_file && (dump_flags & TDF_DETAILS))
>         {
>           fprintf (dump_file, "Need to reexamine ");
> @@ -1046,7 +1039,7 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
>           for (sp = osi->tos; sp > osi->stack; )
>             {
>               --sp;
> -             bitmap_clear_bit (osi->reexamine, *sp);
> +             bitmap_clear_bit (&osi->reexamine, *sp);
>               bitmap_set_bit (computed[osi->object_size_type], *sp);
>               object_sizes[osi->object_size_type][*sp] = 0;
>               if (*sp == varno)
> @@ -1055,7 +1048,7 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
>         }
>        return;
>      }
> -  else if (! bitmap_bit_p (osi->reexamine, varno))
> +  else if (! bitmap_bit_p (&osi->reexamine, varno))
>      return;
>
>    osi->depths[varno] = depth;
> diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
> index 3702922..68f5a68 100644
> --- a/gcc/tree-scalar-evolution.c
> +++ b/gcc/tree-scalar-evolution.c
> @@ -3291,7 +3291,7 @@ scev_const_prop (void)
>    tree name, type, ev;
>    gimple phi, ass;
>    struct loop *loop, *ex_loop;
> -  bitmap ssa_names_to_remove = NULL;
> +  auto_bitmap ssa_names_to_remove;
>    unsigned i;
>    loop_iterator li;
>    gimple_stmt_iterator psi;
> @@ -3326,20 +3326,16 @@ scev_const_prop (void)
>           if (name != ev)
>             replace_uses_by (name, ev);
>
> -         if (!ssa_names_to_remove)
> -           ssa_names_to_remove = BITMAP_ALLOC (NULL);
> -         bitmap_set_bit (ssa_names_to_remove, SSA_NAME_VERSION (name));
> +         bitmap_set_bit (&ssa_names_to_remove, SSA_NAME_VERSION (name));
>         }
>      }
>
>    /* Remove the ssa names that were replaced by constants.  We do not
>       remove them directly in the previous cycle, since this
>       invalidates scev cache.  */
> -  if (ssa_names_to_remove)
> -    {
> -      bitmap_iterator bi;
> +  bitmap_iterator bi;
>
> -      EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
> +  EXECUTE_IF_SET_IN_BITMAP (&ssa_names_to_remove, 0, i, bi)
>         {
>           gimple_stmt_iterator psi;
>           name = ssa_name (i);
> @@ -3350,9 +3346,7 @@ scev_const_prop (void)
>           remove_phi_node (&psi, true);
>         }
>
> -      BITMAP_FREE (ssa_names_to_remove);
>        scev_reset ();
> -    }
>
>    /* Now the regular final value replacement.  */
>    FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
> diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
> index 6a6f027..52fe1fb 100644
> --- a/gcc/tree-ssa-dom.c
> +++ b/gcc/tree-ssa-dom.c
> @@ -3020,9 +3020,6 @@ eliminate_degenerate_phis_1 (basic_block bb, bitmap interesting_names)
>  static unsigned int
>  eliminate_degenerate_phis (void)
>  {
> -  bitmap interesting_names;
> -  bitmap interesting_names1;
> -
>    /* Bitmap of blocks which need EH information updated.  We can not
>       update it on-the-fly as doing so invalidates the dominator tree.  */
>    need_eh_cleanup = BITMAP_ALLOC (NULL);
> @@ -3037,8 +3034,7 @@ eliminate_degenerate_phis (void)
>
>       Experiments have show we generally get better compilation
>       time behavior with bitmaps rather than sbitmaps.  */
> -  interesting_names = BITMAP_ALLOC (NULL);
> -  interesting_names1 = BITMAP_ALLOC (NULL);
> +  auto_bitmap interesting_names, interesting_names1;
>
>    calculate_dominance_info (CDI_DOMINATORS);
>    cfg_altered = false;
> @@ -3051,13 +3047,13 @@ eliminate_degenerate_phis (void)
>       phase in dominator order.  Presumably this is because walking
>       in dominator order leaves fewer PHIs for later examination
>       by the worklist phase.  */
> -  eliminate_degenerate_phis_1 (ENTRY_BLOCK_PTR, interesting_names);
> +  eliminate_degenerate_phis_1 (ENTRY_BLOCK_PTR, &interesting_names);
>
>    /* Second phase.  Eliminate second order degenerate PHIs as well
>       as trivial copies or constant initializations identified by
>       the first phase or this phase.  Basically we keep iterating
>       until our set of INTERESTING_NAMEs is empty.   */
> -  while (!bitmap_empty_p (interesting_names))
> +  while (!bitmap_empty_p (&interesting_names))
>      {
>        unsigned int i;
>        bitmap_iterator bi;
> @@ -3065,9 +3061,9 @@ eliminate_degenerate_phis (void)
>        /* EXECUTE_IF_SET_IN_BITMAP does not like its bitmap
>          changed during the loop.  Copy it to another bitmap and
>          use that.  */
> -      bitmap_copy (interesting_names1, interesting_names);
> +      bitmap_copy (&interesting_names1, &interesting_names);
>
> -      EXECUTE_IF_SET_IN_BITMAP (interesting_names1, 0, i, bi)
> +      EXECUTE_IF_SET_IN_BITMAP (&interesting_names1, 0, i, bi)
>         {
>           tree name = ssa_name (i);
>
> @@ -3075,7 +3071,7 @@ eliminate_degenerate_phis (void)
>              their defining statement was deleted (unreachable).  */
>           if (name)
>             eliminate_const_or_copy (SSA_NAME_DEF_STMT (ssa_name (i)),
> -                                    interesting_names);
> +                                    &interesting_names);
>         }
>      }
>
> @@ -3095,8 +3091,6 @@ eliminate_degenerate_phis (void)
>        BITMAP_FREE (need_eh_cleanup);
>      }
>
> -  BITMAP_FREE (interesting_names);
> -  BITMAP_FREE (interesting_names1);
>    return 0;
>  }
>
> diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
> index 17849a2..58fa24e 100644
> --- a/gcc/tree-ssa-live.c
> +++ b/gcc/tree-ssa-live.c
> @@ -1036,23 +1036,22 @@ live_worklist (tree_live_info_p live)
>    unsigned b;
>    basic_block bb;
>    sbitmap visited = sbitmap_alloc (last_basic_block + 1);
> -  bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack);
> +  auto_bitmap tmp (&liveness_bitmap_obstack);
>
>    bitmap_clear (visited);
>
>    /* Visit all the blocks in reverse order and propagate live on entry values
>       into the predecessors blocks.  */
>    FOR_EACH_BB_REVERSE (bb)
> -    loe_visit_block (live, bb, visited, tmp);
> +    loe_visit_block (live, bb, visited, &tmp);
>
>    /* Process any blocks which require further iteration.  */
>    while (live->stack_top != live->work_stack)
>      {
>        b = *--(live->stack_top);
> -      loe_visit_block (live, BASIC_BLOCK (b), visited, tmp);
> +      loe_visit_block (live, BASIC_BLOCK (b), visited, &tmp);
>      }
>
> -  BITMAP_FREE (tmp);
>    sbitmap_free (visited);
>  }
>
> diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
> index 894ff2d..928bac1 100644
> --- a/gcc/tree-ssa-loop-ivopts.c
> +++ b/gcc/tree-ssa-loop-ivopts.c
> @@ -4970,7 +4970,7 @@ determine_use_iv_costs (struct ivopts_data *data)
>    unsigned i, j;
>    struct iv_use *use;
>    struct iv_cand *cand;
> -  bitmap to_clear = BITMAP_ALLOC (NULL);
> +  auto_bitmap to_clear;
>
>    alloc_use_cost_map (data);
>
> @@ -4994,18 +4994,16 @@ determine_use_iv_costs (struct ivopts_data *data)
>             {
>               cand = iv_cand (data, j);
>               if (!determine_use_iv_cost (data, use, cand))
> -               bitmap_set_bit (to_clear, j);
> +               bitmap_set_bit (&to_clear, j);
>             }
>
>           /* Remove the candidates for that the cost is infinite from
>              the list of related candidates.  */
> -         bitmap_and_compl_into (use->related_cands, to_clear);
> -         bitmap_clear (to_clear);
> +         bitmap_and_compl_into (use->related_cands, &to_clear);
> +         bitmap_clear (&to_clear);
>         }
>      }
>
> -  BITMAP_FREE (to_clear);
> -
>    if (dump_file && (dump_flags & TDF_DETAILS))
>      {
>        fprintf (dump_file, "Use-candidate costs:\n");
> @@ -6492,7 +6490,7 @@ remove_unused_ivs (struct ivopts_data *data)
>  {
>    unsigned j;
>    bitmap_iterator bi;
> -  bitmap toremove = BITMAP_ALLOC (NULL);
> +  auto_bitmap toremove;
>
>    /* Figure out an order in which to release SSA DEFs so that we don't
>       release something that we'd have to propagate into a debug stmt
> @@ -6508,7 +6506,7 @@ remove_unused_ivs (struct ivopts_data *data)
>           && !info->iv->have_use_for
>           && !info->preserve_biv)
>         {
> -         bitmap_set_bit (toremove, SSA_NAME_VERSION (info->iv->ssa_name));
> +         bitmap_set_bit (&toremove, SSA_NAME_VERSION (info->iv->ssa_name));
>
>           tree def = info->iv->ssa_name;
>
> @@ -6614,9 +6612,7 @@ remove_unused_ivs (struct ivopts_data *data)
>         }
>      }
>
> -  release_defs_bitset (toremove);
> -
> -  BITMAP_FREE (toremove);
> +  release_defs_bitset (&toremove);
>  }
>
>  /* Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
> diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
> index 0a1c4d4..a5b5c08 100644
> --- a/gcc/tree-ssa-strlen.c
> +++ b/gcc/tree-ssa-strlen.c
> @@ -1963,10 +1963,9 @@ strlen_dom_walker::before_dom_children (basic_block bb)
>               gimple phi = gsi_stmt (gsi);
>               if (virtual_operand_p (gimple_phi_result (phi)))
>                 {
> -                 bitmap visited = BITMAP_ALLOC (NULL);
> +                 auto_bitmap visited;
>                   int count_vdef = 100;
> -                 do_invalidate (dombb, phi, visited, &count_vdef);
> -                 BITMAP_FREE (visited);
> +                 do_invalidate (dombb, phi, &visited, &count_vdef);
>                   if (count_vdef == 0)
>                     {
>                       /* If there were too many vdefs in between immediate
> diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
> index db95ce1..af41619 100644
> --- a/gcc/tree-ssa-tail-merge.c
> +++ b/gcc/tree-ssa-tail-merge.c
> @@ -1344,15 +1344,14 @@ deps_ok_for_redirect_from_bb_to_bb (basic_block from, basic_block to)
>    basic_block cd, dep_bb = BB_DEP_BB (to);
>    edge_iterator ei;
>    edge e;
> -  bitmap from_preds = BITMAP_ALLOC (NULL);
> +  auto_bitmap from_preds;
>
>    if (dep_bb == NULL)
>      return true;
>
>    FOR_EACH_EDGE (e, ei, from->preds)
> -    bitmap_set_bit (from_preds, e->src->index);
> -  cd = nearest_common_dominator_for_set (CDI_DOMINATORS, from_preds);
> -  BITMAP_FREE (from_preds);
> +    bitmap_set_bit (&from_preds, e->src->index);
> +  cd = nearest_common_dominator_for_set (CDI_DOMINATORS, &from_preds);
>
>    return dominated_by_p (CDI_DOMINATORS, dep_bb, cd);
>  }
> --
> 1.8.4.3
>
Michael Matz Nov. 14, 2013, 3:29 p.m. UTC | #2
Hi,

On Thu, 14 Nov 2013, Richard Biener wrote:

> Why not give bitmap_head a constructor/destructor and allow auto use of 
> that.  Isn't that exactly what should get 'auto' handling automagically?

auto != c++98 :-/


Ciao,
Michael.
Jeff Law Nov. 14, 2013, 8:12 p.m. UTC | #3
On 11/14/13 07:52, Richard Biener wrote:
>>> Another advantage of this class is it puts the bitmap_head struct on the stack
>> instead of mallocing it or using a obstack.
>
> Hm, but then eventually you increase the lifetime of the bitmap
> until the scope closes.
Yea, but often that's when we're releasing them anyway ;-)  I don't 
think we've gone to too much trouble to try and release the bitmaps as 
soon as they're no longer needed.  Releasing at end of scope seems fine 
to me.

I'm a fan of RAII style code.  It's less error prone and often results 
in code that is easier to understand because the code isn't cluttered 
with resource de-allocation either in if bodies or in blocks reached by 
gotos.

Jeff
Jeff Law Nov. 14, 2013, 8:35 p.m. UTC | #4
On 11/14/13 04:04, tsaunders@mozilla.com wrote:
> From: Trevor Saunders <tsaunders@mozilla.com>
>
> Hi,
>
> this patch adds and starts to use a class auto_bitmap, which is a very thin
> wrapper around bitmap.  Its advantage is that it takes care of delocation
> automatically.  So you can do things like
>
> int
> f ()
> {
>    auto_bitmap x;
>    // do stuff with x
> }
>
> Another advantage of this class is it puts the bitmap_head struct on the stack
> instead of mallocing it or using a obstack.
>
> I Think the biggest question is if I should make auto_bitmap a full c++ified
> wrapper around   bitmap or if I should contiune just taking the address of it
> and passing it as a bitmap, but other comments are of course welcome too.
I'd prefer to see it fully c++ified.

In response to one of Richi's comments, I spot checked the patch and 
only found two occurrences where this lengthened the lifetime of the 
bitmap in any significant way.  The vast majority of the time any 
increase in length was trivial.

Those instances are in tree-ssa-loop-ivopts.c and the other in 
tree-ssa-strlen.c.  I don't think you need to change anything for them, 
I'm just pointed out that of all the stuff you changed, these were the 
only ones I saw where lifetimes were changed significantly.

jeff
Richard Biener Nov. 14, 2013, 9:14 p.m. UTC | #5
Jeff Law <law@redhat.com> wrote:
>On 11/14/13 04:04, tsaunders@mozilla.com wrote:
>> From: Trevor Saunders <tsaunders@mozilla.com>
>>
>> Hi,
>>
>> this patch adds and starts to use a class auto_bitmap, which is a
>very thin
>> wrapper around bitmap.  Its advantage is that it takes care of
>delocation
>> automatically.  So you can do things like
>>
>> int
>> f ()
>> {
>>    auto_bitmap x;
>>    // do stuff with x
>> }
>>
>> Another advantage of this class is it puts the bitmap_head struct on
>the stack
>> instead of mallocing it or using a obstack.
>>
>> I Think the biggest question is if I should make auto_bitmap a full
>c++ified
>> wrapper around   bitmap or if I should contiune just taking the
>address of it
>> and passing it as a bitmap, but other comments are of course welcome
>too.
>I'd prefer to see it fully c++ified.
>
>In response to one of Richi's comments, I spot checked the patch and 
>only found two occurrences where this lengthened the lifetime of the 
>bitmap in any significant way.  The vast majority of the time any 
>increase in length was trivial.
>
>Those instances are in tree-ssa-loop-ivopts.c and the other in 
>tree-ssa-strlen.c.  I don't think you need to change anything for them,
>
>I'm just pointed out that of all the stuff you changed, these were the 
>only ones I saw where lifetimes were changed significantly.

I still ask why we need a new type and cannot put this functionality into bitmap_head itself.

Richard.

>jeff
Jeff Law Nov. 14, 2013, 9:33 p.m. UTC | #6
On 11/14/13 14:14, Richard Biener wrote:
>>
>> I'm just pointed out that of all the stuff you changed, these were the
>> only ones I saw where lifetimes were changed significantly.
>
> I still ask why we need a new type and cannot put this functionality into bitmap_head itself.
Given that bitmap is just a *bitmap_head_def aren't we suggesting the 
same thing?

jeff
Trevor Saunders Nov. 15, 2013, 2:28 a.m. UTC | #7
On Thu, Nov 14, 2013 at 02:33:00PM -0700, Jeff Law wrote:
> On 11/14/13 14:14, Richard Biener wrote:
> >>
> >>I'm just pointed out that of all the stuff you changed, these were the
> >>only ones I saw where lifetimes were changed significantly.
> >
> >I still ask why we need a new type and cannot put this functionality into bitmap_head itself.
> Given that bitmap is just a *bitmap_head_def aren't we suggesting
> the same thing?

I think bitmap_head some_bitmap; is a little funny name wise, but
auto_bitmap some_bitmap; is kind of funny too, so I think just having
people use bitmap_head is fine if that's what people prefer.  Its
unfortunate bitmap itself isn't available, but I don't have a plan for
dealing with bitmaps allocated in gc memory right now, so I guess they
need to stay as they are.

Trev

 
> 
> jeff
Richard Biener Nov. 15, 2013, 9:56 a.m. UTC | #8
On Thu, Nov 14, 2013 at 10:33 PM, Jeff Law <law@redhat.com> wrote:
> On 11/14/13 14:14, Richard Biener wrote:
>>>
>>>
>>> I'm just pointed out that of all the stuff you changed, these were the
>>> only ones I saw where lifetimes were changed significantly.
>>
>>
>> I still ask why we need a new type and cannot put this functionality into
>> bitmap_head itself.
>
> Given that bitmap is just a *bitmap_head_def aren't we suggesting the same
> thing?

Not sure - I thought Trevor wanted to make auto_bitmap a full C++ thing,
not bitmap itself?

Richard.

> jeff
Trevor Saunders Nov. 15, 2013, 10:37 a.m. UTC | #9
On Fri, Nov 15, 2013 at 10:56:24AM +0100, Richard Biener wrote:
> On Thu, Nov 14, 2013 at 10:33 PM, Jeff Law <law@redhat.com> wrote:
> > On 11/14/13 14:14, Richard Biener wrote:
> >>>
> >>>
> >>> I'm just pointed out that of all the stuff you changed, these were the
> >>> only ones I saw where lifetimes were changed significantly.
> >>
> >>
> >> I still ask why we need a new type and cannot put this functionality into
> >> bitmap_head itself.
> >
> > Given that bitmap is just a *bitmap_head_def aren't we suggesting the same
> > thing?
> 
> Not sure - I thought Trevor wanted to make auto_bitmap a full C++ thing,
> not bitmap itself?

My only firm goals are less manual memory management, and moving the
bitmap_head bit onto the stack would be really nice.  I'd also like to
leave bitmaps allocated in gc memory alone for the time being, but those
are the only firm goals.  I'm currently trying the approach of adding
constructors and destructors to bitmap_head, but apparently something is
causing them to get invoked even when everybody deals with bitmap_head *
which leads to ICEs that I'm investigating now.

Trev

> 
> Richard.
> 
> > jeff
Richard Biener Nov. 15, 2013, 11:11 a.m. UTC | #10
On Fri, Nov 15, 2013 at 11:37 AM, Trevor Saunders <tsaunders@mozilla.com> wrote:
> On Fri, Nov 15, 2013 at 10:56:24AM +0100, Richard Biener wrote:
>> On Thu, Nov 14, 2013 at 10:33 PM, Jeff Law <law@redhat.com> wrote:
>> > On 11/14/13 14:14, Richard Biener wrote:
>> >>>
>> >>>
>> >>> I'm just pointed out that of all the stuff you changed, these were the
>> >>> only ones I saw where lifetimes were changed significantly.
>> >>
>> >>
>> >> I still ask why we need a new type and cannot put this functionality into
>> >> bitmap_head itself.
>> >
>> > Given that bitmap is just a *bitmap_head_def aren't we suggesting the same
>> > thing?
>>
>> Not sure - I thought Trevor wanted to make auto_bitmap a full C++ thing,
>> not bitmap itself?
>
> My only firm goals are less manual memory management, and moving the
> bitmap_head bit onto the stack would be really nice.  I'd also like to
> leave bitmaps allocated in gc memory alone for the time being, but those
> are the only firm goals.  I'm currently trying the approach of adding
> constructors and destructors to bitmap_head, but apparently something is
> causing them to get invoked even when everybody deals with bitmap_head *
> which leads to ICEs that I'm investigating now.

They are used embedded into other structures as well (to avoid a
pointer indirection).

Richard.

> Trev
>
>>
>> Richard.
>>
>> > jeff
Trevor Saunders Nov. 15, 2013, 1:01 p.m. UTC | #11
On Fri, Nov 15, 2013 at 12:11:07PM +0100, Richard Biener wrote:
> On Fri, Nov 15, 2013 at 11:37 AM, Trevor Saunders <tsaunders@mozilla.com> wrote:
> > On Fri, Nov 15, 2013 at 10:56:24AM +0100, Richard Biener wrote:
> >> On Thu, Nov 14, 2013 at 10:33 PM, Jeff Law <law@redhat.com> wrote:
> >> > On 11/14/13 14:14, Richard Biener wrote:
> >> >>>
> >> >>>
> >> >>> I'm just pointed out that of all the stuff you changed, these were the
> >> >>> only ones I saw where lifetimes were changed significantly.
> >> >>
> >> >>
> >> >> I still ask why we need a new type and cannot put this functionality into
> >> >> bitmap_head itself.
> >> >
> >> > Given that bitmap is just a *bitmap_head_def aren't we suggesting the same
> >> > thing?
> >>
> >> Not sure - I thought Trevor wanted to make auto_bitmap a full C++ thing,
> >> not bitmap itself?
> >
> > My only firm goals are less manual memory management, and moving the
> > bitmap_head bit onto the stack would be really nice.  I'd also like to
> > leave bitmaps allocated in gc memory alone for the time being, but those
> > are the only firm goals.  I'm currently trying the approach of adding
> > constructors and destructors to bitmap_head, but apparently something is
> > causing them to get invoked even when everybody deals with bitmap_head *
> > which leads to ICEs that I'm investigating now.
> 
> They are used embedded into other structures as well (to avoid a
> pointer indirection).

yeah, I see that now, but actually what seems to haave een causing the
problem is that df-core.c df-problems.c and tree-ssa-pre.c where already
putting them directly on the stack.  That and the fact bitmap_clear
doesn't make head->first NULL, and so calling bitmap_clear twice on the
same bitmap causes a double free.

Trev

> 
> Richard.
> 
> > Trev
> >
> >>
> >> Richard.
> >>
> >> > jeff
diff mbox

Patch

diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index b3cb5da..78901fa 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -312,6 +312,14 @@  extern hashval_t bitmap_hash (const_bitmap);
 #define BITMAP_FREE(BITMAP) \
        ((void) (bitmap_obstack_free ((bitmap) BITMAP), (BITMAP) = (bitmap) NULL))
 
+/* bitmap with automatic management of resources. */
+class auto_bitmap : public bitmap_head_def
+{
+public:
+  auto_bitmap (bitmap_obstack *o = &bitmap_default_obstack) { bitmap_initialize_stat (this, o); }
+  ~auto_bitmap () { bitmap_clear (this); }
+};
+
 /* Iterator for bitmaps.  */
 
 typedef struct
diff --git a/gcc/bt-load.c b/gcc/bt-load.c
index 5384d01..819bcbb 100644
--- a/gcc/bt-load.c
+++ b/gcc/bt-load.c
@@ -1072,7 +1072,7 @@  combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
 	     target registers live over the merged range.  */
 	  int btr;
 	  HARD_REG_SET combined_btrs_live;
-	  bitmap combined_live_range = BITMAP_ALLOC (NULL);
+	  auto_bitmap combined_live_range;
 	  btr_user user;
 
 	  if (other_def->live_range == NULL)
@@ -1081,10 +1081,10 @@  combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
 	      btr_def_live_range (other_def, &dummy_btrs_live_in_range);
 	    }
 	  COPY_HARD_REG_SET (combined_btrs_live, *btrs_live_in_range);
-	  bitmap_copy (combined_live_range, def->live_range);
+	  bitmap_copy (&combined_live_range, def->live_range);
 
 	  for (user = other_def->uses; user != NULL; user = user->next)
-	    augment_live_range (combined_live_range, &combined_btrs_live,
+	    augment_live_range (&combined_live_range, &combined_btrs_live,
 				def->bb, user->bb,
 				(flag_btr_bb_exclusive
 				 || user->insn != BB_END (def->bb)
@@ -1121,7 +1121,7 @@  combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
 					      REGNO (user->use)));
 	      clear_btr_from_live_range (other_def);
 	      other_def->uses = NULL;
-	      bitmap_copy (def->live_range, combined_live_range);
+	      bitmap_copy (def->live_range, &combined_live_range);
 	      if (other_def->btr == btr && other_def->other_btr_uses_after_use)
 		def->other_btr_uses_after_use = 1;
 	      COPY_HARD_REG_SET (*btrs_live_in_range, combined_btrs_live);
@@ -1130,7 +1130,6 @@  combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
 	      delete_insn (other_def->insn);
 
 	    }
-	  BITMAP_FREE (combined_live_range);
 	}
     }
 }
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 3ff8e84..4510c0b 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -917,7 +917,6 @@  get_loop_body_in_bfs_order (const struct loop *loop)
 {
   basic_block *blocks;
   basic_block bb;
-  bitmap visited;
   unsigned int i = 0;
   unsigned int vc = 1;
 
@@ -925,7 +924,7 @@  get_loop_body_in_bfs_order (const struct loop *loop)
   gcc_assert (loop->latch != EXIT_BLOCK_PTR);
 
   blocks = XNEWVEC (basic_block, loop->num_nodes);
-  visited = BITMAP_ALLOC (NULL);
+  auto_bitmap visited;
 
   bb = loop->header;
   while (i < loop->num_nodes)
@@ -933,7 +932,7 @@  get_loop_body_in_bfs_order (const struct loop *loop)
       edge e;
       edge_iterator ei;
 
-      if (bitmap_set_bit (visited, bb->index))
+      if (bitmap_set_bit (&visited, bb->index))
 	/* This basic block is now visited */
 	blocks[i++] = bb;
 
@@ -941,7 +940,7 @@  get_loop_body_in_bfs_order (const struct loop *loop)
 	{
 	  if (flow_bb_inside_loop_p (loop, e->dest))
 	    {
-	      if (bitmap_set_bit (visited, e->dest->index))
+	      if (bitmap_set_bit (&visited, e->dest->index))
 		blocks[i++] = e->dest;
 	    }
 	}
@@ -951,7 +950,6 @@  get_loop_body_in_bfs_order (const struct loop *loop)
       bb = blocks[vc++];
     }
 
-  BITMAP_FREE (visited);
   return blocks;
 }
 
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index ae8ba3c..a512813 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -960,7 +960,7 @@  ipa_reference_write_optimization_summary (void)
   unsigned int count = 0;
   int ltrans_statics_bitcount = 0;
   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
-  bitmap ltrans_statics = BITMAP_ALLOC (NULL);
+  auto_bitmap ltrans_statics;
   int i;
 
   reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
@@ -975,7 +975,7 @@  ipa_reference_write_optimization_summary (void)
 	  && referenced_from_this_partition_p (&vnode->ref_list, encoder))
 	{
 	  tree decl = vnode->decl;
-	  bitmap_set_bit (ltrans_statics, DECL_UID (decl));
+	  bitmap_set_bit (&ltrans_statics, DECL_UID (decl));
 	  splay_tree_insert (reference_vars_to_consider,
 			     DECL_UID (decl), (splay_tree_value)decl);
 	  ltrans_statics_bitcount ++;
@@ -988,13 +988,13 @@  ipa_reference_write_optimization_summary (void)
       {
 	symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
 	cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
-	if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
+	if (cnode && write_node_summary_p (cnode, encoder, &ltrans_statics))
 	  count++;
       }
 
   streamer_write_uhwi_stream (ob->main_stream, count);
   if (count)
-    stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
+    stream_out_bitmap (ob, &ltrans_statics, &ltrans_statics,
 		       -1);
 
   /* Process all of the functions.  */
@@ -1003,7 +1003,7 @@  ipa_reference_write_optimization_summary (void)
       {
 	symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
 	cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
-	if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
+	if (cnode && write_node_summary_p (cnode, encoder, &ltrans_statics))
 	  {
 	    ipa_reference_optimization_summary_t info;
 	    int node_ref;
@@ -1012,13 +1012,12 @@  ipa_reference_write_optimization_summary (void)
 	    node_ref = lto_symtab_encoder_encode (encoder, snode);
 	    streamer_write_uhwi_stream (ob->main_stream, node_ref);
 
-	    stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
+	    stream_out_bitmap (ob, info->statics_not_read, &ltrans_statics,
 			       ltrans_statics_bitcount);
-	    stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
+	    stream_out_bitmap (ob, info->statics_not_written, &ltrans_statics,
 			       ltrans_statics_bitcount);
 	  }
       }
-  BITMAP_FREE (ltrans_statics);
   lto_destroy_simple_output_block (ob);
   splay_tree_delete (reference_vars_to_consider);
 }
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index df0a44e..d0bce24 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -195,7 +195,7 @@  static bool
 verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
 		     basic_block return_bb)
 {
-  bitmap seen = BITMAP_ALLOC (NULL);
+  auto_bitmap seen;
   vec<basic_block> worklist = vNULL;
   edge e;
   edge_iterator ei;
@@ -206,7 +206,7 @@  verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
 	&& !bitmap_bit_p (current->split_bbs, e->src->index))
       {
         worklist.safe_push (e->src);
-	bitmap_set_bit (seen, e->src->index);
+	bitmap_set_bit (&seen, e->src->index);
       }
 
   while (!worklist.is_empty ())
@@ -216,7 +216,7 @@  verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
 
       FOR_EACH_EDGE (e, ei, bb->preds)
 	if (e->src != ENTRY_BLOCK_PTR
-	    && bitmap_set_bit (seen, e->src->index))
+	    && bitmap_set_bit (&seen, e->src->index))
 	  {
 	    gcc_checking_assert (!bitmap_bit_p (current->split_bbs,
 					        e->src->index));
@@ -274,7 +274,6 @@  verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
 	}
     }
 done:
-  BITMAP_FREE (seen);
   worklist.release ();
   return ok;
 }
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 295cd532..c27f920 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -4124,20 +4124,20 @@  ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
   bool changed_p;
   ira_allocno_t a;
   HARD_REG_SET forbidden_regs;
-  bitmap temp = BITMAP_ALLOC (NULL);
+  auto_bitmap temp;
 
   /* Add pseudos which conflict with pseudos already in
      SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS.  This is preferable
      to allocating in two steps as some of the conflicts might have
      a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS.  */
   for (i = 0; i < num; i++)
-    bitmap_set_bit (temp, spilled_pseudo_regs[i]);
+    bitmap_set_bit (&temp, spilled_pseudo_regs[i]);
 
   for (i = 0, n = num; i < n; i++)
     {
       int nr, j;
       int regno = spilled_pseudo_regs[i];
-      bitmap_set_bit (temp, regno);
+      bitmap_set_bit (&temp, regno);
 
       a = ira_regno_allocno_map[regno];
       nr = ALLOCNO_NUM_OBJECTS (a);
@@ -4152,7 +4152,7 @@  ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
 	      ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
 	      if (ALLOCNO_HARD_REGNO (conflict_a) < 0
 		  && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
-		  && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
+		  && bitmap_set_bit (&temp, ALLOCNO_REGNO (conflict_a)))
 		{
 		  spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
 		  /* ?!? This seems wrong.  */
@@ -4190,7 +4190,6 @@  ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
 	  changed_p = true;
 	}
     }
-  BITMAP_FREE (temp);
   return changed_p;
 }
 
diff --git a/gcc/ira.c b/gcc/ira.c
index 2ef69cb..c03c7ee 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3445,9 +3445,9 @@  static int
 update_equiv_regs (void)
 {
   rtx insn;
+  auto_bitmap cleared_regs;
   basic_block bb;
   int loop_depth;
-  bitmap cleared_regs;
   bool *pdx_subregs;
 
   /* We need to keep track of whether or not we recorded a LABEL_REF so
@@ -3757,7 +3757,6 @@  update_equiv_regs (void)
 	}
     }
 
-  cleared_regs = BITMAP_ALLOC (NULL);
   /* Now scan all regs killed in an insn to see if any of them are
      registers only used that once.  If so, see if we can replace the
      reference with the equivalent form.  If we can, delete the
@@ -3856,7 +3855,7 @@  update_equiv_regs (void)
 			= XEXP (reg_equiv[regno].init_insns, 1);
 
 		      ira_reg_equiv[regno].init_insns = NULL_RTX;
-		      bitmap_set_bit (cleared_regs, regno);
+		      bitmap_set_bit (&cleared_regs, regno);
 		    }
 		  /* Move the initialization of the register to just before
 		     INSN.  Update the flow information.  */
@@ -3890,23 +3889,23 @@  update_equiv_regs (void)
 
 		      ira_reg_equiv[regno].init_insns
 			= gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
-		      bitmap_set_bit (cleared_regs, regno);
+		      bitmap_set_bit (&cleared_regs, regno);
 		    }
 		}
 	    }
 	}
     }
 
-  if (!bitmap_empty_p (cleared_regs))
+  if (!bitmap_empty_p (&cleared_regs))
     {
       FOR_EACH_BB (bb)
 	{
-	  bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
-	  bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
+	  bitmap_and_compl_into (DF_LR_IN (bb), &cleared_regs);
+	  bitmap_and_compl_into (DF_LR_OUT (bb), &cleared_regs);
 	  if (! df_live)
 	    continue;
-	  bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
-	  bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
+	  bitmap_and_compl_into (DF_LIVE_IN (bb), &cleared_regs);
+	  bitmap_and_compl_into (DF_LIVE_OUT (bb), &cleared_regs);
 	}
 
       /* Last pass - adjust debug insns referencing cleared regs.  */
@@ -3918,14 +3917,12 @@  update_equiv_regs (void)
 	      INSN_VAR_LOCATION_LOC (insn)
 		= simplify_replace_fn_rtx (old_loc, NULL_RTX,
 					   adjust_cleared_regs,
-					   (void *) cleared_regs);
+					   (void *) &cleared_regs);
 	      if (old_loc != INSN_VAR_LOCATION_LOC (insn))
 		df_insn_rescan (insn);
 	    }
     }
 
-  BITMAP_FREE (cleared_regs);
-
   out:
   /* Clean up.  */
 
@@ -4106,8 +4103,8 @@  build_insn_chain (void)
   basic_block bb;
   struct insn_chain *c = NULL;
   struct insn_chain *next = NULL;
-  bitmap live_relevant_regs = BITMAP_ALLOC (NULL);
-  bitmap elim_regset = BITMAP_ALLOC (NULL);
+  auto_bitmap live_relevant_regs;
+  auto_bitmap elim_regset;
   /* live_subregs is a vector used to keep accurate information about
      which hardregs are live in multiword pseudos.  live_subregs and
      live_subregs_used are indexed by pseudo number.  The live_subreg
@@ -4116,31 +4113,31 @@  build_insn_chain (void)
      live_subreg[allocno] is number of bytes that the pseudo can
      occupy.  */
   sbitmap *live_subregs = XCNEWVEC (sbitmap, max_regno);
-  bitmap live_subregs_used = BITMAP_ALLOC (NULL);
+  auto_bitmap live_subregs_used;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (TEST_HARD_REG_BIT (eliminable_regset, i))
-      bitmap_set_bit (elim_regset, i);
+      bitmap_set_bit (&elim_regset, i);
   FOR_EACH_BB_REVERSE (bb)
     {
       bitmap_iterator bi;
       rtx insn;
 
-      CLEAR_REG_SET (live_relevant_regs);
-      bitmap_clear (live_subregs_used);
+      CLEAR_REG_SET (&live_relevant_regs);
+      bitmap_clear (&live_subregs_used);
 
       EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), 0, i, bi)
 	{
 	  if (i >= FIRST_PSEUDO_REGISTER)
 	    break;
-	  bitmap_set_bit (live_relevant_regs, i);
+	  bitmap_set_bit (&live_relevant_regs, i);
 	}
 
       EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb),
 				FIRST_PSEUDO_REGISTER, i, bi)
 	{
 	  if (pseudo_for_reload_consideration_p (i))
-	    bitmap_set_bit (live_relevant_regs, i);
+	    bitmap_set_bit (&live_relevant_regs, i);
 	}
 
       FOR_BB_INSNS_REVERSE (bb, insn)
@@ -4197,8 +4194,8 @@  build_insn_chain (void)
 			      + GET_MODE_SIZE (GET_MODE (reg));
 
 			    init_live_subregs
-			      (bitmap_bit_p (live_relevant_regs, regno),
-			       live_subregs, live_subregs_used, regno, reg);
+			      (bitmap_bit_p (&live_relevant_regs, regno),
+			       live_subregs, &live_subregs_used, regno, reg);
 
 			    if (!DF_REF_FLAGS_IS_SET
 				(def, DF_REF_STRICT_LOW_PART))
@@ -4223,14 +4220,14 @@  build_insn_chain (void)
 
 			    if (bitmap_empty_p (live_subregs[regno]))
 			      {
-				bitmap_clear_bit (live_subregs_used, regno);
-				bitmap_clear_bit (live_relevant_regs, regno);
+				bitmap_clear_bit (&live_subregs_used, regno);
+				bitmap_clear_bit (&live_relevant_regs, regno);
 			      }
 			    else
 			      /* Set live_relevant_regs here because
 				 that bit has to be true to get us to
 				 look at the live_subregs fields.  */
-			      bitmap_set_bit (live_relevant_regs, regno);
+			      bitmap_set_bit (&live_relevant_regs, regno);
 			  }
 			else
 			  {
@@ -4241,15 +4238,15 @@  build_insn_chain (void)
 			       modeling the def as a killing def.  */
 			    if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL))
 			      {
-				bitmap_clear_bit (live_subregs_used, regno);
-				bitmap_clear_bit (live_relevant_regs, regno);
+				bitmap_clear_bit (&live_subregs_used, regno);
+				bitmap_clear_bit (&live_relevant_regs, regno);
 			      }
 			  }
 		      }
 		  }
 
-	      bitmap_and_compl_into (live_relevant_regs, elim_regset);
-	      bitmap_copy (&c->live_throughout, live_relevant_regs);
+	      bitmap_and_compl_into (&live_relevant_regs, &elim_regset);
+	      bitmap_copy (&c->live_throughout, &live_relevant_regs);
 
 	      if (NONDEBUG_INSN_P (insn))
 		for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
@@ -4270,7 +4267,7 @@  build_insn_chain (void)
 		      continue;
 
 		    /* Add the last use of each var to dead_or_set.  */
-		    if (!bitmap_bit_p (live_relevant_regs, regno))
+		    if (!bitmap_bit_p (&live_relevant_regs, regno))
 		      {
 			if (regno < FIRST_PSEUDO_REGISTER)
 			  {
@@ -4294,8 +4291,8 @@  build_insn_chain (void)
 			      + GET_MODE_SIZE (GET_MODE (reg));
 
 			    init_live_subregs
-			      (bitmap_bit_p (live_relevant_regs, regno),
-			       live_subregs, live_subregs_used, regno, reg);
+			      (bitmap_bit_p (&live_relevant_regs, regno),
+			       live_subregs, &live_subregs_used, regno, reg);
 
 			    /* Ignore the paradoxical bits.  */
 			    if (last > SBITMAP_SIZE (live_subregs[regno]))
@@ -4312,8 +4309,8 @@  build_insn_chain (void)
 			     effectively saying do not use the subregs
 			     because we are reading the whole
 			     pseudo.  */
-			  bitmap_clear_bit (live_subregs_used, regno);
-			bitmap_set_bit (live_relevant_regs, regno);
+			  bitmap_clear_bit (&live_subregs_used, regno);
+			bitmap_set_bit (&live_relevant_regs, regno);
 		      }
 		  }
 	    }
@@ -4349,7 +4346,7 @@  build_insn_chain (void)
 		 code did.  */
 	      c->block = bb->index;
 	      c->insn = insn;
-	      bitmap_copy (&c->live_throughout, live_relevant_regs);
+	      bitmap_copy (&c->live_throughout, &live_relevant_regs);
 	    }
 	  insn = PREV_INSN (insn);
 	}
@@ -4362,9 +4359,6 @@  build_insn_chain (void)
     if (live_subregs[i] != NULL)
       sbitmap_free (live_subregs[i]);
   free (live_subregs);
-  BITMAP_FREE (live_subregs_used);
-  BITMAP_FREE (live_relevant_regs);
-  BITMAP_FREE (elim_regset);
 
   if (dump_file)
     print_insn_chains (dump_file);
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index c5d6b5a..caa2f68 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -655,10 +655,10 @@  static void
 find_defs (struct loop *loop, basic_block *body)
 {
   unsigned i;
-  bitmap blocks = BITMAP_ALLOC (NULL);
+  auto_bitmap blocks;
 
   for (i = 0; i < loop->num_nodes; i++)
-    bitmap_set_bit (blocks, body[i]->index);
+    bitmap_set_bit (&blocks, body[i]->index);
 
   if (dump_file)
     {
@@ -670,7 +670,7 @@  find_defs (struct loop *loop, basic_block *body)
   df_remove_problem (df_chain);
   df_process_deferred_rescans ();
   df_chain_add_problem (DF_UD_CHAIN);
-  df_set_blocks (blocks);
+  df_set_blocks (&blocks);
   df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
   df_analyze ();
   check_invariant_table_size ();
@@ -682,8 +682,6 @@  find_defs (struct loop *loop, basic_block *body)
 	       "*****ending processing of loop %d ******\n",
 	       loop->num);
     }
-
-  BITMAP_FREE (blocks);
 }
 
 /* Creates a new invariant for definition DEF in INSN, depending on invariants
@@ -995,24 +993,20 @@  find_invariants_body (struct loop *loop, basic_block *body,
 static void
 find_invariants (struct loop *loop)
 {
-  bitmap may_exit = BITMAP_ALLOC (NULL);
-  bitmap always_reached = BITMAP_ALLOC (NULL);
-  bitmap has_exit = BITMAP_ALLOC (NULL);
-  bitmap always_executed = BITMAP_ALLOC (NULL);
+  auto_bitmap may_exit;
+  auto_bitmap always_reached;
+  auto_bitmap has_exit;
+  auto_bitmap always_executed;
   basic_block *body = get_loop_body_in_dom_order (loop);
 
-  find_exits (loop, body, may_exit, has_exit);
-  compute_always_reached (loop, body, may_exit, always_reached);
-  compute_always_reached (loop, body, has_exit, always_executed);
+  find_exits (loop, body, &may_exit, &has_exit);
+  compute_always_reached (loop, body, &may_exit, &always_reached);
+  compute_always_reached (loop, body, &has_exit, &always_executed);
 
   find_defs (loop, body);
-  find_invariants_body (loop, body, always_reached, always_executed);
+  find_invariants_body (loop, body, &always_reached, &always_executed);
   merge_identical_invariants ();
 
-  BITMAP_FREE (always_reached);
-  BITMAP_FREE (always_executed);
-  BITMAP_FREE (may_exit);
-  BITMAP_FREE (has_exit);
   free (body);
 }
 
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index e67bc35..e3187b6 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -412,33 +412,27 @@  find_pseudo_copy (rtx set)
 static void
 propagate_pseudo_copies (void)
 {
-  bitmap queue, propagate;
+  auto_bitmap queue, propagate;
 
-  queue = BITMAP_ALLOC (NULL);
-  propagate = BITMAP_ALLOC (NULL);
-
-  bitmap_copy (queue, decomposable_context);
+  bitmap_copy (&queue, decomposable_context);
   do
     {
       bitmap_iterator iter;
       unsigned int i;
 
-      bitmap_clear (propagate);
+      bitmap_clear (&propagate);
 
-      EXECUTE_IF_SET_IN_BITMAP (queue, 0, i, iter)
+      EXECUTE_IF_SET_IN_BITMAP (&queue, 0, i, iter)
 	{
 	  bitmap b = reg_copy_graph[i];
 	  if (b)
-	    bitmap_ior_and_compl_into (propagate, b, non_decomposable_context);
+	    bitmap_ior_and_compl_into (&propagate, b, non_decomposable_context);
 	}
 
-      bitmap_and_compl (queue, propagate, decomposable_context);
-      bitmap_ior_into (decomposable_context, propagate);
+      bitmap_and_compl (&queue, &propagate, decomposable_context);
+      bitmap_ior_into (decomposable_context, &propagate);
     }
-  while (!bitmap_empty_p (queue));
-
-  BITMAP_FREE (queue);
-  BITMAP_FREE (propagate);
+  while (!bitmap_empty_p (&queue));
 }
 
 /* A pointer to one of these values is passed to
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index 08fdc77..4d6223f 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -7269,11 +7269,11 @@  static void
 sel_region_target_finish (bool reset_sched_cycles_p)
 {
   int i;
-  bitmap scheduled_blocks = BITMAP_ALLOC (NULL);
+  auto_bitmap scheduled_blocks;
 
   for (i = 0; i < current_nr_blocks; i++)
     {
-      if (bitmap_bit_p (scheduled_blocks, i))
+      if (bitmap_bit_p (&scheduled_blocks, i))
 	continue;
 
       /* While pipelining outer loops, skip bundling for loop
@@ -7281,7 +7281,7 @@  sel_region_target_finish (bool reset_sched_cycles_p)
       if (sel_is_loop_preheader_p (EBB_FIRST_BB (i)))
 	continue;
 
-      find_ebb_boundaries (EBB_FIRST_BB (i), scheduled_blocks);
+      find_ebb_boundaries (EBB_FIRST_BB (i), &scheduled_blocks);
 
       if (no_real_insns_p (current_sched_info->head, current_sched_info->tail))
 	continue;
@@ -7303,8 +7303,6 @@  sel_region_target_finish (bool reset_sched_cycles_p)
 	  sched_extend_luids ();
 	}
     }
-
-  BITMAP_FREE (scheduled_blocks);
 }
 
 /* Free the scheduling data for the current region.  When RESET_SCHED_CYCLES_P
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 601efd6..4a7007d 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -7515,7 +7515,6 @@  remove_edge_and_dominated_blocks (edge e)
 {
   vec<basic_block> bbs_to_remove = vNULL;
   vec<basic_block> bbs_to_fix_dom = vNULL;
-  bitmap df, df_idom;
   edge f;
   edge_iterator ei;
   bool none_removed = false;
@@ -7557,11 +7556,10 @@  remove_edge_and_dominated_blocks (edge e)
 	}
     }
 
-  df = BITMAP_ALLOC (NULL);
-  df_idom = BITMAP_ALLOC (NULL);
+  auto_bitmap df, df_idom;
 
   if (none_removed)
-    bitmap_set_bit (df_idom,
+    bitmap_set_bit (&df_idom,
 		    get_immediate_dominator (CDI_DOMINATORS, e->dest)->index);
   else
     {
@@ -7571,16 +7569,16 @@  remove_edge_and_dominated_blocks (edge e)
 	  FOR_EACH_EDGE (f, ei, bb->succs)
 	    {
 	      if (f->dest != EXIT_BLOCK_PTR)
-		bitmap_set_bit (df, f->dest->index);
+		bitmap_set_bit (&df, f->dest->index);
 	    }
 	}
       FOR_EACH_VEC_ELT (bbs_to_remove, i, bb)
-	bitmap_clear_bit (df, bb->index);
+	bitmap_clear_bit (&df, bb->index);
 
-      EXECUTE_IF_SET_IN_BITMAP (df, 0, i, bi)
+      EXECUTE_IF_SET_IN_BITMAP (&df, 0, i, bi)
 	{
 	  bb = BASIC_BLOCK (i);
-	  bitmap_set_bit (df_idom,
+	  bitmap_set_bit (&df_idom,
 			  get_immediate_dominator (CDI_DOMINATORS, bb)->index);
 	}
     }
@@ -7589,7 +7587,7 @@  remove_edge_and_dominated_blocks (edge e)
     {
       /* Record the set of the altered basic blocks.  */
       bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
-      bitmap_ior_into (cfgcleanup_altered_bbs, df);
+      bitmap_ior_into (cfgcleanup_altered_bbs, &df);
     }
 
   /* Remove E and the cancelled blocks.  */
@@ -7615,7 +7613,7 @@  remove_edge_and_dominated_blocks (edge e)
      removed, and let W = F->dest.  Before removal, idom(W) = Y (since Y
      dominates W, and because of P, Z does not dominate W), and W belongs to
      the dominance frontier of E.  Therefore, Y belongs to DF_IDOM.  */
-  EXECUTE_IF_SET_IN_BITMAP (df_idom, 0, i, bi)
+  EXECUTE_IF_SET_IN_BITMAP (&df_idom, 0, i, bi)
     {
       bb = BASIC_BLOCK (i);
       for (dbb = first_dom_son (CDI_DOMINATORS, bb);
@@ -7626,8 +7624,6 @@  remove_edge_and_dominated_blocks (edge e)
 
   iterate_fix_dominators (CDI_DOMINATORS, bbs_to_fix_dom, true);
 
-  BITMAP_FREE (df);
-  BITMAP_FREE (df_idom);
   bbs_to_remove.release ();
   bbs_to_fix_dom.release ();
 }
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 3ca84c5..e6ccbae 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -532,19 +532,18 @@  fixup_noreturn_call (gimple stmt)
 	  bitmap_iterator bi;
 	  unsigned int bb_index;
 
-	  bitmap blocks = BITMAP_ALLOC (NULL);
+	  auto_bitmap blocks;
 
           FOR_EACH_IMM_USE_STMT (use_stmt, iter, op)
 	    {
 	      if (gimple_code (use_stmt) != GIMPLE_PHI)
-	        bitmap_set_bit (blocks, gimple_bb (use_stmt)->index);
+	        bitmap_set_bit (&blocks, gimple_bb (use_stmt)->index);
 	      else
 		FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
 		  SET_USE (use_p, error_mark_node);
 	    }
-	  EXECUTE_IF_SET_IN_BITMAP (blocks, 0, bb_index, bi)
+	  EXECUTE_IF_SET_IN_BITMAP (&blocks, 0, bb_index, bi)
 	    delete_basic_block (BASIC_BLOCK (bb_index));
-	  BITMAP_FREE (blocks);
 	  release_ssa_name (op);
 	}
       update_stmt (stmt);
@@ -717,14 +716,13 @@  cleanup_tree_cfg_noloop (void)
 static void
 repair_loop_structures (void)
 {
-  bitmap changed_bbs;
   unsigned n_new_loops;
 
   calculate_dominance_info (CDI_DOMINATORS);
 
   timevar_push (TV_REPAIR_LOOPS);
-  changed_bbs = BITMAP_ALLOC (NULL);
-  n_new_loops = fix_loop_structure (changed_bbs);
+  auto_bitmap changed_bbs;
+  n_new_loops = fix_loop_structure (&changed_bbs);
 
   /* This usually does nothing.  But sometimes parts of cfg that originally
      were inside a loop get out of it due to edge removal (since they
@@ -732,11 +730,9 @@  repair_loop_structures (void)
      irreducible loop can become reducible - in this case force a full
      rewrite into loop-closed SSA form.  */
   if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
-    rewrite_into_loop_closed_ssa (n_new_loops ? NULL : changed_bbs,
+    rewrite_into_loop_closed_ssa (n_new_loops ? NULL : &changed_bbs,
 				  TODO_update_ssa);
 
-  BITMAP_FREE (changed_bbs);
-
 #ifdef ENABLE_CHECKING
   verify_loop_structure ();
 #endif
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index a489b61..3c2a75a 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -4100,7 +4100,6 @@  cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
   gimple_stmt_iterator ngsi, ogsi;
   edge_iterator ei;
   edge e;
-  bitmap ophi_handled;
 
   /* The destination block must not be a regular successor for any
      of the preds of the landing pad.  Thus, avoid turning
@@ -4121,7 +4120,7 @@  cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
   FOR_EACH_EDGE (e, ei, old_bb->preds)
     redirect_edge_var_map_clear (e);
 
-  ophi_handled = BITMAP_ALLOC (NULL);
+  auto_bitmap ophi_handled;
 
   /* First, iterate through the PHIs on NEW_BB and set up the edge_var_map
      for the edges we're going to move.  */
@@ -4161,7 +4160,7 @@  cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
 		    goto fail;
 		}
 	    }
-	  bitmap_set_bit (ophi_handled, SSA_NAME_VERSION (nop));
+	  bitmap_set_bit (&ophi_handled, SSA_NAME_VERSION (nop));
 	  FOR_EACH_EDGE (e, ei, old_bb->preds)
 	    {
 	      location_t oloc;
@@ -4193,7 +4192,7 @@  cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
     {
       gimple ophi = gsi_stmt (ogsi);
       tree oresult = gimple_phi_result (ophi);
-      if (!bitmap_bit_p (ophi_handled, SSA_NAME_VERSION (oresult)))
+      if (!bitmap_bit_p (&ophi_handled, SSA_NAME_VERSION (oresult)))
 	goto fail;
     }
 
@@ -4223,13 +4222,11 @@  cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
     else
       ei_next (&ei);
 
-  BITMAP_FREE (ophi_handled);
   return true;
 
  fail:
   FOR_EACH_EDGE (e, ei, old_bb->preds)
     redirect_edge_var_map_clear (e);
-  BITMAP_FREE (ophi_handled);
   return false;
 }
 
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 576dcb7..44e2f53 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -35,7 +35,7 @@  along with GCC; see the file COPYING3.  If not see
 struct object_size_info
 {
   int object_size_type;
-  bitmap visited, reexamine;
+  auto_bitmap visited, reexamine;
   int pass;
   bool changed;
   unsigned int *depths;
@@ -514,8 +514,6 @@  compute_builtin_object_size (tree ptr, int object_size_type)
 	      fprintf (dump_file, ":\n");
 	    }
 
-	  osi.visited = BITMAP_ALLOC (NULL);
-	  osi.reexamine = BITMAP_ALLOC (NULL);
 	  osi.object_size_type = object_size_type;
 	  osi.depths = NULL;
 	  osi.stack = NULL;
@@ -532,9 +530,9 @@  compute_builtin_object_size (tree ptr, int object_size_type)
 	  /* Second pass: keep recomputing object sizes of variables
 	     that need reexamination, until no object sizes are
 	     increased or all object sizes are computed.  */
-	  if (! bitmap_empty_p (osi.reexamine))
+	  if (! bitmap_empty_p (&osi.reexamine))
 	    {
-	      bitmap reexamine = BITMAP_ALLOC (NULL);
+	      auto_bitmap reexamine;
 
 	      /* If looking for minimum instead of maximum object size,
 		 detect cases where a pointer is increased in a loop.
@@ -550,9 +548,9 @@  compute_builtin_object_size (tree ptr, int object_size_type)
 		  osi.pass = 1;
 		  /* collect_object_sizes_for is changing
 		     osi.reexamine bitmap, so iterate over a copy.  */
-		  bitmap_copy (reexamine, osi.reexamine);
-		  EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
-		    if (bitmap_bit_p (osi.reexamine, i))
+		  bitmap_copy (&reexamine, &osi.reexamine);
+		  EXECUTE_IF_SET_IN_BITMAP (&reexamine, 0, i, bi)
+		    if (bitmap_bit_p (&osi.reexamine, i))
 		      check_for_plus_in_loops (&osi, ssa_name (i));
 
 		  free (osi.depths);
@@ -568,9 +566,9 @@  compute_builtin_object_size (tree ptr, int object_size_type)
 		  osi.changed = false;
 		  /* collect_object_sizes_for is changing
 		     osi.reexamine bitmap, so iterate over a copy.  */
-		  bitmap_copy (reexamine, osi.reexamine);
-		  EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
-		    if (bitmap_bit_p (osi.reexamine, i))
+		  bitmap_copy (&reexamine, &osi.reexamine);
+		  EXECUTE_IF_SET_IN_BITMAP (&reexamine, 0, i, bi)
+		    if (bitmap_bit_p (&osi.reexamine, i))
 		      {
 			collect_object_sizes_for (&osi, ssa_name (i));
 			if (dump_file && (dump_flags & TDF_DETAILS))
@@ -583,16 +581,14 @@  compute_builtin_object_size (tree ptr, int object_size_type)
 		      }
 		}
 	      while (osi.changed);
-
-	      BITMAP_FREE (reexamine);
 	    }
-	  EXECUTE_IF_SET_IN_BITMAP (osi.reexamine, 0, i, bi)
+	  EXECUTE_IF_SET_IN_BITMAP (&osi.reexamine, 0, i, bi)
 	    bitmap_set_bit (computed[object_size_type], i);
 
 	  /* Debugging dumps.  */
 	  if (dump_file)
 	    {
-	      EXECUTE_IF_SET_IN_BITMAP (osi.visited, 0, i, bi)
+	      EXECUTE_IF_SET_IN_BITMAP (&osi.visited, 0, i, bi)
 		if (object_sizes[object_size_type][i]
 		    != unknown[object_size_type])
 		  {
@@ -606,9 +602,6 @@  compute_builtin_object_size (tree ptr, int object_size_type)
 			     object_sizes[object_size_type][i]);
 		  }
 	    }
-
-	  BITMAP_FREE (osi.reexamine);
-	  BITMAP_FREE (osi.visited);
 	}
 
       return object_sizes[object_size_type][SSA_NAME_VERSION (ptr)];
@@ -756,7 +749,7 @@  merge_object_sizes (struct object_size_info *osi, tree dest, tree orig,
 	  osi->changed = true;
 	}
     }
-  return bitmap_bit_p (osi->reexamine, SSA_NAME_VERSION (orig));
+  return bitmap_bit_p (&osi->reexamine, SSA_NAME_VERSION (orig));
 }
 
 
@@ -898,7 +891,7 @@  collect_object_sizes_for (struct object_size_info *osi, tree var)
 
   if (osi->pass == 0)
     {
-      if (bitmap_set_bit (osi->visited, varno))
+      if (bitmap_set_bit (&osi->visited, varno))
 	{
 	  object_sizes[object_size_type][varno]
 	    = (object_size_type & 2) ? -1 : 0;
@@ -907,7 +900,7 @@  collect_object_sizes_for (struct object_size_info *osi, tree var)
 	{
 	  /* Found a dependency loop.  Mark the variable for later
 	     re-examination.  */
-	  bitmap_set_bit (osi->reexamine, varno);
+	  bitmap_set_bit (&osi->reexamine, varno);
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    {
 	      fprintf (dump_file, "Found a dependency loop at ");
@@ -1011,11 +1004,11 @@  collect_object_sizes_for (struct object_size_info *osi, tree var)
       || object_sizes[object_size_type][varno] == unknown[object_size_type])
     {
       bitmap_set_bit (computed[object_size_type], varno);
-      bitmap_clear_bit (osi->reexamine, varno);
+      bitmap_clear_bit (&osi->reexamine, varno);
     }
   else
     {
-      bitmap_set_bit (osi->reexamine, varno);
+      bitmap_set_bit (&osi->reexamine, varno);
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
 	  fprintf (dump_file, "Need to reexamine ");
@@ -1046,7 +1039,7 @@  check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
 	  for (sp = osi->tos; sp > osi->stack; )
 	    {
 	      --sp;
-	      bitmap_clear_bit (osi->reexamine, *sp);
+	      bitmap_clear_bit (&osi->reexamine, *sp);
 	      bitmap_set_bit (computed[osi->object_size_type], *sp);
 	      object_sizes[osi->object_size_type][*sp] = 0;
 	      if (*sp == varno)
@@ -1055,7 +1048,7 @@  check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
 	}
       return;
     }
-  else if (! bitmap_bit_p (osi->reexamine, varno))
+  else if (! bitmap_bit_p (&osi->reexamine, varno))
     return;
 
   osi->depths[varno] = depth;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 3702922..68f5a68 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -3291,7 +3291,7 @@  scev_const_prop (void)
   tree name, type, ev;
   gimple phi, ass;
   struct loop *loop, *ex_loop;
-  bitmap ssa_names_to_remove = NULL;
+  auto_bitmap ssa_names_to_remove;
   unsigned i;
   loop_iterator li;
   gimple_stmt_iterator psi;
@@ -3326,20 +3326,16 @@  scev_const_prop (void)
 	  if (name != ev)
 	    replace_uses_by (name, ev);
 
-	  if (!ssa_names_to_remove)
-	    ssa_names_to_remove = BITMAP_ALLOC (NULL);
-	  bitmap_set_bit (ssa_names_to_remove, SSA_NAME_VERSION (name));
+	  bitmap_set_bit (&ssa_names_to_remove, SSA_NAME_VERSION (name));
 	}
     }
 
   /* Remove the ssa names that were replaced by constants.  We do not
      remove them directly in the previous cycle, since this
      invalidates scev cache.  */
-  if (ssa_names_to_remove)
-    {
-      bitmap_iterator bi;
+  bitmap_iterator bi;
 
-      EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
+  EXECUTE_IF_SET_IN_BITMAP (&ssa_names_to_remove, 0, i, bi)
 	{
 	  gimple_stmt_iterator psi;
 	  name = ssa_name (i);
@@ -3350,9 +3346,7 @@  scev_const_prop (void)
 	  remove_phi_node (&psi, true);
 	}
 
-      BITMAP_FREE (ssa_names_to_remove);
       scev_reset ();
-    }
 
   /* Now the regular final value replacement.  */
   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 6a6f027..52fe1fb 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -3020,9 +3020,6 @@  eliminate_degenerate_phis_1 (basic_block bb, bitmap interesting_names)
 static unsigned int
 eliminate_degenerate_phis (void)
 {
-  bitmap interesting_names;
-  bitmap interesting_names1;
-
   /* Bitmap of blocks which need EH information updated.  We can not
      update it on-the-fly as doing so invalidates the dominator tree.  */
   need_eh_cleanup = BITMAP_ALLOC (NULL);
@@ -3037,8 +3034,7 @@  eliminate_degenerate_phis (void)
 
      Experiments have show we generally get better compilation
      time behavior with bitmaps rather than sbitmaps.  */
-  interesting_names = BITMAP_ALLOC (NULL);
-  interesting_names1 = BITMAP_ALLOC (NULL);
+  auto_bitmap interesting_names, interesting_names1;
 
   calculate_dominance_info (CDI_DOMINATORS);
   cfg_altered = false;
@@ -3051,13 +3047,13 @@  eliminate_degenerate_phis (void)
      phase in dominator order.  Presumably this is because walking
      in dominator order leaves fewer PHIs for later examination
      by the worklist phase.  */
-  eliminate_degenerate_phis_1 (ENTRY_BLOCK_PTR, interesting_names);
+  eliminate_degenerate_phis_1 (ENTRY_BLOCK_PTR, &interesting_names);
 
   /* Second phase.  Eliminate second order degenerate PHIs as well
      as trivial copies or constant initializations identified by
      the first phase or this phase.  Basically we keep iterating
      until our set of INTERESTING_NAMEs is empty.   */
-  while (!bitmap_empty_p (interesting_names))
+  while (!bitmap_empty_p (&interesting_names))
     {
       unsigned int i;
       bitmap_iterator bi;
@@ -3065,9 +3061,9 @@  eliminate_degenerate_phis (void)
       /* EXECUTE_IF_SET_IN_BITMAP does not like its bitmap
 	 changed during the loop.  Copy it to another bitmap and
 	 use that.  */
-      bitmap_copy (interesting_names1, interesting_names);
+      bitmap_copy (&interesting_names1, &interesting_names);
 
-      EXECUTE_IF_SET_IN_BITMAP (interesting_names1, 0, i, bi)
+      EXECUTE_IF_SET_IN_BITMAP (&interesting_names1, 0, i, bi)
 	{
 	  tree name = ssa_name (i);
 
@@ -3075,7 +3071,7 @@  eliminate_degenerate_phis (void)
 	     their defining statement was deleted (unreachable).  */
 	  if (name)
 	    eliminate_const_or_copy (SSA_NAME_DEF_STMT (ssa_name (i)),
-				     interesting_names);
+				     &interesting_names);
 	}
     }
 
@@ -3095,8 +3091,6 @@  eliminate_degenerate_phis (void)
       BITMAP_FREE (need_eh_cleanup);
     }
 
-  BITMAP_FREE (interesting_names);
-  BITMAP_FREE (interesting_names1);
   return 0;
 }
 
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 17849a2..58fa24e 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -1036,23 +1036,22 @@  live_worklist (tree_live_info_p live)
   unsigned b;
   basic_block bb;
   sbitmap visited = sbitmap_alloc (last_basic_block + 1);
-  bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack);
+  auto_bitmap tmp (&liveness_bitmap_obstack);
 
   bitmap_clear (visited);
 
   /* Visit all the blocks in reverse order and propagate live on entry values
      into the predecessors blocks.  */
   FOR_EACH_BB_REVERSE (bb)
-    loe_visit_block (live, bb, visited, tmp);
+    loe_visit_block (live, bb, visited, &tmp);
 
   /* Process any blocks which require further iteration.  */
   while (live->stack_top != live->work_stack)
     {
       b = *--(live->stack_top);
-      loe_visit_block (live, BASIC_BLOCK (b), visited, tmp);
+      loe_visit_block (live, BASIC_BLOCK (b), visited, &tmp);
     }
 
-  BITMAP_FREE (tmp);
   sbitmap_free (visited);
 }
 
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 894ff2d..928bac1 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -4970,7 +4970,7 @@  determine_use_iv_costs (struct ivopts_data *data)
   unsigned i, j;
   struct iv_use *use;
   struct iv_cand *cand;
-  bitmap to_clear = BITMAP_ALLOC (NULL);
+  auto_bitmap to_clear;
 
   alloc_use_cost_map (data);
 
@@ -4994,18 +4994,16 @@  determine_use_iv_costs (struct ivopts_data *data)
 	    {
 	      cand = iv_cand (data, j);
 	      if (!determine_use_iv_cost (data, use, cand))
-		bitmap_set_bit (to_clear, j);
+		bitmap_set_bit (&to_clear, j);
 	    }
 
 	  /* Remove the candidates for that the cost is infinite from
 	     the list of related candidates.  */
-	  bitmap_and_compl_into (use->related_cands, to_clear);
-	  bitmap_clear (to_clear);
+	  bitmap_and_compl_into (use->related_cands, &to_clear);
+	  bitmap_clear (&to_clear);
 	}
     }
 
-  BITMAP_FREE (to_clear);
-
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "Use-candidate costs:\n");
@@ -6492,7 +6490,7 @@  remove_unused_ivs (struct ivopts_data *data)
 {
   unsigned j;
   bitmap_iterator bi;
-  bitmap toremove = BITMAP_ALLOC (NULL);
+  auto_bitmap toremove;
 
   /* Figure out an order in which to release SSA DEFs so that we don't
      release something that we'd have to propagate into a debug stmt
@@ -6508,7 +6506,7 @@  remove_unused_ivs (struct ivopts_data *data)
 	  && !info->iv->have_use_for
 	  && !info->preserve_biv)
 	{
-	  bitmap_set_bit (toremove, SSA_NAME_VERSION (info->iv->ssa_name));
+	  bitmap_set_bit (&toremove, SSA_NAME_VERSION (info->iv->ssa_name));
 	  
 	  tree def = info->iv->ssa_name;
 
@@ -6614,9 +6612,7 @@  remove_unused_ivs (struct ivopts_data *data)
 	}
     }
 
-  release_defs_bitset (toremove);
-
-  BITMAP_FREE (toremove);
+  release_defs_bitset (&toremove);
 }
 
 /* Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 0a1c4d4..a5b5c08 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1963,10 +1963,9 @@  strlen_dom_walker::before_dom_children (basic_block bb)
 	      gimple phi = gsi_stmt (gsi);
 	      if (virtual_operand_p (gimple_phi_result (phi)))
 		{
-		  bitmap visited = BITMAP_ALLOC (NULL);
+		  auto_bitmap visited;
 		  int count_vdef = 100;
-		  do_invalidate (dombb, phi, visited, &count_vdef);
-		  BITMAP_FREE (visited);
+		  do_invalidate (dombb, phi, &visited, &count_vdef);
 		  if (count_vdef == 0)
 		    {
 		      /* If there were too many vdefs in between immediate
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index db95ce1..af41619 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -1344,15 +1344,14 @@  deps_ok_for_redirect_from_bb_to_bb (basic_block from, basic_block to)
   basic_block cd, dep_bb = BB_DEP_BB (to);
   edge_iterator ei;
   edge e;
-  bitmap from_preds = BITMAP_ALLOC (NULL);
+  auto_bitmap from_preds;
 
   if (dep_bb == NULL)
     return true;
 
   FOR_EACH_EDGE (e, ei, from->preds)
-    bitmap_set_bit (from_preds, e->src->index);
-  cd = nearest_common_dominator_for_set (CDI_DOMINATORS, from_preds);
-  BITMAP_FREE (from_preds);
+    bitmap_set_bit (&from_preds, e->src->index);
+  cd = nearest_common_dominator_for_set (CDI_DOMINATORS, &from_preds);
 
   return dominated_by_p (CDI_DOMINATORS, dep_bb, cd);
 }