On Fri, 29 Nov 2013, Richard Biener wrote:

> 
> The following re-org allows a cheaper fix to PR59208 than
> a push/pop_cfun pair around a single update_stmt call.
> 
> It's simple to make the SSA operand machinery cfun-agnostic
> as it has few direct uses and does not use any APIs that
> implicitely use cfun.
> 
> Thus the patch adds and uses a new update_stmt_fn function.
> 
> Bootstrap and regtest running on x86_64-unknown-linux-gnu.

This is what I have committed.

Richard.

2013-11-29  Richard Biener  <rguent...@suse.de>

        PR middle-end/59208
        * tree-ssa-operands.h (fini_ssa_operands, verify_ssa_operands,
        free_stmt_operands, update_stmt_operands): Add struct function
        argument.
        * tree-ssa-operands.c: Remove uses of cfun, propagate struct
        function argument from fini_ssa_operands, verify_ssa_operands,
        free_stmt_operands and update_stmt_operands everywhere.
        * tree-ssanames.h (release_ssa_name_fn): New.
        (release_ssa_name): Inline wrapper around release_ssa_name_fn.
        * tree-ssanames.c (release_ssa_name): Rename to ...
        (release_ssa_name_fn): ... this and add struct function argument.
        * gimple-ssa.h (update_stmt, update_stmt_if_modified): Adjust.
        (update_stmt_fn): New function.
        * tree-cfg.c (move_block_to_fn): Adjust.
        * tree-if-conv.c (free_bb_predicate): Likewise.
        * tree-ssa.c (verify_ssa): Likewise.
        (delete_tree_ssa): Likewise.
        * gimple-pretty-print.c (dump_gimple_mem_ops): Remove guard.
        * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Call
        update_stmt_fn instead of update_stmt.

        * g++.dg/torture/pr59208.C: New testcase.

