This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][RFC] Kill per-stmt addresses_taken bitmap


This patch removes the addresses_taken bitmap which is only used by
ipa-reference and the update_address_taken pass.  Its representation
is notoriously inefficent (it uses a bitmap for usually storing a
single bit).  The per-stmt bitmap is replaced by a per-stmt walk
via the new walk_stmt_load_store_addr_ops walker.

A quick check shows this saves 0.5% memory for tramp3d.

Re-bootstrap / regtest still running.

Comments?

Thanks,
Richard.

2009-04-08  Richard Guenther  <rguenther@suse.de>

	* gimple.c (gimple_copy): Do not clear addresses_taken bitmap.
	(gimple_ior_addresses_taken_1): New function.
	(gimple_ior_addresses_taken): Likewise.
	* gimple.h (struct gimple_statement_with_ops_base): Remove
	addresses_taken member.
	(gimple_ior_addresses_taken): Declare.
	(gimple_addresses_taken, gimple_addresses_taken_ptr,
	gimple_set_addresses_taken): Remove.
	* ipa-reference.c (mark_address): New function.
	(scan_stmt_for_static_refs): Use it for marking addresses taken.
	* tree-ssa-operands.c (add_to_addressable_set): Rename to ...
	(mark_address_taken): ... this.  Just set TREE_ADDRESSABLE.
	(gimple_add_to_addresses_taken): Remove.
	(get_tmr_operands): Call mark_address_taken.
	(get_asm_expr_operands): Likewise.
	(get_expr_operands): Likewise.
	(build_ssa_operands): Do not clear the addresses_taken bitmap.
	(free_stmt_operands): Do not free it.
	* tree-ssa.c (delete_tree_ssa): Likewise.
	(execute_update_addresses_taken): Use gimple_ior_addresses_taken.

Index: trunk/gcc/gimple.c
===================================================================
*** trunk.orig/gcc/gimple.c	2009-04-07 16:32:19.000000000 +0200
--- trunk/gcc/gimple.c	2009-04-07 16:32:20.000000000 +0200
*************** gimple_copy (gimple stmt)
*** 2195,2210 ****
        for (i = 0; i < num_ops; i++)
  	gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
  
!       /* Clear out SSA operand vectors on COPY.  Note that we cannot
! 	 call the API functions for setting addresses_taken, stores
! 	 and loads.  These functions free the previous values, and we
! 	 cannot do that on COPY as it will affect the original
! 	 statement.  */
        if (gimple_has_ops (stmt))
  	{
  	  gimple_set_def_ops (copy, NULL);
  	  gimple_set_use_ops (copy, NULL);
- 	  copy->gsops.opbase.addresses_taken = NULL;
  	}
  
        if (gimple_has_mem_ops (stmt))
--- 2195,2205 ----
        for (i = 0; i < num_ops; i++)
  	gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
  
!       /* Clear out SSA operand vectors on COPY.  */
        if (gimple_has_ops (stmt))
  	{
  	  gimple_set_def_ops (copy, NULL);
  	  gimple_set_use_ops (copy, NULL);
  	}
  
        if (gimple_has_mem_ops (stmt))
*************** walk_stmt_load_store_addr_ops (gimple st
*** 3379,3382 ****
--- 3374,3406 ----
    return ret;
  }
  
+ 
+ /* Helper for gimple_ior_addresses_taken_1.  */
+ 
+ static bool
+ gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED,
+ 			      tree addr, void *data)
+ {
+   bitmap addresses_taken = (bitmap)data;
+   while (handled_component_p (addr))
+     addr = TREE_OPERAND (addr, 0);
+   if (DECL_P (addr))
+     {
+       bitmap_set_bit (addresses_taken, DECL_UID (addr));
+       return true;
+     }
+   return false;
+ }
+ 
+ /* Set the bit for the uid of all decls that have their address taken
+    in STMT in the ADDRESSES_TAKEN bitmap.  Returns true if there
+    were any in this stmt.  */
+ 
+ bool
+ gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt)
+ {
+   return walk_stmt_load_store_addr_ops (stmt, addresses_taken, NULL, NULL,
+ 					gimple_ior_addresses_taken_1);
+ }
+ 
  #include "gt-gimple.h"
