Hello,

As a followup to my previous message enquiring about the intent
underlying various addressability checks in the gimplifier, attached
is an example of patch which addresses the issues we're observing.

It for instance fixes an ICE in in expand_expr_addr_expr_1 on the
testcase below:

   procedure P5 is

      type Long_Message is record
         Data : String (1 .. 16);
      end record;

      type Short_Message is record
         B : Boolean;
         Data : String (1 .. 4);
      end record;
      pragma Pack (Short_Message);

      procedure Process (LM : Long_Message; Size : Natural) is
         SM : Short_Message;
      begin
         SM.Data (1 .. Size) := LM.Data (1 .. Size);
      end;

   begin
      null;
   end;

which is the one producing the tree excerpt quoted in the previous
message (for SM.Data (1 .. Size) in Process).

The patch bootstraps fine with languages="all,ada" on i686-pc-linux-gnu,
and introduces no new regression.

Regarding gimple predicates typically not recursing down trees (in
accordance with the grammar), as I said

<< I'm pretty sure I'm missing implicit assumptions and/or bits of design
   intents in various places, so would appreciate input on the case and
   puzzles described above.
>>
 
So this patch is posted here primarily for discussion purposes.  I'd
welcome suggestions on better ways to address this, if the approach is
indeed considered inappropriate.

Thanks in advance for your help,

With Kind Regards,

Olivier








2006-06-19  Olivier Hainque  <[EMAIL PROTECTED]>

        * tree-gimple.c (is_gimple_lvalue, is_gimple_addressable): Account for
        possibly nested bitfield component refs, not addressable while still
        valid lvalues.

*** tree-gimple.c.ori   Tue May 30 15:55:07 2006
--- tree-gimple.c       Mon Jun 19 16:50:38 2006
*************** rhs_predicate_for (tree lhs)
*** 139,149 ****
  bool
  is_gimple_lvalue (tree t)
  {
!   return (is_gimple_addressable (t)
!         || TREE_CODE (t) == WITH_SIZE_EXPR
!         /* These are complex lvalues, but don't have addresses, so they
!            go here.  */
!         || TREE_CODE (t) == BIT_FIELD_REF);
  }
  
  /*  Return true if T is a GIMPLE condition.  */
--- 139,148 ----
  bool
  is_gimple_lvalue (tree t)
  {
!   return (TREE_CODE (t) == WITH_SIZE_EXPR
!         || INDIRECT_REF_P (t)
!         || handled_component_p (t)
!         || is_gimple_variable (t));
  }
  
  /*  Return true if T is a GIMPLE condition.  */
*************** is_gimple_condexpr (tree t)
*** 159,166 ****
  bool
  is_gimple_addressable (tree t)
  {
!   return (is_gimple_id (t) || handled_component_p (t)
!         || INDIRECT_REF_P (t));
  }
  
  /* Return true if T is function invariant.  Or rather a restricted
--- 158,181 ----
  bool
  is_gimple_addressable (tree t)
  {
!   if (is_gimple_id (t) || INDIRECT_REF_P (t))
!     return true;
! 
!   switch (TREE_CODE (t))
!     {
!     case COMPONENT_REF:
!       return
!       !DECL_BIT_FIELD (TREE_OPERAND (t, 1))
!       && is_gimple_addressable (TREE_OPERAND (t, 0));
! 
!     case VIEW_CONVERT_EXPR:
!     case ARRAY_REF:       case ARRAY_RANGE_REF:
!     case REALPART_EXPR:   case IMAGPART_EXPR:
!       return is_gimple_addressable (TREE_OPERAND (t, 0));
! 
!     default:
!       return false;
!     }
  }
  
  /* Return true if T is function invariant.  Or rather a restricted
*** gimplify.c.ori      Tue May 30 15:54:59 2006
--- gimplify.c  Mon Jun 19 16:55:00 2006
*************** gimplify_modify_expr (tree *expr_p, tree
*** 3422,3430 ****
      return ret;
  
    /* If we've got a variable sized assignment between two lvalues (i.e. does
!      not involve a call), then we can make things a bit more straightforward
!      by converting the assignment to memcpy or memset.  */
!   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
      {
        tree from = TREE_OPERAND (*from_p, 0);
        tree size = TREE_OPERAND (*from_p, 1);
--- 3422,3431 ----
      return ret;
  
    /* If we've got a variable sized assignment between two lvalues (i.e. does
!      not involve a call), we can make things a bit more straightforward by
!      converting the assignment to memcpy or memset as soon as both operands
!      can have their address taken.  */
!   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR && is_gimple_addressable (*to_p))
      {
        tree from = TREE_OPERAND (*from_p, 0);
        tree size = TREE_OPERAND (*from_p, 1);

Reply via email to