Index: gcc/tree-ssa-operands.h
===================================================================
*** gcc/tree-ssa-operands.h.orig        2013-11-29 11:45:49.000000000 +0100
--- gcc/tree-ssa-operands.h     2013-11-29 13:10:18.072553361 +0100
*************** struct GTY(()) ssa_operands {
*** 91,100 ****
  
  extern bool ssa_operands_active (struct function *);
  extern void init_ssa_operands (struct function *fn);
! extern void fini_ssa_operands (void);
! extern bool verify_ssa_operands (gimple stmt);
! extern void free_stmt_operands (gimple);
! extern void update_stmt_operands (gimple);
  extern void swap_ssa_operands (gimple, tree *, tree *);
  extern bool verify_imm_links (FILE *f, tree var);
  
--- 91,100 ----
  
  extern bool ssa_operands_active (struct function *);
  extern void init_ssa_operands (struct function *fn);
! extern void fini_ssa_operands (struct function *);
! extern bool verify_ssa_operands (struct function *, gimple stmt);
! extern void free_stmt_operands (struct function *, gimple);
! extern void update_stmt_operands (struct function *, gimple);
  extern void swap_ssa_operands (gimple, tree *, tree *);
  extern bool verify_imm_links (FILE *f, tree var);
  
Index: gcc/tree-ssa-operands.c
===================================================================
*** gcc/tree-ssa-operands.c.orig        2013-11-29 11:45:49.000000000 +0100
--- gcc/tree-ssa-operands.c     2013-11-29 13:23:30.781756355 +0100
*************** static tree build_vuse;
*** 129,135 ****
     compilations of multiple functions.  */
  static bitmap_obstack operands_bitmap_obstack;
  
! static void get_expr_operands (gimple, tree *, int);
  
  /* Number of functions with initialized ssa_operands.  */
  static int n_initialized = 0;
--- 129,135 ----
     compilations of multiple functions.  */
  static bitmap_obstack operands_bitmap_obstack;
  
! static void get_expr_operands (struct function *, gimple, tree *, int);
  
  /* Number of functions with initialized ssa_operands.  */
  static int n_initialized = 0;
*************** init_ssa_operands (struct function *fn)
*** 217,223 ****
  /* Dispose of anything required by the operand routines.  */
  
  void
! fini_ssa_operands (void)
  {
    struct ssa_operand_memory_d *ptr;
  
--- 217,223 ----
  /* Dispose of anything required by the operand routines.  */
  
  void
! fini_ssa_operands (struct function *fn)
  {
    struct ssa_operand_memory_d *ptr;
  
*************** fini_ssa_operands (void)
*** 228,276 ****
        build_vuse = NULL_TREE;
      }
  
!   gimple_ssa_operands (cfun)->free_uses = NULL;
  
!   while ((ptr = gimple_ssa_operands (cfun)->operand_memory) != NULL)
      {
!       gimple_ssa_operands (cfun)->operand_memory
!       = gimple_ssa_operands (cfun)->operand_memory->next;
        ggc_free (ptr);
      }
  
!   gimple_ssa_operands (cfun)->ops_active = false;
  
    if (!n_initialized)
      bitmap_obstack_release (&operands_bitmap_obstack);
  
!   cfun->gimple_df->vop = NULL_TREE;
  }
  
  
  /* Return memory for an operand of size SIZE.  */
  
  static inline void *
! ssa_operand_alloc (unsigned size)
  {
    char *ptr;
  
    gcc_assert (size == sizeof (struct use_optype_d));
  
!   if (gimple_ssa_operands (cfun)->operand_memory_index + size
!       >= gimple_ssa_operands (cfun)->ssa_operand_mem_size)
      {
        struct ssa_operand_memory_d *ptr;
  
!       switch (gimple_ssa_operands (cfun)->ssa_operand_mem_size)
        {
        case OP_SIZE_INIT:
!         gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_1;
          break;
        case OP_SIZE_1:
!         gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_2;
          break;
        case OP_SIZE_2:
        case OP_SIZE_3:
!         gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_3;
          break;
        default:
          gcc_unreachable ();
--- 228,276 ----
        build_vuse = NULL_TREE;
      }
  
!   gimple_ssa_operands (fn)->free_uses = NULL;
  
!   while ((ptr = gimple_ssa_operands (fn)->operand_memory) != NULL)
      {
!       gimple_ssa_operands (fn)->operand_memory
!       = gimple_ssa_operands (fn)->operand_memory->next;
        ggc_free (ptr);
      }
  
!   gimple_ssa_operands (fn)->ops_active = false;
  
    if (!n_initialized)
      bitmap_obstack_release (&operands_bitmap_obstack);
  
!   fn->gimple_df->vop = NULL_TREE;
  }
  
  
  /* Return memory for an operand of size SIZE.  */
  
  static inline void *
! ssa_operand_alloc (struct function *fn, unsigned size)
  {
    char *ptr;
  
    gcc_assert (size == sizeof (struct use_optype_d));
  
!   if (gimple_ssa_operands (fn)->operand_memory_index + size
!       >= gimple_ssa_operands (fn)->ssa_operand_mem_size)
      {
        struct ssa_operand_memory_d *ptr;
  
!       switch (gimple_ssa_operands (fn)->ssa_operand_mem_size)
        {
        case OP_SIZE_INIT:
!         gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_1;
          break;
        case OP_SIZE_1:
!         gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_2;
          break;
        case OP_SIZE_2:
        case OP_SIZE_3:
!         gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_3;
          break;
        default:
          gcc_unreachable ();
*************** ssa_operand_alloc (unsigned size)
*** 278,293 ****
  
  
        ptr = ggc_alloc_ssa_operand_memory_d (sizeof (void *)
!                         + gimple_ssa_operands (cfun)->ssa_operand_mem_size);
  
!       ptr->next = gimple_ssa_operands (cfun)->operand_memory;
!       gimple_ssa_operands (cfun)->operand_memory = ptr;
!       gimple_ssa_operands (cfun)->operand_memory_index = 0;
      }
  
!   ptr = &(gimple_ssa_operands (cfun)->operand_memory
!         ->mem[gimple_ssa_operands (cfun)->operand_memory_index]);
!   gimple_ssa_operands (cfun)->operand_memory_index += size;
    return ptr;
  }
  
--- 278,293 ----
  
  
        ptr = ggc_alloc_ssa_operand_memory_d (sizeof (void *)
!                         + gimple_ssa_operands (fn)->ssa_operand_mem_size);
  
!       ptr->next = gimple_ssa_operands (fn)->operand_memory;
!       gimple_ssa_operands (fn)->operand_memory = ptr;
!       gimple_ssa_operands (fn)->operand_memory_index = 0;
      }
  
!   ptr = &(gimple_ssa_operands (fn)->operand_memory
!         ->mem[gimple_ssa_operands (fn)->operand_memory_index]);
!   gimple_ssa_operands (fn)->operand_memory_index += size;
    return ptr;
  }
  
*************** ssa_operand_alloc (unsigned size)
*** 295,312 ****
  /* Allocate a USE operand.  */
  
  static inline struct use_optype_d *
! alloc_use (void)
  {
    struct use_optype_d *ret;
!   if (gimple_ssa_operands (cfun)->free_uses)
      {
!       ret = gimple_ssa_operands (cfun)->free_uses;
!       gimple_ssa_operands (cfun)->free_uses
!       = gimple_ssa_operands (cfun)->free_uses->next;
      }
    else
      ret = (struct use_optype_d *)
!           ssa_operand_alloc (sizeof (struct use_optype_d));
    return ret;
  }
  
--- 295,312 ----
  /* Allocate a USE operand.  */
  
  static inline struct use_optype_d *
! alloc_use (struct function *fn)
  {
    struct use_optype_d *ret;
!   if (gimple_ssa_operands (fn)->free_uses)
      {
!       ret = gimple_ssa_operands (fn)->free_uses;
!       gimple_ssa_operands (fn)->free_uses
!       = gimple_ssa_operands (fn)->free_uses->next;
      }
    else
      ret = (struct use_optype_d *)
!           ssa_operand_alloc (fn, sizeof (struct use_optype_d));
    return ret;
  }
  
*************** alloc_use (void)
*** 314,324 ****
  /* Adds OP to the list of uses of statement STMT after LAST.  */
  
  static inline use_optype_p
! add_use_op (gimple stmt, tree *op, use_optype_p last)
  {
    use_optype_p new_use;
  
!   new_use = alloc_use ();
    USE_OP_PTR (new_use)->use = op;
    link_imm_use_stmt (USE_OP_PTR (new_use), *op, stmt);
    last->next = new_use;
--- 314,324 ----
  /* Adds OP to the list of uses of statement STMT after LAST.  */
  
  static inline use_optype_p
! add_use_op (struct function *fn, gimple stmt, tree *op, use_optype_p last)
  {
    use_optype_p new_use;
  
!   new_use = alloc_use (fn);
    USE_OP_PTR (new_use)->use = op;
    link_imm_use_stmt (USE_OP_PTR (new_use), *op, stmt);
    last->next = new_use;
*************** add_use_op (gimple stmt, tree *op, use_o
*** 332,338 ****
     TODO -- Make build_defs vec of tree *.  */
  
  static inline void
! finalize_ssa_defs (gimple stmt)
  {
    /* Pre-pend the vdef we may have built.  */
    if (build_vdef != NULL_TREE)
--- 332,338 ----
     TODO -- Make build_defs vec of tree *.  */
  
  static inline void
! finalize_ssa_defs (struct function *fn, gimple stmt)
  {
    /* Pre-pend the vdef we may have built.  */
    if (build_vdef != NULL_TREE)
*************** finalize_ssa_defs (gimple stmt)
*** 352,358 ****
        if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
        {
          unlink_stmt_vdef (stmt);
!         release_ssa_name (gimple_vdef (stmt));
        }
        gimple_set_vdef (stmt, NULL_TREE);
      }
--- 352,358 ----
        if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
        {
          unlink_stmt_vdef (stmt);
!         release_ssa_name_fn (fn, gimple_vdef (stmt));
        }
        gimple_set_vdef (stmt, NULL_TREE);
      }
*************** finalize_ssa_defs (gimple stmt)
*** 361,368 ****
    if (gimple_vdef (stmt)
        && TREE_CODE (gimple_vdef (stmt)) != SSA_NAME)
      {
!       cfun->gimple_df->rename_vops = 1;
!       cfun->gimple_df->ssa_renaming_needed = 1;
      }
  }
  
--- 361,368 ----
    if (gimple_vdef (stmt)
        && TREE_CODE (gimple_vdef (stmt)) != SSA_NAME)
      {
!       fn->gimple_df->rename_vops = 1;
!       fn->gimple_df->ssa_renaming_needed = 1;
      }
  }
  
*************** finalize_ssa_defs (gimple stmt)
*** 371,377 ****
     TODO -- Make build_uses vec of tree *.  */
  
  static inline void
! finalize_ssa_uses (gimple stmt)
  {
    unsigned new_i;
    struct use_optype_d new_list;
--- 371,377 ----
     TODO -- Make build_uses vec of tree *.  */
  
  static inline void
! finalize_ssa_uses (struct function *fn, gimple stmt)
  {
    unsigned new_i;
    struct use_optype_d new_list;
*************** finalize_ssa_uses (gimple stmt)
*** 405,412 ****
      {
        for (ptr = old_ops; ptr; ptr = ptr->next)
        delink_imm_use (USE_OP_PTR (ptr));
!       old_ops->next = gimple_ssa_operands (cfun)->free_uses;
!       gimple_ssa_operands (cfun)->free_uses = old_ops;
      }
  
    /* If we added a VUSE, make sure to set the operand if it is not already
--- 405,412 ----
      {
        for (ptr = old_ops; ptr; ptr = ptr->next)
        delink_imm_use (USE_OP_PTR (ptr));
!       old_ops->next = gimple_ssa_operands (fn)->free_uses;
!       gimple_ssa_operands (fn)->free_uses = old_ops;
      }
  
    /* If we added a VUSE, make sure to set the operand if it is not already
*************** finalize_ssa_uses (gimple stmt)
*** 414,429 ****
    if (build_vuse != NULL_TREE
        && gimple_vuse (stmt) == NULL_TREE)
      {
!       gimple_set_vuse (stmt, gimple_vop (cfun));
!       cfun->gimple_df->rename_vops = 1;
!       cfun->gimple_df->ssa_renaming_needed = 1;
      }
  
    /* Now create nodes for all the new nodes.  */
    for (new_i = 0; new_i < build_uses.length (); new_i++)
      {
        tree *op = (tree *) build_uses[new_i];
!       last = add_use_op (stmt, op, last);
      }
  
    /* Now set the stmt's operands.  */
--- 414,429 ----
    if (build_vuse != NULL_TREE
        && gimple_vuse (stmt) == NULL_TREE)
      {
!       gimple_set_vuse (stmt, gimple_vop (fn));
!       fn->gimple_df->rename_vops = 1;
!       fn->gimple_df->ssa_renaming_needed = 1;
      }
  
    /* Now create nodes for all the new nodes.  */
    for (new_i = 0; new_i < build_uses.length (); new_i++)
      {
        tree *op = (tree *) build_uses[new_i];
!       last = add_use_op (fn, stmt, op, last);
      }
  
    /* Now set the stmt's operands.  */
*************** cleanup_build_arrays (void)
*** 446,455 ****
  /* Finalize all the build vectors, fill the new ones into INFO.  */
  
  static inline void
! finalize_ssa_stmt_operands (gimple stmt)
  {
!   finalize_ssa_defs (stmt);
!   finalize_ssa_uses (stmt);
    cleanup_build_arrays ();
  }
  
--- 446,455 ----
  /* Finalize all the build vectors, fill the new ones into INFO.  */
  
  static inline void
! finalize_ssa_stmt_operands (struct function *fn, gimple stmt)
  {
!   finalize_ssa_defs (fn, stmt);
!   finalize_ssa_uses (fn, stmt);
    cleanup_build_arrays ();
  }
  
*************** append_vuse (tree var)
*** 509,515 ****
  /* Add virtual operands for STMT.  FLAGS is as in get_expr_operands.  */
  
  static void
! add_virtual_operand (gimple stmt ATTRIBUTE_UNUSED, int flags)
  {
    /* Add virtual operands to the stmt, unless the caller has specifically
       requested not to do that (used when adding operands inside an
--- 509,516 ----
  /* Add virtual operands for STMT.  FLAGS is as in get_expr_operands.  */
  
  static void
! add_virtual_operand (struct function *fn,
!                    gimple stmt ATTRIBUTE_UNUSED, int flags)
  {
    /* Add virtual operands to the stmt, unless the caller has specifically
       requested not to do that (used when adding operands inside an
*************** add_virtual_operand (gimple stmt ATTRIBU
*** 520,528 ****
    gcc_assert (!is_gimple_debug (stmt));
  
    if (flags & opf_def)
!     append_vdef (gimple_vop (cfun));
    else
!     append_vuse (gimple_vop (cfun));
  }
  
  
--- 521,529 ----
    gcc_assert (!is_gimple_debug (stmt));
  
    if (flags & opf_def)
!     append_vdef (gimple_vop (fn));
    else
!     append_vuse (gimple_vop (fn));
  }
  
  
*************** add_virtual_operand (gimple stmt ATTRIBU
*** 532,538 ****
     added to virtual operands.  */
  
  static void
! add_stmt_operand (tree *var_p, gimple stmt, int flags)
  {
    tree var = *var_p;
  
--- 533,539 ----
     added to virtual operands.  */
  
  static void
! add_stmt_operand (struct function *fn, tree *var_p, gimple stmt, int flags)
  {
    tree var = *var_p;
  
*************** add_stmt_operand (tree *var_p, gimple st
*** 546,552 ****
        else
        append_use (var_p);
        if (DECL_P (*var_p))
!       cfun->gimple_df->ssa_renaming_needed = 1;
      }
    else
      {
--- 547,553 ----
        else
        append_use (var_p);
        if (DECL_P (*var_p))
!       fn->gimple_df->ssa_renaming_needed = 1;
      }
    else
      {
*************** add_stmt_operand (tree *var_p, gimple st
*** 556,562 ****
        gimple_set_has_volatile_ops (stmt, true);
  
        /* The variable is a memory access.  Add virtual operands.  */
!       add_virtual_operand (stmt, flags);
      }
  }
  
--- 557,563 ----
        gimple_set_has_volatile_ops (stmt, true);
  
        /* The variable is a memory access.  Add virtual operands.  */
!       add_virtual_operand (fn, stmt, flags);
      }
  }
  
*************** mark_address_taken (tree ref)
*** 596,602 ****
     FLAGS is as in get_expr_operands.  */
  
  static void
! get_indirect_ref_operands (gimple stmt, tree expr, int flags)
  {
    tree *pptr = &TREE_OPERAND (expr, 0);
  
--- 597,604 ----
     FLAGS is as in get_expr_operands.  */
  
  static void
! get_indirect_ref_operands (struct function *fn,
!                          gimple stmt, tree expr, int flags)
  {
    tree *pptr = &TREE_OPERAND (expr, 0);
  
*************** get_indirect_ref_operands (gimple stmt,
*** 605,614 ****
      gimple_set_has_volatile_ops (stmt, true);
  
    /* Add the VOP.  */
!   add_virtual_operand (stmt, flags);
  
    /* If requested, add a USE operand for the base pointer.  */
!   get_expr_operands (stmt, pptr,
                     opf_non_addressable | opf_use
                     | (flags & (opf_no_vops|opf_not_non_addressable)));
  }
--- 607,616 ----
      gimple_set_has_volatile_ops (stmt, true);
  
    /* Add the VOP.  */
!   add_virtual_operand (fn, stmt, flags);
  
    /* If requested, add a USE operand for the base pointer.  */
!   get_expr_operands (fn, stmt, pptr,
                     opf_non_addressable | opf_use
                     | (flags & (opf_no_vops|opf_not_non_addressable)));
  }
*************** get_indirect_ref_operands (gimple stmt,
*** 617,634 ****
  /* A subroutine of get_expr_operands to handle TARGET_MEM_REF.  */
  
  static void
! get_tmr_operands (gimple stmt, tree expr, int flags)
  {
    if (!(flags & opf_no_vops)
        && TREE_THIS_VOLATILE (expr))
      gimple_set_has_volatile_ops (stmt, true);
  
    /* First record the real operands.  */
!   get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
!   get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & 
opf_no_vops));
!   get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & 
opf_no_vops));
  
!   add_virtual_operand (stmt, flags);
  }
  
  
--- 619,639 ----
  /* A subroutine of get_expr_operands to handle TARGET_MEM_REF.  */
  
  static void
! get_tmr_operands (struct function *fn, gimple stmt, tree expr, int flags)
  {
    if (!(flags & opf_no_vops)
        && TREE_THIS_VOLATILE (expr))
      gimple_set_has_volatile_ops (stmt, true);
  
    /* First record the real operands.  */
!   get_expr_operands (fn, stmt,
!                    &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
!   get_expr_operands (fn, stmt,
!                    &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
!   get_expr_operands (fn, stmt,
!                    &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
  
!   add_virtual_operand (fn, stmt, flags);
  }
  
  
*************** get_tmr_operands (gimple stmt, tree expr
*** 636,642 ****
     escape, add them to the VDEF/VUSE lists for it.  */
  
  static void
! maybe_add_call_vops (gimple stmt)
  {
    int call_flags = gimple_call_flags (stmt);
  
--- 641,647 ----
     escape, add them to the VDEF/VUSE lists for it.  */
  
  static void
! maybe_add_call_vops (struct function *fn, gimple stmt)
  {
    int call_flags = gimple_call_flags (stmt);
  
*************** maybe_add_call_vops (gimple stmt)
*** 649,657 ****
         A 'noreturn' function might, but since we don't return anyway
         there is no point in recording that.  */
        if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
!       add_virtual_operand (stmt, opf_def);
        else if (!(call_flags & ECF_CONST))
!       add_virtual_operand (stmt, opf_use);
      }
  }
  
--- 654,662 ----
         A 'noreturn' function might, but since we don't return anyway
         there is no point in recording that.  */
        if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
!       add_virtual_operand (fn, stmt, opf_def);
        else if (!(call_flags & ECF_CONST))
!       add_virtual_operand (fn, stmt, opf_use);
      }
  }
  
*************** maybe_add_call_vops (gimple stmt)
*** 659,665 ****
  /* Scan operands in the ASM_EXPR stmt referred to in INFO.  */
  
  static void
! get_asm_expr_operands (gimple stmt)
  {
    size_t i, noutputs;
    const char **oconstraints;
--- 664,670 ----
  /* Scan operands in the ASM_EXPR stmt referred to in INFO.  */
  
  static void
! get_asm_expr_operands (struct function *fn, gimple stmt)
  {
    size_t i, noutputs;
    const char **oconstraints;
*************** get_asm_expr_operands (gimple stmt)
*** 686,692 ****
        if (!allows_reg && allows_mem)
        mark_address_taken (TREE_VALUE (link));
  
!       get_expr_operands (stmt, &TREE_VALUE (link), opf_def | 
opf_not_non_addressable);
      }
  
    /* Gather all input operands.  */
--- 691,698 ----
        if (!allows_reg && allows_mem)
        mark_address_taken (TREE_VALUE (link));
  
!       get_expr_operands (fn, stmt,
!                        &TREE_VALUE (link), opf_def | opf_not_non_addressable);
      }
  
    /* Gather all input operands.  */
*************** get_asm_expr_operands (gimple stmt)
*** 702,713 ****
        if (!allows_reg && allows_mem)
        mark_address_taken (TREE_VALUE (link));
  
!       get_expr_operands (stmt, &TREE_VALUE (link), opf_not_non_addressable);
      }
  
    /* Clobber all memory and addressable symbols for asm ("" : : : "memory");  
*/
    if (gimple_asm_clobbers_memory_p (stmt))
!     add_virtual_operand (stmt, opf_def);
  }
  
  
--- 708,719 ----
        if (!allows_reg && allows_mem)
        mark_address_taken (TREE_VALUE (link));
  
!       get_expr_operands (fn, stmt, &TREE_VALUE (link), 
opf_not_non_addressable);
      }
  
    /* Clobber all memory and addressable symbols for asm ("" : : : "memory");  
*/
    if (gimple_asm_clobbers_memory_p (stmt))
!     add_virtual_operand (fn, stmt, opf_def);
  }
  
  
*************** get_asm_expr_operands (gimple stmt)
*** 716,722 ****
     interpret the operands found.  */
  
  static void
! get_expr_operands (gimple stmt, tree *expr_p, int flags)
  {
    enum tree_code code;
    enum tree_code_class codeclass;
--- 722,728 ----
     interpret the operands found.  */
  
  static void
! get_expr_operands (struct function *fn, gimple stmt, tree *expr_p, int flags)
  {
    enum tree_code code;
    enum tree_code_class codeclass;
*************** get_expr_operands (gimple stmt, tree *ex
*** 755,761 ****
         here are ARRAY_REF indices which will always be real operands
         (GIMPLE does not allow non-registers as array indices).  */
        flags |= opf_no_vops;
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 0),
                         flags | opf_not_non_addressable);
        return;
  
--- 761,767 ----
         here are ARRAY_REF indices which will always be real operands
         (GIMPLE does not allow non-registers as array indices).  */
        flags |= opf_no_vops;
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0),
                         flags | opf_not_non_addressable);
        return;
  
*************** get_expr_operands (gimple stmt, tree *ex
*** 763,769 ****
      case VAR_DECL:
      case PARM_DECL:
      case RESULT_DECL:
!       add_stmt_operand (expr_p, stmt, flags);
        return;
  
      case DEBUG_EXPR_DECL:
--- 769,775 ----
      case VAR_DECL:
      case PARM_DECL:
      case RESULT_DECL:
!       add_stmt_operand (fn, expr_p, stmt, flags);
        return;
  
      case DEBUG_EXPR_DECL:
*************** get_expr_operands (gimple stmt, tree *ex
*** 771,781 ****
        return;
  
      case MEM_REF:
!       get_indirect_ref_operands (stmt, expr, flags);
        return;
  
      case TARGET_MEM_REF:
!       get_tmr_operands (stmt, expr, flags);
        return;
  
      case ARRAY_REF:
--- 777,787 ----
        return;
  
      case MEM_REF:
!       get_indirect_ref_operands (fn, stmt, expr, flags);
        return;
  
      case TARGET_MEM_REF:
!       get_tmr_operands (fn, stmt, expr, flags);
        return;
  
      case ARRAY_REF:
*************** get_expr_operands (gimple stmt, tree *ex
*** 788,807 ****
            && TREE_THIS_VOLATILE (expr))
          gimple_set_has_volatile_ops (stmt, true);
  
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
  
        if (code == COMPONENT_REF)
          {
            if (!(flags & opf_no_vops)
                && TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1)))
              gimple_set_has_volatile_ops (stmt, true);
!           get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
          }
        else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
          {
!             get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
!             get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
!             get_expr_operands (stmt, &TREE_OPERAND (expr, 3), uflags);
          }
  
        return;
--- 794,813 ----
            && TREE_THIS_VOLATILE (expr))
          gimple_set_has_volatile_ops (stmt, true);
  
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
  
        if (code == COMPONENT_REF)
          {
            if (!(flags & opf_no_vops)
                && TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1)))
              gimple_set_has_volatile_ops (stmt, true);
