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]

Another missed DECL_INITIAL folding


Hi,
the following testcases shows problem with fold_const_aggregate_ref
producing non-gimple &global_trees[TI_VOID_TYPE] (taken from DECL_INITIAL)
and later failing it to use it as known constant. We eventually get the constant
value at cfgexpand time only.

I am not sure what is the proper way to fold this, so I ended up with using
maybe_fold_offset_to_address.  With removal of some code redundancy it is hopefully
not too bad.

Bootstrapped/regtested x86_64-linux, OK?
Honza

/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
typedef union tree_node *tree;
enum tree_code
{
  OFFSET_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, POINTER_TYPE, FIXED_POINT_TYPE,
};
struct tree_base
{
  unsigned public_flag:1;
};
struct tree_decl_with_vis
{
  unsigned comdat_flag:1;
};
union tree_node
{
  struct tree_base base;
  struct tree_decl_with_vis decl_with_vis;
};
enum tree_index
{
    TI_LONG_DOUBLE_PTR_TYPE, TI_INTEGER_PTR_TYPE, TI_VOID_TYPE, TI_PTR_TYPE,
    TI_VA_LIST_FPR_COUNTER_FIELD, TI_BOOLEAN_TYPE, TI_FILEPTR_TYPE,
    TI_CURRENT_TARGET_PRAGMA, TI_CURRENT_OPTIMIZE_PRAGMA, TI_MAX
};
extern tree global_trees[TI_MAX];
emit_support_tinfos (void)
{
  static tree *const fundamentals[] = {
    &global_trees[TI_VOID_TYPE], &global_trees[TI_BOOLEAN_TYPE],
  };
  int ix;
  for (ix = 0; fundamentals[ix]; ix++)
    {
	{
	  tree tinfo;
	    {
	      ((void) (!(((tinfo)->base.public_flag) && !(__extension__ (
									  {
									  __typeof
									  (tinfo)
									  __t
									  =
									  (tinfo);
									  __t;}
							  )->decl_with_vis.
							  comdat_flag)) ?
		       fancy_abort ("../../gcc/cp/rtti.c", 1529,
				    __FUNCTION__), 0 : 0));
	    }
	}
    }
}
/* We should copy loop header to fundamentals[0] and then fold it way into
   known value.  */
/* { dg-final { scan-tree-dump-times "fundamental.0" 1 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
	* gimple.h (canonicalize_consturctor_val): Declare.
	* gimple-fold.c (canonicalize_consturctor_val): New function.
	(get_symbol_constant_value):Use it.
	* tree-ssa-ccp.c (fold_const_aggregate_ref): Likewise.
Index: gimple.h
===================================================================
--- gimple.h	(revision 163808)
+++ gimple.h	(working copy)
@@ -4876,6 +4876,7 @@ tree maybe_fold_offset_to_address (locat
 tree maybe_fold_offset_to_reference (location_t, tree, tree, tree);
 tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
 tree get_symbol_constant_value (tree);
+tree canonicalize_consturctor_val (tree);
 bool may_propagate_address_into_dereference (tree, tree);
 extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, 
 					enum tree_code, tree, tree);
Index: gimple-fold.c
===================================================================
--- gimple-fold.c	(revision 163808)
+++ gimple-fold.c	(working copy)
@@ -31,6 +31,30 @@ along with GCC; see the file COPYING3.  
 #include "tree-ssa-propagate.h"
 #include "target.h"
 
+/* CVAL is value taken from DECL_INITIAL of variable.  Try to transorm it into
+   acceptable form for is_gimple_min_invariant.   */
+
+tree
+canonicalize_consturctor_val (tree cval)
+{
+  STRIP_NOPS (cval);
+  if (TREE_CODE (cval) == POINTER_PLUS_EXPR)
+    {
+      tree t = maybe_fold_offset_to_address (EXPR_LOCATION (cval),
+					     TREE_OPERAND (cval, 0),
+					     TREE_OPERAND (cval, 1),
+					     TREE_TYPE (cval));
+      if (t)
+	cval = t;
+    }
+  if (TREE_CODE (cval) == ADDR_EXPR)
+    {
+      tree base = get_base_address (TREE_OPERAND (cval, 0));
+      if (base && TREE_CODE (base) == VAR_DECL)
+	add_referenced_var (base);
+    }
+  return cval;
+}
 
 /* If SYM is a constant variable with known value, return the value.
    NULL_TREE is returned otherwise.  */
@@ -45,21 +69,9 @@ get_symbol_constant_value (tree sym)
       tree val = DECL_INITIAL (sym);
       if (val)
 	{
-	  STRIP_NOPS (val);
+	  val = canonicalize_consturctor_val (val);
 	  if (is_gimple_min_invariant (val))
-	    {
-	      if (TREE_CODE (val) == ADDR_EXPR)
-		{
-		  tree base = get_base_address (TREE_OPERAND (val, 0));
-		  if (base && TREE_CODE (base) == VAR_DECL)
-		    {
-		      TREE_ADDRESSABLE (base) = 1;
-		      if (gimple_referenced_vars (cfun))
-			add_referenced_var (base);
-		    }
-		}
-	      return val;
-	    }
+	    return val;
 	}
       /* Variables declared 'const' without an initializer
 	 have zero as the initializer if they may not be
Index: tree-ssa-ccp.c
===================================================================
--- tree-ssa-ccp.c	(revision 163808)
+++ tree-ssa-ccp.c	(working copy)
@@ -1413,16 +1417,7 @@ fold_const_aggregate_ref (tree t)
       /* Whoo-hoo!  I'll fold ya baby.  Yeah!  */
       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
 	if (tree_int_cst_equal (cfield, idx))
-	  {
-	    STRIP_NOPS (cval);
-	    if (TREE_CODE (cval) == ADDR_EXPR)
-	      {
-		tree base = get_base_address (TREE_OPERAND (cval, 0));
-		if (base && TREE_CODE (base) == VAR_DECL)
-		  add_referenced_var (base);
-	      }
-	    return cval;
-	  }
+	  return canonicalize_consturctor_val (cval);
       break;
 
     case COMPONENT_REF:
@@ -1463,16 +1458,7 @@ fold_const_aggregate_ref (tree t)
 	if (cfield == field
 	    /* FIXME: Handle bit-fields.  */
 	    && ! DECL_BIT_FIELD (cfield))
-	  {
-	    STRIP_NOPS (cval);
-	    if (TREE_CODE (cval) == ADDR_EXPR)
-	      {
-		tree base = get_base_address (TREE_OPERAND (cval, 0));
-		if (base && TREE_CODE (base) == VAR_DECL)
-		  add_referenced_var (base);
-	      }
-	    return cval;
-	  }
+	  return canonicalize_consturctor_val (cval);
       break;
 
     case REALPART_EXPR:
@@ -1567,13 +1553,7 @@ fold_const_aggregate_ref (tree t)
 	  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
 	    if (tree_int_cst_equal (cfield, idx))
 	      {
-		STRIP_NOPS (cval);
-		if (TREE_CODE (cval) == ADDR_EXPR)
-		  {
-		    tree base = get_base_address (TREE_OPERAND (cval, 0));
-		    if (base && TREE_CODE (base) == VAR_DECL)
-		      add_referenced_var (base);
-		  }
+		cval = canonicalize_consturctor_val (cval);
 		if (useless_type_conversion_p (TREE_TYPE (t), TREE_TYPE (cval)))
 		  return cval;
 		else if (CONSTANT_CLASS_P (cval))


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