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: Allow generate_element_init in tree-sra.c to fail


I fixed a few buglets and committed this version.


r~



        * tree-sra.c (struct sra_walk_fns): Revert 2004-07-05 change.
        (sra_walk_modify_expr, scan_init): Likewise.
        (generate_element_zero): Check visited before scanning children.
        (generate_element_init): Set visited on error.
        (scalarize_init): Handle generate_element_init failure similar
        to use_block_copy.

Index: tree-sra.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-sra.c,v
retrieving revision 2.16
diff -c -p -d -r2.16 tree-sra.c
*** tree-sra.c	5 Jul 2004 16:14:51 -0000	2.16
--- tree-sra.c	6 Jul 2004 22:57:11 -0000
*************** struct sra_walk_fns
*** 569,577 ****
  		block_stmt_iterator *bsi);
  
    /* Invoked when ELT is initialized from a constant.  VALUE may be NULL,
!      in which case it should be treated as an empty CONSTRUCTOR.  Return
!      false if we found a case we couldn't handle.  */
!   bool (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
  
    /* Invoked when we have a copy between one scalarizable reference ELT
       and one non-scalarizable reference OTHER.  IS_OUTPUT is true if ELT
--- 569,576 ----
  		block_stmt_iterator *bsi);
  
    /* Invoked when ELT is initialized from a constant.  VALUE may be NULL,
!      in which case it should be treated as an empty CONSTRUCTOR.  */
!   void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
  
    /* Invoked when we have a copy between one scalarizable reference ELT
       and one non-scalarizable reference OTHER.  IS_OUTPUT is true if ELT
*************** sra_walk_modify_expr (tree expr, block_s
*** 770,790 ****
      {
        /* If this is an assignment from a constant, or constructor, then
  	 we have access to all of the elements individually.  Invoke INIT.  */
!       if ((TREE_CODE (rhs) == COMPLEX_EXPR
! 	   || TREE_CODE (rhs) == COMPLEX_CST
! 	   || TREE_CODE (rhs) == CONSTRUCTOR)
! 	  && fns->init (lhs_elt, rhs, bsi))
! 	;
  
        /* If this is an assignment from read-only memory, treat this as if
  	 we'd been passed the constructor directly.  Invoke INIT.  */
        else if (TREE_CODE (rhs) == VAR_DECL
  	       && TREE_STATIC (rhs)
  	       && TREE_READONLY (rhs)
! 	       && targetm.binds_local_p (rhs)
! 	       && DECL_INITIAL (rhs)
! 	       && fns->init (lhs_elt, DECL_INITIAL (rhs), bsi))
! 	;
  
        /* If this is a copy from a non-scalarizable lvalue, invoke LDST.
  	 The lvalue requirement prevents us from trying to directly scalarize
--- 769,786 ----
      {
        /* If this is an assignment from a constant, or constructor, then
  	 we have access to all of the elements individually.  Invoke INIT.  */
!       if (TREE_CODE (rhs) == COMPLEX_EXPR
! 	  || TREE_CODE (rhs) == COMPLEX_CST
! 	  || TREE_CODE (rhs) == CONSTRUCTOR)
! 	fns->init (lhs_elt, rhs, bsi);
  
        /* If this is an assignment from read-only memory, treat this as if
  	 we'd been passed the constructor directly.  Invoke INIT.  */
        else if (TREE_CODE (rhs) == VAR_DECL
  	       && TREE_STATIC (rhs)
  	       && TREE_READONLY (rhs)
! 	       && targetm.binds_local_p (rhs))
! 	fns->init (lhs_elt, DECL_INITIAL (rhs), bsi);
  
        /* If this is a copy from a non-scalarizable lvalue, invoke LDST.
  	 The lvalue requirement prevents us from trying to directly scalarize
*************** scan_copy (struct sra_elt *lhs_elt, stru
*** 934,945 ****
    rhs_elt->n_copies += 1;
  }
  
! static bool
  scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
  	   block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
  {
    lhs_elt->n_copies += 1;
-   return true;
  }
  
  static void
--- 930,940 ----
    rhs_elt->n_copies += 1;
  }
  
! static void
  scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
  	   block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
  {
    lhs_elt->n_copies += 1;
  }
  
  static void
*************** generate_element_zero (struct sra_elt *e
*** 1490,1501 ****
  {
    struct sra_elt *c;
  
    for (c = elt->children; c ; c = c->sibling)
      generate_element_zero (c, list_p);
  
!   if (elt->visited)
!     elt->visited = false;
!   else if (elt->replacement)
      {
        tree t;
  
--- 1485,1500 ----
  {
    struct sra_elt *c;
  
+   if (elt->visited)
+     {
+       elt->visited = false;
+       return;
+     }
+ 
    for (c = elt->children; c ; c = c->sibling)
      generate_element_zero (c, list_p);
  
!   if (elt->replacement)
      {
        tree t;
  
*************** generate_element_init (struct sra_elt *e
*** 1567,1572 ****
--- 1566,1572 ----
        break;
  
      default:
+       elt->visited = true;
        result = false;
      }
  
*************** scalarize_copy (struct sra_elt *lhs_elt,
*** 1760,1768 ****
  /* Scalarize an INIT.  To recap, this is an assignment to a scalarizable
     reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or
     COMPLEX_EXPR.  If RHS is NULL, it should be treated as an empty
!    CONSTRUCTOR.  Return false if we didn't handle this case.  */
  
! static bool
  scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
  {
    bool result = true;
--- 1760,1768 ----
  /* Scalarize an INIT.  To recap, this is an assignment to a scalarizable
     reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or
     COMPLEX_EXPR.  If RHS is NULL, it should be treated as an empty
!    CONSTRUCTOR.  */
  
! static void
  scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
  {
    bool result = true;
*************** scalarize_init (struct sra_elt *lhs_elt,
*** 1776,1803 ****
       a zero value.  Initialize the rest of the instantiated elements.  */
    generate_element_zero (lhs_elt, &list);
  
!   /* If we didn't generate anything or couldn't handle this case return.
!      Say which it was.  */
!   if (!result || list == NULL)
!     return result;
  
!   if (lhs_elt->use_block_copy)
      {
        /* Since LHS is not fully instantiated, we must leave the structure
  	 assignment in place.  Treating this case differently from a USE
  	 exposes constants to later optimizations.  */
!       mark_all_v_defs (expr_first (list));
!       sra_insert_after (bsi, list);
      }
    else
      {
        /* The LHS is fully instantiated.  The list of initializations
  	 replaces the original structure assignment.  */
        mark_all_v_defs (bsi_stmt (*bsi));
        sra_replace (bsi, list);
      }
- 
-   return true;
  }
  
  /* A subroutine of scalarize_ldst called via walk_tree.  Set TREE_NO_TRAP
--- 1776,1816 ----
       a zero value.  Initialize the rest of the instantiated elements.  */
    generate_element_zero (lhs_elt, &list);
  
!   if (!result)
!     {
!       /* If we failed to convert the entire initializer, then we must
! 	 leave the structure assignment in place and must load values
! 	 from the structure into the slots for which we did not find
! 	 constants.  The easiest way to do this is to generate a complete
! 	 copy-out, and then follow that with the constant assignments
! 	 that we were able to build.  DCE will clean things up.  */
!       tree list0 = NULL;
!       generate_copy_inout (lhs_elt, true, generate_element_ref (lhs_elt),
! 			   &list0);
!       append_to_statement_list (list, &list0);
!       list = list0;
!     }
  
!   if (lhs_elt->use_block_copy || !result)
      {
        /* Since LHS is not fully instantiated, we must leave the structure
  	 assignment in place.  Treating this case differently from a USE
  	 exposes constants to later optimizations.  */
!       if (list)
! 	{
! 	  mark_all_v_defs (expr_first (list));
! 	  sra_insert_after (bsi, list);
! 	}
      }
    else
      {
        /* The LHS is fully instantiated.  The list of initializations
  	 replaces the original structure assignment.  */
+       if (!list)
+ 	abort ();
        mark_all_v_defs (bsi_stmt (*bsi));
        sra_replace (bsi, list);
      }
  }
  
  /* A subroutine of scalarize_ldst called via walk_tree.  Set TREE_NO_TRAP


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