!           get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), uflags);
          }
        else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
          {
!             get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), uflags);
!             get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), uflags);
!             get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 3), uflags);
          }
  
        return;
*************** get_expr_operands (gimple stmt, tree *ex
*** 810,825 ****
      case WITH_SIZE_EXPR:
        /* WITH_SIZE_EXPR is a pass-through reference to its first argument,
         and an rvalue reference to its second argument.  */
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
        return;
  
      case COND_EXPR:
      case VEC_COND_EXPR:
      case VEC_PERM_EXPR:
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 0), uflags);
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
        return;
  
      case CONSTRUCTOR:
--- 816,831 ----
      case WITH_SIZE_EXPR:
        /* WITH_SIZE_EXPR is a pass-through reference to its first argument,
         and an rvalue reference to its second argument.  */
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), uflags);
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
        return;
  
      case COND_EXPR:
      case VEC_COND_EXPR:
      case VEC_PERM_EXPR:
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), uflags);
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), uflags);
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), uflags);
        return;
  
      case CONSTRUCTOR:
*************** get_expr_operands (gimple stmt, tree *ex
*** 839,845 ****
        for (idx = 0;
             vec_safe_iterate (CONSTRUCTOR_ELTS (expr), idx, &ce);
             idx++)
!         get_expr_operands (stmt, &ce->value, uflags);
  
        return;
        }
