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] PR32901: handle assignment from constructors better


Hi folks.

The problem in the PR is that a constructor with multiple bitfield
constants gets put into static storage, instead of being calculated at
compile time.

	struct foo {
	        unsigned a1: 1;
	        unsigned a2: 3;
	        unsigned : 4;
	};

	extern struct foo thefoo;

	void setup_foo(void) {
	        const struct foo init = {
			.a1 = 1,
                	.a2 = 5,
        	};
        	thefoo = init;
	}

In the snippet above, we put the constant 11 in static storage, then
initialize "thefoo", by reading from memory.

In my fix below, when initializing a variable from a const variable that
was initialized from a constant constructor, we pull the constant
constructor to the RHS of the assignment.  In the above example, we will
end up with:

	thefoo.0 = {};
	thefoo.0.a1 = 1;
	thefoo.0.a2 = 5;

Which unfortunately, will pass pretty much unmodified through the tree
optimizations, but combine saves the day and calculates the 11 constant
and make the replacement.

As Jakub points out in the PR, we should ideally (also) have a tree pass
that optimizes consecutive constant stores into aggregates, by
calculating the constant-- but we don't.

This patch fixes the problem in the PR.

Bootstrapped finished.  Tests are almost done.

OK pending tests?

	* gimplify.c (gimplify_modify_expr_rhs): Handle the case when we
	are assigning from a constant constructor.
	Fix wrapping in function comment.

Index: gimplify.c
===================================================================
--- gimplify.c	(revision 130773)
+++ gimplify.c	(working copy)
@@ -3470,8 +3470,9 @@ fold_indirect_ref_rhs (tree t)
   return NULL_TREE;
 }
 
-/* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs
-   based on the code of the RHS.  We loop for as long as something changes.  */
+/* Subroutine of gimplify_modify_expr to do simplifications of
+   MODIFY_EXPRs based on the code of the RHS.  We loop for as long as
+   something changes.  */
 
 static enum gimplify_status
 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
@@ -3482,6 +3483,19 @@ gimplify_modify_expr_rhs (tree *expr_p, 
   while (ret != GS_UNHANDLED)
     switch (TREE_CODE (*from_p))
       {
+      case VAR_DECL:
+	/* If we're assigning from a constant constructor, move the
+	   constructor expression to the RHS of the MODIFY_EXPR.
+	*/
+	if (DECL_INITIAL (*from_p)
+	    && TYPE_READONLY (TREE_TYPE (*from_p))
+	    && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
+	  {
+	    *from_p = DECL_INITIAL (*from_p);
+	    ret = GS_OK;
+	  }
+	ret = GS_UNHANDLED;
+	break;
       case INDIRECT_REF:
 	{
 	  /* If we have code like 


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