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]

[tree-ssa] Aliasing fixes, take 3


Hi,
Per Jeff's request, I've re-tested my patches with i686-pc-linux-gnu, instead
of i386-linux.  This ineed makes clean tree to bootstrap.  Additionally I've
also bootstrapped i386-linux and x86-64-linux (without libjava).

The patch is unification of the reverted patch to tree-must-alias fixes and
patch to recompute TREE_ADDRESSABLE instead of relying on frontend to do that.
It is not possible to break this patch further as each bugfix triggers latent
bug fixed by other bugfix.

I do have many direct followups to this patch: re-enabling of tail recursion,
verify_stmts, removal of TREE_ADDRESSABLE code from front-ends, removal of
ADDRESSOF construct, small improvements to aliasing, more proper handling of
matching constraints in asm operands.  So I really hope this time everything
will go right.

Head of changelog of tree I tested patch on is:

2003-11-21  Diego Novillo  <dnovillo@redhat.com>

	* Makefile.in (tree-dfa.o): Add dependency on $(TREE_DUMP_H)
	* tree-dfa.c: Include tree-dump.h
	(compute_alias_sets): Call dump_function_to_file.
	(may_access_global_mem_p): Check if the base address of _REF nodes
	may point to global memory.

And the comparsion of testsuites gives:
- FAIL: gcc.c-torture/execute/20010403-1.c execution,  -O3 -fomit-frame-pointer
- FAIL: gcc.c-torture/execute/20010403-1.c execution,  -O3 -g
- FAIL: gcc.dg/format/ext-3.c bad %_0 (test for warnings, line 213)
- FAIL: gcc.dg/format/ext-3.c bad %^# (test for warnings, line 215)

So two of long standing failures fewer.
Honza

2003-11-22  Jan Hubicka  <jh@suse.cz>

	* tree-dfa.c (walk_state): Add force_addressable field.
	(add_referenced_var):  Add new argument in_addr_expr_p; recompute TREE_ADDRESSABLE.
	(find_referenced_vars): Update call.
	(find_vars_r): Likewise.
	(add_referenced_tmp_var): Likewise.
	(get_expr_operands): FIx handling of i386.
	* tree-must-alias.c (tree_compute_must_alias): Promote pointers.
	(find_addressable_vars):  Deal with complex references.
	(promote_var): Do not clear may_point_to_global_mem
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.187
diff -c -3 -p -r1.1.4.187 tree-dfa.c
*** tree-dfa.c	21 Nov 2003 23:17:17 -0000	1.1.4.187
--- tree-dfa.c	22 Nov 2003 13:03:41 -0000
*************** struct walk_state
*** 89,94 ****
--- 89,97 ----
    /* Nonzero if the walker is inside an ASM_EXPR node.  */
    int is_asm_expr : 1;
  
+   /* Nonzero if the walker should force all references to be addressable.  */
+   int force_addressable : 1;
+ 
    /* Nonzero if the walker is inside a non-GIMPLE expression.  */
    int is_not_gimple : 1;
  
*************** static void add_call_read_ops (tree, vop
*** 134,140 ****
  static void add_stmt_operand (tree *, tree, int, voperands_t);
  static void add_immediate_use (tree, tree);
  static tree find_vars_r (tree *, int *, void *);
! static void add_referenced_var (tree, struct walk_state *);
  static tree get_memory_tag_for (tree);
  static void compute_immediate_uses_for_phi (tree, bool (*)(tree));
  static void compute_immediate_uses_for_stmt (tree, int, bool (*)(tree));
--- 137,143 ----
  static void add_stmt_operand (tree *, tree, int, voperands_t);
  static void add_immediate_use (tree, tree);
  static tree find_vars_r (tree *, int *, void *);
! static void add_referenced_var (tree, struct walk_state *, bool);
  static tree get_memory_tag_for (tree);
  static void compute_immediate_uses_for_phi (tree, bool (*)(tree));
  static void compute_immediate_uses_for_stmt (tree, int, bool (*)(tree));
*************** find_referenced_vars (tree fndecl)
*** 1982,1988 ****
      if (walk_state.num_calls * num_call_clobbered_vars < n_calls * n_clobbers)
        global_var = NULL_TREE;
      else if (global_var)
!       add_referenced_var (global_var, &walk_state);
    }
  
    htab_delete (vars_found);
--- 1985,1991 ----
      if (walk_state.num_calls * num_call_clobbered_vars < n_calls * n_clobbers)
        global_var = NULL_TREE;
      else if (global_var)