Index: trunk/gcc/gimple.h
===================================================================
*** trunk.orig/gcc/gimple.h	2009-04-07 16:32:19.000000000 +0200
--- trunk/gcc/gimple.h	2009-04-07 16:32:20.000000000 +0200
*************** struct gimple_statement_base GTY(())
*** 327,341 ****
  
  struct gimple_statement_with_ops_base GTY(())
  {
!   /* [ WORD  1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]
!      Symbols whose addresses are taken by this statement (i.e., they
!      appear inside ADDR_EXPR nodes).  */
!   bitmap GTY((skip (""))) addresses_taken;
! 
!   /* [ WORD 6-7 ]
       SSA operand vectors.  NOTE: It should be possible to
       amalgamate these vectors with the operand vector OP.  However,
       the SSA operand vectors are organized differently and contain
--- 327,336 ----
  
  struct gimple_statement_with_ops_base GTY(())
  {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5-6 ]
       SSA operand vectors.  NOTE: It should be possible to
       amalgamate these vectors with the operand vector OP.  However,
       the SSA operand vectors are organized differently and contain
*************** struct gimple_statement_with_ops_base GT
*** 349,358 ****
  
  struct gimple_statement_with_ops GTY(())
  {
!   /* [ WORD 1-7 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 8 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
--- 344,353 ----
  
  struct gimple_statement_with_ops GTY(())
  {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 7 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
*************** struct gimple_statement_with_ops GTY(())
*** 364,373 ****
  
  struct gimple_statement_with_memory_ops_base GTY(())
  {
!   /* [ WORD 1-7 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 8-9 ]
       Virtual operands for this statement.  The GC will pick them
       up via the ssa_names array.  */
    tree GTY((skip (""))) vdef;
--- 359,368 ----
  
  struct gimple_statement_with_memory_ops_base GTY(())
  {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 7-8 ]
       Virtual operands for this statement.  The GC will pick them
       up via the ssa_names array.  */
    tree GTY((skip (""))) vdef;
*************** struct gimple_statement_with_memory_ops_
*** 379,388 ****
  
  struct gimple_statement_with_memory_ops GTY(())
  {
!   /* [ WORD 1-9 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 10 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
--- 374,383 ----
  
  struct gimple_statement_with_memory_ops GTY(())
  {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 9 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
*************** struct gimple_statement_wce GTY(())
*** 545,564 ****
  
  struct gimple_statement_asm GTY(())
  {
!   /* [ WORD 1-9 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 10 ]
       __asm__ statement.  */
    const char *string;
  
!   /* [ WORD 11 ]
         Number of inputs, outputs and clobbers.  */
    unsigned char ni;
    unsigned char no;
    unsigned short nc;
  
!   /* [ WORD 12 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
--- 540,559 ----
  
  struct gimple_statement_asm GTY(())
  {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 9 ]
       __asm__ statement.  */
    const char *string;
  
!   /* [ WORD 10 ]
         Number of inputs, outputs and clobbers.  */
    unsigned char ni;
    unsigned char no;
    unsigned short nc;
  
!   /* [ WORD 11 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
*************** extern bool walk_stmt_load_store_addr_op
*** 913,918 ****
--- 908,914 ----
  					   bool (*)(gimple, tree, void *),
  					   bool (*)(gimple, tree, void *),
  					   bool (*)(gimple, tree, void *));
+ bool gimple_ior_addresses_taken (bitmap, gimple);
  
  /* In gimplify.c  */
  extern tree create_tmp_var_raw (tree, const char *);
*************** gimple_has_mem_ops (const_gimple g)
*** 1239,1279 ****
    return gimple_code (g) >= GIMPLE_ASSIGN && gimple_code (g) <= GIMPLE_RETURN;
  }
  
- /* Return the set of addresses taken by statement G.  */
- 
- static inline bitmap
- gimple_addresses_taken (const_gimple g)
- {
-   if (gimple_has_ops (g))
-     return g->gsops.opbase.addresses_taken;
-   else
-     return NULL;
- }
- 
- 
- /* Return a pointer to the set of addresses taken by statement G.  */
- 
- static inline bitmap *
- gimple_addresses_taken_ptr (gimple g)
- {
-   if (gimple_has_ops (g))
-     return &g->gsops.opbase.addresses_taken;
-   else
-     return NULL;
- }
- 
- 
- /* Set B to be the set of addresses taken by statement G.  The
-    previous set is freed.  */
- 
- static inline void
- gimple_set_addresses_taken (gimple g, bitmap b)
- {
-   gcc_assert (gimple_has_ops (g));
-   BITMAP_FREE (g->gsops.opbase.addresses_taken);
-   g->gsops.opbase.addresses_taken = b;
- }
- 
  
  /* Return the set of DEF operands for statement G.  */
  
--- 1235,1240 ----
Index: trunk/gcc/ipa-reference.c
===================================================================
*** trunk.orig/gcc/ipa-reference.c	2009-04-07 16:32:19.000000000 +0200
--- trunk/gcc/ipa-reference.c	2009-04-07 16:32:20.000000000 +0200
*************** mark_address_taken (tree x)
*** 334,339 ****
--- 334,351 ----
      bitmap_set_bit (module_statics_escape, DECL_UID (x));
  }
  
