Convert (type *)&A into &A->field_of_type_and_offset_0.

Jan Hubicka jh@suse.cz
Sun Apr 8 12:14:00 GMT 2007


> 
> Yes.  As Andrew mentions, a few testcases would be nice.  And...
Sure, I had two in testing but wanted to wait for full regression runs.
It is:

/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-optimized" } */
struct a{
	int a;
	int b;
} a;
int *
t()
{
	return (int *)&a;
}
/* { dg-final { scan-tree-dump "a.a" "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */


/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-optimized" } */
struct a{
	char a;
	int b;
} a;
int *
t()
{
	return (((int *)&a)+1);
}
/* { dg-final { scan-tree-dump "a.b" "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

It also shows one problem - with "int a" instead of "char a" in the
second testcase we and up with "a.a+4" since the first folder match
first.  Pretty weird, but it should not happen in the case of multiple
inheritance we are interested in since the individual fields should have
different types, right?

We probably could add folding for this (ie decode a.a into offset again,
and call function appropriately) if it seems worthwhile.  I guess it is
just weird side case.
> 
> especially for this one - does this really happen?  I guess the comment 
> should
> read (type *)(&A + offset) and here I would expect we fold it right to the 
> case
> below, (type *)&A + offset'.

Yes, it should be (type *)(&A + offset).
All three variants happens during the bootstrap.
I don't see folder that would be responsible for the conversion you
suggest above, but it definitly makes sense as canonicalization.

> 
> >       if ((TREE_CODE (op0) == MODIFY_EXPR
> >           || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
> >          && TREE_CONSTANT (GENERIC_TREE_OPERAND (op0, 1))
> >@@ -9227,6 +9284,15 @@ fold_binary (enum tree_code code, tree t
> >              if (tem)
> >                return fold_convert (type, tem);
> >            }
> >+          /* Convert ((type *)&A)+offset into 
> >&A->field_of_type_and_offset.  */
> >+         if (TREE_CODE (op0) == NOP_EXPR
> >+             && TREE_CODE (TREE_OPERAND (op0, 0)) == ADDR_EXPR
> >+             && TREE_CODE (op1) == INTEGER_CST
> >+             && (tem = maybe_fold_offset_to_component_ref
> >+                         (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (op0, 0), 
> >0)),
> >+                          TREE_OPERAND (TREE_OPERAND (op0, 0), 0),
> >+                          op1, TREE_TYPE (type), false)))
> >+           return build_fold_addr_expr_with_type (tem, type);
> 
> Do we handle &A + offset (without the cast) somewhere already in fold?

We don't, OK, since we just cummulated another at least 3 ideas for
folding, I am sending the easy part first (that deals only with first
testcase) and will do other three incrementally.

Thanks,
Honza

	* tree.h (maybe_fold_offset_to_component_ref): Declare.
	* fold-const.c (fold_unary): Fold NOPs of ADDR_EXPR
	into COMPONENT_REFs.
	* tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Export.
Index: tree.h
===================================================================
--- tree.h	(revision 123639)
+++ tree.h	(working copy)
@@ -4413,6 +4413,8 @@ extern void fold_defer_overflow_warnings
 extern void fold_undefer_overflow_warnings (bool, tree, int);
 extern void fold_undefer_and_ignore_overflow_warnings (void);
 extern bool fold_deferring_overflow_warnings_p (void);
+extern tree maybe_fold_offset_to_component_ref (tree, tree, tree,
+				                tree, bool);
 
 extern tree force_fit_type_double (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT,
 				   int, bool);
Index: tree-ssa-ccp.c
===================================================================
--- tree-ssa-ccp.c	(revision 123639)
+++ tree-ssa-ccp.c	(working copy)
@@ -1643,7 +1643,7 @@ maybe_fold_offset_to_array_ref (tree bas
    is the desired result type.  */
 /* ??? This doesn't handle class inheritance.  */
 
-static tree
+tree
 maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
 				    tree orig_type, bool base_is_ptr)
 {
Index: fold-const.c
===================================================================
*** fold-const.c	(revision 123639)
--- fold-const.c	(working copy)
*************** fold_view_convert_expr (tree type, tree 
*************** fold_unary (enum tree_code code, tree ty
*** 7735,7740 ****
--- 7775,7787 ----
  	    return fold_convert (type, build_fold_addr_expr (base));
          }
  
+       /* Convert (type *)&A into &A->field_of_type_and_offset_0.  */
+       if (TREE_CODE (op0) == ADDR_EXPR && POINTER_TYPE_P (type)
+ 	  && (tem = maybe_fold_offset_to_component_ref
+ 		      (TREE_TYPE (TREE_OPERAND (op0, 0)), TREE_OPERAND (op0, 0),
+ 		       integer_zero_node, TREE_TYPE (type), false)))
+         return build_fold_addr_expr_with_type (tem, type);
+ 
        if ((TREE_CODE (op0) == MODIFY_EXPR
  	   || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
  	  && TREE_CONSTANT (GENERIC_TREE_OPERAND (op0, 1))



More information about the Gcc-patches mailing list