--- 845,851 ----
        for (idx = 0;
             vec_safe_iterate (CONSTRUCTOR_ELTS (expr), idx, &ce);
             idx++)
!         get_expr_operands (fn, stmt, &ce->value, uflags);
  
        return;
        }
*************** get_expr_operands (gimple stmt, tree *ex
*** 852,858 ****
  
      case VIEW_CONVERT_EXPR:
      do_unary:
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
        return;
  
      case COMPOUND_EXPR:
--- 858,864 ----
  
      case VIEW_CONVERT_EXPR:
      do_unary:
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
        return;
  
      case COMPOUND_EXPR:
*************** get_expr_operands (gimple stmt, tree *ex
*** 860,867 ****
      case ASSERT_EXPR:
      do_binary:
        {
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
        return;
        }
  
--- 866,873 ----
      case ASSERT_EXPR:
      do_binary:
        {
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), flags);
        return;
        }
  
*************** get_expr_operands (gimple stmt, tree *ex
*** 871,879 ****
      case WIDEN_MULT_MINUS_EXPR:
      case FMA_EXPR:
        {
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
!       get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
        return;
        }
  
--- 877,885 ----
      case WIDEN_MULT_MINUS_EXPR:
      case FMA_EXPR:
        {
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), flags);
!       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), flags);
        return;
        }
  