+ /* Wrapper around mark_address_taken for the stmt walker.  */
+ 
+ static bool
+ mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
+ 	      void *data ATTRIBUTE_UNUSED)
+ {
+   while (handled_component_p (addr))
+     addr = TREE_OPERAND (addr, 0);
+   mark_address_taken (addr);
+   return false;
+ }
+ 
  /* Mark load of T.  */
  
  static bool
*************** scan_stmt_for_static_refs (gimple_stmt_i
*** 429,451 ****
  {
    gimple stmt = gsi_stmt (*gsip);
    ipa_reference_local_vars_info_t local = NULL;
-   unsigned int i;
-   bitmap_iterator bi;
  
    if (fn)
      local = get_reference_vars_info (fn)->local;
  
    /* Look for direct loads and stores.  */
!   walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store, NULL);
  
    if (is_gimple_call (stmt))
      check_call (local, stmt);
    else if (gimple_code (stmt) == GIMPLE_ASM)
      check_asm_memory_clobber (local, stmt);
- 
-   if (gimple_addresses_taken (stmt))
-     EXECUTE_IF_SET_IN_BITMAP (gimple_addresses_taken (stmt), 0, i, bi)
-       mark_address_taken (referenced_var_lookup (i));
    
    return NULL;
  }
--- 441,458 ----
  {
    gimple stmt = gsi_stmt (*gsip);
    ipa_reference_local_vars_info_t local = NULL;
  
    if (fn)
      local = get_reference_vars_info (fn)->local;
  
    /* Look for direct loads and stores.  */
!   walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
! 				 mark_address);
  
    if (is_gimple_call (stmt))
      check_call (local, stmt);
    else if (gimple_code (stmt) == GIMPLE_ASM)
      check_asm_memory_clobber (local, stmt);
    
    return NULL;
  }
Index: trunk/gcc/tree-ssa-operands.c
===================================================================
*** trunk.orig/gcc/tree-ssa-operands.c	2009-04-07 14:41:52.000000000 +0200
--- trunk/gcc/tree-ssa-operands.c	2009-04-07 16:32:20.000000000 +0200
*************** add_stmt_operand (tree *var_p, gimple st
*** 686,695 ****
      add_virtual_operand (stmt, flags);
  }
  
! /* Add the base address of REF to SET.  */
  
  static void
! add_to_addressable_set (tree ref, bitmap *set)
  {
    tree var;
  
--- 686,698 ----
      add_virtual_operand (stmt, flags);
  }
  
! /* Mark the base address of REF as having its address taken.
!    REF may be a single variable whose address has been taken or any
!    other valid GIMPLE memory reference (structure reference, array,
!    etc).  */
  
  static void
! mark_address_taken (tree ref)
  {
    tree var;
  
*************** add_to_addressable_set (tree ref, bitmap
*** 699,725 ****
       be referenced using pointer arithmetic.  See PR 21407 and the
       ensuing mailing list discussion.  */
    var = get_base_address (ref);
!   if (var && SSA_VAR_P (var))
!     {
!       if (*set == NULL)
! 	*set = BITMAP_ALLOC (&operands_bitmap_obstack);
! 
!       bitmap_set_bit (*set, DECL_UID (var));
!       TREE_ADDRESSABLE (var) = 1;
!     }
! }
! 
! /* Add the base address of REF to the set of addresses taken by STMT.
!    REF may be a single variable whose address has been taken or any
!    other valid GIMPLE memory reference (structure reference, array,
!    etc).  If the base address of REF is a decl that has sub-variables,
!    also add all of its sub-variables.  */
! 
! static void
! gimple_add_to_addresses_taken (gimple stmt, tree ref)
! {
!   gcc_assert (gimple_has_ops (stmt));
!   add_to_addressable_set (ref, gimple_addresses_taken_ptr (stmt));
  }
  
  
--- 702,709 ----
       be referenced using pointer arithmetic.  See PR 21407 and the
       ensuing mailing list discussion.  */
    var = get_base_address (ref);
!   if (var && DECL_P (var))
!     TREE_ADDRESSABLE (var) = 1;
  }
  
  
*************** get_tmr_operands (gimple stmt, tree expr
*** 763,769 ****
    get_expr_operands (stmt, &TMR_INDEX (expr), opf_use);
  
    if (TMR_SYMBOL (expr))
!     gimple_add_to_addresses_taken (stmt, TMR_SYMBOL (expr));
  
    add_virtual_operand (stmt, flags);
  }
--- 747,753 ----
    get_expr_operands (stmt, &TMR_INDEX (expr), opf_use);
  
    if (TMR_SYMBOL (expr))