!       add_referenced_var (global_var, &walk_state, true);
    }
  
    htab_delete (vars_found);
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2480,2490 ****
  
        return t;
      }
    else if (TREE_CODE (t) == ASM_EXPR)
      {
        walk_state->is_asm_expr = 1;
        walk_state->is_store = 1;
!       walk_tree (&ASM_OUTPUTS (t), find_vars_r, walk_state, NULL);
        walk_tree (&ASM_CLOBBERS (t), find_vars_r, walk_state, NULL);
        walk_state->is_store = 0;
        walk_tree (&ASM_INPUTS (t), find_vars_r, walk_state, NULL);
--- 2483,2529 ----
  
        return t;
      }
+   else if (TREE_CODE (t) == ADDR_EXPR)
+     {
+       t = TREE_OPERAND (t, 0);
+       if (TREE_CODE (t) == ARRAY_REF
+ 	  || TREE_CODE (t) == COMPONENT_REF
+ 	  || TREE_CODE (t) == REALPART_EXPR
+ 	  || TREE_CODE (t) == IMAGPART_EXPR)
+ 	t = TREE_OPERAND (t, 0);
+       if (SSA_VAR_P (t))
+ 	{
+ 	  add_referenced_var (t, walk_state, true);
+ 	}
+       return NULL_TREE;
+     }
    else if (TREE_CODE (t) == ASM_EXPR)
      {
+       int noutputs = list_length (ASM_OUTPUTS (t));
+       const char **oconstraints
+ 	= (const char **) alloca ((noutputs) * sizeof (const char *));
+       int i;
+       tree link;
+       const char *constraint;
+       bool allows_mem, allows_reg, is_inout;
+ 
        walk_state->is_asm_expr = 1;
        walk_state->is_store = 1;
!       for (i=0, link = ASM_OUTPUTS (t); link;
! 	   ++i, link = TREE_CHAIN (link))
! 	{
! 	  oconstraints[i] = constraint
! 	    = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
! 	  parse_output_constraint (&constraint, i, 0, 0,
! 				   &allows_mem, &allows_reg, &is_inout);
! 	  if (allows_reg && is_inout)
! 	    /* This should have been split in gimplify_asm_expr.  */
! 	    abort ();
! 	  if (!allows_reg && allows_mem)
! 	    walk_state->force_addressable = true;
! 	  walk_tree (&TREE_VALUE (link), find_vars_r, walk_state, NULL);
! 	  walk_state->force_addressable = false;
! 	}
        walk_tree (&ASM_CLOBBERS (t), find_vars_r, walk_state, NULL);
        walk_state->is_store = 0;
        walk_tree (&ASM_INPUTS (t), find_vars_r, walk_state, NULL);
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2507,2513 ****
  
    if (SSA_VAR_P (t))
      {
!       add_referenced_var (t, walk_state);
        return NULL_TREE;
      }
  
--- 2546,2552 ----
  
    if (SSA_VAR_P (t))
      {
!       add_referenced_var (t, walk_state, walk_state->force_addressable);
        return NULL_TREE;
      }
  
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2528,2534 ****
  	      && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (arg))))
  	    {
  	      walk_state->is_indirect_ref = 1;
! 	      add_referenced_var (arg, walk_state);
  	      walk_state->is_indirect_ref = 0;
  	    }
  	}
--- 2567,2573 ----
  	      && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (arg))))
  	    {
  	      walk_state->is_indirect_ref = 1;
! 	      add_referenced_var (arg, walk_state, false);
  	      walk_state->is_indirect_ref = 0;
  	    }
  	}
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2554,2560 ****
     assumes that VAR is a valid SSA variable.  */
  
  static void