*************** get_expr_operands (gimple stmt, tree *ex
*** 907,913 ****
     build_* operand vectors will have potential operands in them.  */
  
  static void
! parse_ssa_operands (gimple stmt)
  {
    enum gimple_code code = gimple_code (stmt);
    size_t i, n, start = 0;
--- 913,919 ----
     build_* operand vectors will have potential operands in them.  */
  
  static void
! parse_ssa_operands (struct function *fn, gimple stmt)
  {
    enum gimple_code code = gimple_code (stmt);
    size_t i, n, start = 0;
*************** parse_ssa_operands (gimple stmt)
*** 915,946 ****
    switch (code)
      {
      case GIMPLE_ASM:
!       get_asm_expr_operands (stmt);
        break;
  
      case GIMPLE_TRANSACTION:
        /* The start of a transaction is a memory barrier.  */
!       add_virtual_operand (stmt, opf_def | opf_use);
        break;
  
      case GIMPLE_DEBUG:
        if (gimple_debug_bind_p (stmt)
          && gimple_debug_bind_has_value_p (stmt))
!       get_expr_operands (stmt, gimple_debug_bind_get_value_ptr (stmt),
                           opf_use | opf_no_vops);
        break;
  
      case GIMPLE_RETURN:
!       append_vuse (gimple_vop (cfun));
        goto do_default;
  
      case GIMPLE_CALL:
        /* Add call-clobbered operands, if needed.  */
!       maybe_add_call_vops (stmt);
        /* FALLTHRU */
  
      case GIMPLE_ASSIGN:
!       get_expr_operands (stmt, gimple_op_ptr (stmt, 0), opf_def);
        start = 1;
        /* FALLTHRU */
  
--- 921,952 ----
    switch (code)
      {
      case GIMPLE_ASM:
!       get_asm_expr_operands (fn, stmt);
        break;
  
      case GIMPLE_TRANSACTION:
        /* The start of a transaction is a memory barrier.  */
!       add_virtual_operand (fn, stmt, opf_def | opf_use);
        break;
  
      case GIMPLE_DEBUG:
        if (gimple_debug_bind_p (stmt)
          && gimple_debug_bind_has_value_p (stmt))
!       get_expr_operands (fn, stmt, gimple_debug_bind_get_value_ptr (stmt),
                           opf_use | opf_no_vops);
        break;
  
      case GIMPLE_RETURN:
!       append_vuse (gimple_vop (fn));
        goto do_default;
  
      case GIMPLE_CALL:
        /* Add call-clobbered operands, if needed.  */
!       maybe_add_call_vops (fn, stmt);
        /* FALLTHRU */
  
      case GIMPLE_ASSIGN:
!       get_expr_operands (fn, stmt, gimple_op_ptr (stmt, 0), opf_def);
        start = 1;
        /* FALLTHRU */
  
*************** parse_ssa_operands (gimple stmt)
*** 948,954 ****
      do_default:
        n = gimple_num_ops (stmt);
        for (i = start; i < n; i++)
!       get_expr_operands (stmt, gimple_op_ptr (stmt, i), opf_use);
        break;
      }
  }
--- 954,960 ----
      do_default:
        n = gimple_num_ops (stmt);
        for (i = start; i < n; i++)
!       get_expr_operands (fn, stmt, gimple_op_ptr (stmt, i), opf_use);
        break;
      }
  }
*************** parse_ssa_operands (gimple stmt)
*** 957,976 ****
  /* Create an operands cache for STMT.  */
  
  static void
! build_ssa_operands (gimple stmt)
  {
    /* Initially assume that the statement has no volatile operands.  */
    gimple_set_has_volatile_ops (stmt, false);
  
    start_ssa_stmt_operands ();
!   parse_ssa_operands (stmt);
!   finalize_ssa_stmt_operands (stmt);
  }
  
  /* Verifies SSA statement operands.  */
  
  DEBUG_FUNCTION bool
! verify_ssa_operands (gimple stmt)
  {
    use_operand_p use_p;
    def_operand_p def_p;
--- 963,982 ----
  /* Create an operands cache for STMT.  */
  
  static void
! build_ssa_operands (struct function *fn, gimple stmt)
  {
    /* Initially assume that the statement has no volatile operands.  */
    gimple_set_has_volatile_ops (stmt, false);
  
    start_ssa_stmt_operands ();
!   parse_ssa_operands (fn, stmt);
!   finalize_ssa_stmt_operands (fn, stmt);
  }
  
  /* Verifies SSA statement operands.  */
  
  DEBUG_FUNCTION bool
! verify_ssa_operands (struct function *fn, gimple stmt)
  {
    use_operand_p use_p;
    def_operand_p def_p;
*************** verify_ssa_operands (gimple stmt)
*** 982,988 ****
    /* build_ssa_operands w/o finalizing them.  */
    gimple_set_has_volatile_ops (stmt, false);
    start_ssa_stmt_operands ();
!   parse_ssa_operands (stmt);
  
    /* Now verify the built operands are the same as present in STMT.  */
    def = gimple_vdef (stmt);
--- 988,994 ----
    /* build_ssa_operands w/o finalizing them.  */
    gimple_set_has_volatile_ops (stmt, false);
    start_ssa_stmt_operands ();
!   parse_ssa_operands (fn, stmt);
  
    /* Now verify the built operands are the same as present in STMT.  */
    def = gimple_vdef (stmt);
*************** verify_ssa_operands (gimple stmt)
*** 1059,1065 ****
     the stmt operand lists.  */
  
  void
! free_stmt_operands (gimple stmt)
  {
    use_optype_p uses = gimple_use_ops (stmt), last_use;
  
--- 1065,1071 ----
     the stmt operand lists.  */
  
  void
! free_stmt_operands (struct function *fn, gimple stmt)
  {
    use_optype_p uses = gimple_use_ops (stmt), last_use;
  
*************** free_stmt_operands (gimple stmt)
*** 1068,1075 ****
        for (last_use = uses; last_use->next; last_use = last_use->next)
        delink_imm_use (USE_OP_PTR (last_use));
        delink_imm_use (USE_OP_PTR (last_use));
!       last_use->next = gimple_ssa_operands (cfun)->free_uses;
!       gimple_ssa_operands (cfun)->free_uses = uses;
        gimple_set_use_ops (stmt, NULL);
      }
  
--- 1074,1081 ----
        for (last_use = uses; last_use->next; last_use = last_use->next)
        delink_imm_use (USE_OP_PTR (last_use));
        delink_imm_use (USE_OP_PTR (last_use));
!       last_use->next = gimple_ssa_operands (fn)->free_uses;
!       gimple_ssa_operands (fn)->free_uses = uses;
        gimple_set_use_ops (stmt, NULL);
      }
  
*************** free_stmt_operands (gimple stmt)
*** 1084,1094 ****
  /* Get the operands of statement STMT.  */
  
  void
! update_stmt_operands (gimple stmt)
  {
    /* If update_stmt_operands is called before SSA is initialized, do
       nothing.  */
!   if (!ssa_operands_active (cfun))
      return;
  
    timevar_push (TV_TREE_OPS);
--- 1090,1100 ----
  /* Get the operands of statement STMT.  */
  
  void
! update_stmt_operands (struct function *fn, gimple stmt)
  {
    /* If update_stmt_operands is called before SSA is initialized, do
       nothing.  */
!   if (!ssa_operands_active (fn))
      return;
  
    timevar_push (TV_TREE_OPS);
*************** update_stmt_operands (gimple stmt)
*** 1097,1106 ****
       split_bbs_on_noreturn_calls during cfg cleanup.  */
    if (is_gimple_call (stmt)
        && gimple_call_noreturn_p (stmt))
!     vec_safe_push (MODIFIED_NORETURN_CALLS (cfun), stmt);
  
    gcc_assert (gimple_modified_p (stmt));
!   build_ssa_operands (stmt);
    gimple_set_modified (stmt, false);
  
    timevar_pop (TV_TREE_OPS);
--- 1103,1112 ----
       split_bbs_on_noreturn_calls during cfg cleanup.  */
    if (is_gimple_call (stmt)
        && gimple_call_noreturn_p (stmt))
!     vec_safe_push (MODIFIED_NORETURN_CALLS (fn), stmt);
  
    gcc_assert (gimple_modified_p (stmt));
!   build_ssa_operands (fn, stmt);
    gimple_set_modified (stmt, false);
  
    timevar_pop (TV_TREE_OPS);
*************** swap_ssa_operands (gimple stmt, tree *ex
*** 1117,1124 ****
    op0 = *exp0;
    op1 = *exp1;
  
-   gcc_checking_assert (ssa_operands_active (cfun));
- 
    if (op0 != op1)
      {
        /* Attempt to preserve the relative positions of these two operands in
--- 1123,1128 ----
Index: gcc/gimple-ssa.h
===================================================================
*** gcc/gimple-ssa.h.orig       2013-11-29 11:45:49.000000000 +0100
--- gcc/gimple-ssa.h    2013-11-29 13:10:18.087553532 +0100
*************** update_stmt (gimple s)
*** 141,147 ****
    if (gimple_has_ops (s))
      {
        gimple_set_modified (s, true);
!       update_stmt_operands (s);
      }
  }
  
--- 141,147 ----
    if (gimple_has_ops (s))
      {
        gimple_set_modified (s, true);
!       update_stmt_operands (cfun, s);
      }
  }
  
*************** static inline void
*** 151,157 ****
  update_stmt_if_modified (gimple s)
  {
    if (gimple_modified_p (s))
!     update_stmt_operands (s);
  }
  
  
--- 151,169 ----
  update_stmt_if_modified (gimple s)
  {
    if (gimple_modified_p (s))
!     update_stmt_operands (cfun, s);
! }
! 
! /* Mark statement S as modified, and update it.  */
! 
! static inline void
! update_stmt_fn (struct function *fn, gimple s)
! {
!   if (gimple_has_ops (s))
!     {
!       gimple_set_modified (s, true);
!       update_stmt_operands (fn, s);
!     }
  }
  
  
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c.orig   2013-11-29 11:45:49.000000000 +0100
--- gcc/cgraph.c        2013-11-29 13:10:18.087553532 +0100
*************** cgraph_redirect_edge_call_stmt_to_callee
*** 1468,1474 ****
      {
        new_stmt = e->call_stmt;
        gimple_call_set_fndecl (new_stmt, e->callee->decl);
!       update_stmt (new_stmt);
      }
  
    cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt, 
false);
--- 1468,1474 ----
      {
        new_stmt = e->call_stmt;
        gimple_call_set_fndecl (new_stmt, e->callee->decl);
!       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
      }
  
    cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt, 
false);
Index: gcc/testsuite/g++.dg/torture/pr59208.C
===================================================================
*** /dev/null   1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/torture/pr59208.C      2013-11-29 13:10:18.123553951 
+0100
***************
*** 0 ****
--- 1,26 ----
+ // { dg-do compile }
+ 
+ class A {
+ public:
+     A();
+     A(int *);
+ };
+ class B {};
+ class C : B {
+ public:
+     virtual void m_fn1();
+     void operator+=(int) { m_fn1(); }
+ };
+ enum DebuggerType {};
+ C a;
+ DebuggerType b;
+ void operator==(A &, const A &);
+ static A get_dbx_doc(A &p1) { p1 == 0; }
+ 
+ void add_button() {
+     A c;
+     switch (b)
+     case 0:
+       get_dbx_doc(c);
+       a += 0;
+ }
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig 2013-11-29 13:09:30.000000000 +0100
--- gcc/tree-cfg.c      2013-11-29 13:10:18.124553965 +0100
*************** move_block_to_fn (struct function *dest_
*** 6566,6572 ****
  
        /* We cannot leave any operands allocated from the operand caches of
         the current function.  */
!       free_stmt_operands (stmt);
        push_cfun (dest_cfun);
        update_stmt (stmt);
        pop_cfun ();
--- 6566,6572 ----
  
        /* We cannot leave any operands allocated from the operand caches of
         the current function.  */
!       free_stmt_operands (cfun, stmt);
        push_cfun (dest_cfun);
        update_stmt (stmt);
        pop_cfun ();
Index: gcc/tree-if-conv.c
===================================================================
*** gcc/tree-if-conv.c.orig     2013-11-29 11:45:49.000000000 +0100
--- gcc/tree-if-conv.c  2013-11-29 13:10:18.124553965 +0100
*************** free_bb_predicate (basic_block bb)
*** 212,218 ****
        gimple_stmt_iterator i;
  
        for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
!       free_stmt_operands (gsi_stmt (i));
      }
  
    free (bb->aux);
--- 212,218 ----
        gimple_stmt_iterator i;
  
        for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
!       free_stmt_operands (cfun, gsi_stmt (i));
      }
  
    free (bb->aux);
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c.orig 2013-11-29 11:45:49.000000000 +0100
--- gcc/tree-ssa.c      2013-11-29 13:10:18.124553965 +0100
*************** verify_ssa (bool check_modified_stmt)
*** 1049,1055 ****
              goto err;
            }
  
!         if (verify_ssa_operands (stmt))
            {
              print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
              goto err;
--- 1049,1055 ----
              goto err;
            }
  
!         if (verify_ssa_operands (cfun, stmt))
            {
              print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
              goto err;
*************** delete_tree_ssa (void)
*** 1202,1208 ****
  
    /* We no longer maintain the SSA operand cache at this point.  */
    if (ssa_operands_active (cfun))
!     fini_ssa_operands ();
  
    htab_delete (cfun->gimple_df->default_defs);
    cfun->gimple_df->default_defs = NULL;
--- 1202,1208 ----
  
    /* We no longer maintain the SSA operand cache at this point.  */
    if (ssa_operands_active (cfun))
!     fini_ssa_operands (cfun);
  
    htab_delete (cfun->gimple_df->default_defs);
    cfun->gimple_df->default_defs = NULL;
Index: gcc/gimple-pretty-print.c
===================================================================
*** gcc/gimple-pretty-print.c.orig      2013-11-25 10:44:30.000000000 +0100
--- gcc/gimple-pretty-print.c   2013-11-29 13:15:18.252039795 +0100
*************** dump_gimple_mem_ops (pretty_printer *buf
*** 2027,2036 ****
    tree vdef = gimple_vdef (gs);
    tree vuse = gimple_vuse (gs);
  
-   if (!ssa_operands_active (DECL_STRUCT_FUNCTION (current_function_decl))
-       || !gimple_references_memory_p (gs))
-     return;
- 
    if (vdef != NULL_TREE)
      {
        pp_string (buffer, "# ");
--- 2027,2032 ----
Index: gcc/tree-ssanames.c
===================================================================
*** gcc/tree-ssanames.c.orig    2013-11-29 09:40:27.000000000 +0100
--- gcc/tree-ssanames.c 2013-11-29 13:23:19.964630855 +0100
*************** get_nonzero_bits (const_tree name)
*** 301,307 ****
     other fields must be assumed clobbered.  */
  
  void
! release_ssa_name (tree var)
  {
    if (!var)
      return;
--- 301,307 ----
     other fields must be assumed clobbered.  */
  
  void
! release_ssa_name_fn (struct function *fn, tree var)
  {
    if (!var)
      return;
*************** release_ssa_name (tree var)
*** 341,347 ****
        while (imm->next != imm)
        delink_imm_use (imm->next);
  
!       (*SSANAMES (cfun))[SSA_NAME_VERSION (var)] = NULL_TREE;
        memset (var, 0, tree_size (var));
  
        imm->prev = imm;
--- 341,347 ----
        while (imm->next != imm)
        delink_imm_use (imm->next);
  
!       (*SSANAMES (fn))[SSA_NAME_VERSION (var)] = NULL_TREE;
        memset (var, 0, tree_size (var));
  
        imm->prev = imm;
*************** release_ssa_name (tree var)
*** 363,369 ****
        SSA_NAME_IN_FREE_LIST (var) = 1;
  
        /* And finally put it on the free list.  */
!       vec_safe_push (FREE_SSANAMES (cfun), var);
      }
  }
  
--- 363,369 ----
        SSA_NAME_IN_FREE_LIST (var) = 1;
  
        /* And finally put it on the free list.  */
!       vec_safe_push (FREE_SSANAMES (fn), var);
      }
  }
  
Index: gcc/tree-ssanames.h
===================================================================
*** gcc/tree-ssanames.h.orig    2013-11-29 09:40:27.000000000 +0100
--- gcc/tree-ssanames.h 2013-11-29 13:18:50.121499386 +0100
*************** extern void init_ssanames (struct functi
*** 81,87 ****
  extern void fini_ssanames (void);
  extern void ssanames_print_statistics (void);
  extern tree make_ssa_name_fn (struct function *, tree, gimple);
! extern void release_ssa_name (tree);
  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
                                    unsigned int *);
  extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
--- 81,87 ----
  extern void fini_ssanames (void);
  extern void ssanames_print_statistics (void);
  extern tree make_ssa_name_fn (struct function *, tree, gimple);
! extern void release_ssa_name_fn (struct function *, tree);
  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
                                    unsigned int *);
  extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
*************** duplicate_ssa_name (tree var, gimple stm
*** 127,132 ****
--- 127,140 ----
    return duplicate_ssa_name_fn (cfun, var, stmt);
  }
  
+ /* Release the SSA name NAME used in function cfun.  */
+ 
+ static inline void
+ release_ssa_name (tree name)
+ {
+   release_ssa_name_fn (cfun, name);
+ }
+ 
  /* Return an anonymous SSA_NAME node for type TYPE defined in statement STMT
     in function cfun.  Arrange so that it uses NAME in dumps.  */
  

Reply via email to