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]

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


On 4/7/07, Jan Hubicka <hubicka@ucw.cz> wrote:
> > On 4/6/07, Jan Hubicka <jh@suse.cz> wrote:
> > >Hi,
> > >this patch teach fold_unary to convert (type *)&A into
> > >&A->field_of_type_and_offset_0. These constructs are common in C++
> > >inheritance
> > >and the strange cast is a stopper for various further optimizations.
> > >The transformation matches couple hounderd times compiling Gerald's
> > >testcase,
> > >but also on GCC bootstrap (in parser, genattrtab and other places)
> > >Bootstrapped/regtested i686-linux, OK?
> >
> > I think tree-ssa-ccp.c:maybe_fold_offset_to_component_ref has
> > some "interesting" side-cases and does not require memory allocation
> > but passes back component_refs, that looks better in my view.
>
> Hmm, maybe_fold_offset_to_component_ref should've probably matched the
> case I was looking into, but it didn't because it tries to recurse only
> on the first field overlapping with offset specified, so on union and
> offset of 0, it will goto found at first field of sufficient size and
> won't look into rest of union. At least if I am reading the code right.

Hi,
actually the reason seems to be as simple as the fact that the function
is never called, since it is considered only to fold away INDIRECT_REFs
of something.  The folding is useful for bare ADDR_EXPRs too, so this
patch adds the call.

I've also added calls with nonzero offset, since the functionally is
readilly available. It would be nice if we can fold away this way a
multiple inheritance, that does not work (just in artifical testcase I
get match).  This is because we would need to combine the two gimple
statements, that probably forward propagation can be told about. I
guess it is best to proceed incrementally. (Ie I would still like to try
to avoid unnecesary allocations and get the function working on unions
where fild field is not the match)

I am testing the patch on x86_64-linux, does it seem to make more sense
now?

Yes. As Andrew mentions, a few testcases would be nice. And...


        * tree.h (maybe_fold_offset_to_component_ref): Declare.
        * fold-const.c (fold_unary, fold_binary): 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 123515)
+++ tree.h      (working copy)
@@ -4412,6 +4412,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: fold-const.c
===================================================================
--- fold-const.c        (revision 123515)
+++ fold-const.c        (working copy)
@@ -7735,6 +7775,23 @@ fold_unary (enum tree_code code, tree ty
            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);
+
+      /* Convert (type *)&(A+offset) into &A->field_of_type_and_offset.  */
+      if (TREE_CODE (op0) == PLUS_EXPR
+         && TREE_CODE (TREE_OPERAND (op0, 0)) == ADDR_EXPR
+         && TREE_CODE (TREE_OPERAND (op0, 1)) == 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),
+                      TREE_OPERAND (op0, 1), TREE_TYPE (type), false)))
+        return build_fold_addr_expr_with_type (tem, type);

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'.

       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?


Richard.

        }
       else
        {
Index: tree-ssa-ccp.c
===================================================================
--- tree-ssa-ccp.c      (revision 123515)
+++ 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]