! add_referenced_var (tree var, struct walk_state *walk_state)
  {
    void **slot;
    var_ann_t v_ann;
--- 2593,2599 ----
     assumes that VAR is a valid SSA variable.  */
  
  static void
! add_referenced_var (tree var, struct walk_state *walk_state, bool in_addr_expr_p)
  {
    void **slot;
    var_ann_t v_ann;
*************** add_referenced_var (tree var, struct wal
*** 2578,2583 ****
--- 2617,2628 ----
        v_ann->uid = num_referenced_vars;
        VARRAY_PUSH_TREE (referenced_vars, var);
  
+       /* FIXME: For aggregates we must keep addresable bit set to keep front-end happy.
+          Honza will track this next!  */
+       if (!AGGREGATE_TYPE_P (TREE_TYPE (var))
+           && decl_function_context (var) == current_function_decl)
+ 	TREE_ADDRESSABLE (var) = 0;
+ 
        /* Arguments or global variable pointers may point to memory outside
  	 the current function.  */
        if (POINTER_TYPE_P (TREE_TYPE (var))
*************** add_referenced_var (tree var, struct wal
*** 2624,2629 ****
--- 2669,2701 ----
        if (DECL_NONLOCAL (var))
  	set_is_used (var);
      }
+   if (in_addr_expr_p && !TREE_ADDRESSABLE (var)
+       && decl_function_context (var) == current_function_decl)
+     {
+       struct alias_map_d *alias_map;
+ 
+       /* In our simplistics view taking address makes variable call clobbered.  */
+       if (!is_gimple_call_clobbered (var))
+ 	{
+ 	  add_call_clobbered_var (var);
+ 	  v_ann->is_call_clobbered = 1;
+ 	  if (POINTER_TYPE_P (TREE_TYPE (var)))
+ 	    v_ann->may_point_to_global_mem = 1;
+ 	}
+       TREE_ADDRESSABLE (var) = 1;
+       /* Verify that we are still stupid this way.  */
+       if (!is_gimple_call_clobbered (var))
+ 	abort ();
+       /* Create a new alias set entry for VAR.  */
+       alias_map = ggc_alloc (sizeof (*alias_map));
+       alias_map->var = var;
+ 
+       if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ 	alias_map->set = get_alias_set (TREE_TYPE (TREE_TYPE (var)));
+       else
+ 	alias_map->set = get_alias_set (var);
+       VARRAY_PUSH_GENERIC_PTR (addressable_vars, alias_map);
+     }
  
    /* Now, set attributes that depend on WALK_STATE.  */
    if (walk_state == NULL)
*************** add_referenced_var (tree var, struct wal
*** 2670,2676 ****
  	 the memory tag that depend on WALK_STATE (e.g., whether this
  	 variable is being stored-to).  */
        walk_state->is_indirect_ref = 0;
!       add_referenced_var (tag, walk_state);
  
        /* If pointer VAR may point to global mem, then TAG may alias
  	 global memory.  */
--- 2742,2748 ----
  	 the memory tag that depend on WALK_STATE (e.g., whether this
  	 variable is being stored-to).  */
        walk_state->is_indirect_ref = 0;
!       add_referenced_var (tag, walk_state, false);
  
        /* If pointer VAR may point to global mem, then TAG may alias
  	 global memory.  */
*************** create_global_var (void)
*** 2873,2879 ****
  void
  add_referenced_tmp_var (tree var)
  {
!   add_referenced_var (var, NULL);
  }
  
  /* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE.
--- 2945,2951 ----
  void
  add_referenced_tmp_var (tree var)
  {
!   add_referenced_var (var, NULL, false);
  }
  
  /* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE.
Index: tree-must-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-must-alias.c,v
retrieving revision 1.1.2.10
diff -c -3 -p -r1.1.2.10 tree-must-alias.c
*** tree-must-alias.c	21 Nov 2003 22:56:00 -0000	1.1.2.10
--- tree-must-alias.c	22 Nov 2003 13:03:42 -0000
*************** tree_compute_must_alias (tree fndecl, sb
*** 93,100 ****
        
        /* We are only interested in disambiguating addressable locals.  */
        if (TREE_ADDRESSABLE (var)
! 	  /* FIXME Why exactly do we need to ignore pointers and arrays?  */
! 	  && !POINTER_TYPE_P (TREE_TYPE (var))
  	  && TREE_CODE (TREE_TYPE (var)) != ARRAY_TYPE
  	  && decl_function_context (var) == current_function_decl
  	  && !DECL_NONLOCAL (var)
--- 93,99 ----
        
        /* We are only interested in disambiguating addressable locals.  */
        if (TREE_ADDRESSABLE (var)
! 	  /* FIXME Why exactly do we need to ignore arrays?  */
  	  && TREE_CODE (TREE_TYPE (var)) != ARRAY_TYPE
  	  && decl_function_context (var) == current_function_decl
  	  && !DECL_NONLOCAL (var)
*************** find_addressable_vars (sbitmap addresses
*** 172,180 ****
--- 171,190 ----
  	    {
  	      tree t = PHI_ARG_DEF (phi, i);
  
+ 	      if (TREE_CODE (t) == NOP_EXPR)
+ 		t = TREE_OPERAND (t, 0);
+ 
+ 	      if (TREE_CODE (t) == PLUS_EXPR)
+ 		t = TREE_OPERAND (t, 0);
+ 
  	      if (TREE_CODE (t) != ADDR_EXPR)
  		continue;
  	      t = TREE_OPERAND (t, 0);
+ 	      if (TREE_CODE (t) == ARRAY_REF
+ 		  || TREE_CODE (t) == COMPONENT_REF
+ 		  || TREE_CODE (t) == REALPART_EXPR
+ 		  || TREE_CODE (t) == IMAGPART_EXPR)
+ 		t = TREE_OPERAND (t, 0);
  	      if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
  		continue;
  	      SET_BIT (addresses_needed, var_ann (t)->uid);
*************** promote_var (tree var, sbitmap vars_to_r
*** 217,223 ****
    ann->may_aliases = NULL;
    ann->is_call_clobbered = 0;
    ann->may_alias_global_mem = 0;
-   ann->may_point_to_global_mem = 0;
  
    /* If the variable was an alias tag, remove it from every variable that
       had it in its may-alias set.  */
--- 227,232 ----


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