!     mark_address_taken (TMR_SYMBOL (expr));
  
    add_virtual_operand (stmt, flags);
  }
*************** get_asm_expr_operands (gimple stmt)
*** 824,830 ****
  	{
  	  tree t = get_base_address (TREE_VALUE (link));
  	  if (t && DECL_P (t))
! 	    gimple_add_to_addresses_taken (stmt, t);
  	}
  
        get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
--- 808,814 ----
  	{
  	  tree t = get_base_address (TREE_VALUE (link));
  	  if (t && DECL_P (t))
! 	    mark_address_taken (t);
  	}
  
        get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
*************** get_asm_expr_operands (gimple stmt)
*** 844,850 ****
  	{
  	  tree t = get_base_address (TREE_VALUE (link));
  	  if (t && DECL_P (t))
! 	    gimple_add_to_addresses_taken (stmt, t);
  	}
  
        get_expr_operands (stmt, &TREE_VALUE (link), 0);
--- 828,834 ----
  	{
  	  tree t = get_base_address (TREE_VALUE (link));
  	  if (t && DECL_P (t))
! 	    mark_address_taken (t);
  	}
  
        get_expr_operands (stmt, &TREE_VALUE (link), 0);
*************** get_expr_operands (gimple stmt, tree *ex
*** 887,893 ****
  	 reference to it, but the fact that the statement takes its
  	 address will be of interest to some passes (e.g. alias
  	 resolution).  */
!       gimple_add_to_addresses_taken (stmt, TREE_OPERAND (expr, 0));
  
        /* If the address is invariant, there may be no interesting
  	 variable references inside.  */
--- 871,877 ----
  	 reference to it, but the fact that the statement takes its
  	 address will be of interest to some passes (e.g. alias
  	 resolution).  */
!       mark_address_taken (TREE_OPERAND (expr, 0));
  
        /* If the address is invariant, there may be no interesting
  	 variable references inside.  */
*************** parse_ssa_operands (gimple stmt)
*** 1091,1104 ****
  static void
  build_ssa_operands (gimple stmt)
  {
!   /* Initially assume that the statement has no volatile operands and
!      makes no memory references.  */
    gimple_set_has_volatile_ops (stmt, false);
  
-   /* Just clear the bitmap so we don't end up reallocating it over and over.  */
-   if (gimple_addresses_taken (stmt))
-     bitmap_clear (gimple_addresses_taken (stmt));
- 
    start_ssa_stmt_operands ();
    parse_ssa_operands (stmt);
    finalize_ssa_stmt_operands (stmt);
--- 1075,1083 ----
  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);
*************** free_stmt_operands (gimple stmt)
*** 1133,1141 ****
        gimple_set_use_ops (stmt, NULL);
      }
  
-   if (gimple_has_ops (stmt))
-     gimple_set_addresses_taken (stmt, NULL);
- 
    if (gimple_has_mem_ops (stmt))
      {
        gimple_set_vuse (stmt, NULL_TREE);
--- 1112,1117 ----
Index: trunk/gcc/tree-ssa.c
===================================================================
*** trunk.orig/gcc/tree-ssa.c	2009-04-07 14:41:52.000000000 +0200
--- trunk/gcc/tree-ssa.c	2009-04-07 16:32:44.000000000 +0200
*************** delete_tree_ssa (void)
*** 834,840 ****
  	    {
  	      gimple_set_def_ops (stmt, NULL);
  	      gimple_set_use_ops (stmt, NULL);
- 	      gimple_set_addresses_taken (stmt, NULL);
  	    }
  
  	  if (gimple_has_mem_ops (stmt))
--- 834,839 ----
*************** execute_update_addresses_taken (bool do_
*** 1504,1516 ****
      {
        for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
  	{
! 	  const_gimple stmt = gsi_stmt (gsi);
  	  enum gimple_code code = gimple_code (stmt);
! 	  bitmap taken = gimple_addresses_taken (stmt);
! 	  
! 	  if (taken)
! 	    bitmap_ior_into (addresses_taken, taken);
! 	  
  	  /* If we have a call or an assignment, see if the lhs contains
  	     a local decl that requires not to be a gimple register.  */
  	  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
--- 1503,1514 ----
      {
        for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
  	{
! 	  gimple stmt = gsi_stmt (gsi);
  	  enum gimple_code code = gimple_code (stmt);
! 
! 	  /* Note all addresses taken by the stmt.  */
! 	  gimple_ior_addresses_taken (addresses_taken, stmt);
! 
  	  /* If we have a call or an assignment, see if the lhs contains
  	     a local decl that requires not to be a gimple register.  */
  	  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]