(I'm copying this thread back to the main GCC list, to
document the problem that we ran into, RG's suggestion
and the fix that we made.)

While merging our GCC/UPC implementation with
the GCC trunk, we ran into a situation where
some tests failed on the check shown below in
verify_gimple_assign_single().  This failed because
our representation of a UPC pointer-to-shared has an
internal struct representation but in other respects
is a pointer type (and appears to be register type).

For some temps that UPC creates, they have to be
marked as addressable, which causes them to no longer
qualify as is_gimple_reg(), but the type still asserts
is_gimple_reg_type().

The trees that were being created failed on this test:

      if (!is_gimple_reg (lhs)
          && is_gimple_reg_type (TREE_TYPE (lhs)))
        {
          error ("invalid rhs for gimple memory store");
          debug_generic_stmt (lhs);
          debug_generic_stmt (rhs1);
          return true;
        }

At first, I wondered if the checks above might be overly
inclusive?

On 01/11/10 11:03:46, Richard Guenther wrote:
> You need a temporary for register type but non-register copy.  Thus
> it needs to be
> 
>   tmp_2 = A;
>   B = tmp_2;
> 
> with tmp_2 being an SSA name, not
> 
>   B = A;

Looking at some of the code in gimplify.c, we determined
that calling prepare_gimple_addressable() is all that is needed:

       if (!is_gimple_addressable (src)
           || is_gimple_non_addressable (src))
         {
           /* We can't address the object - we have to copy
              to a local (non-shared) temporary.  */
-          src = get_initialized_tmp_var (src, pre_p, NULL);
+          prepare_gimple_addressable (&src, pre_p);
           mark_addressable (src);
           is_shared_copy = 0;
           is_src_shared = 0;
         }
     }

To make this work, prepare_gimple_addressable() needed to be changed
so that it is exported from gimplify.c:

-static void
+void
 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
 {
   while (handled_component_p (*expr_p))
     expr_p = &TREE_OPERAND (*expr_p, 0);
   if (is_gimple_reg (*expr_p))
     *expr_p = get_initialized_tmp_var (*expr_p, seq_p, NULL);
 }

With this fix in place, we were able pass the various checks
in tree-cfg.c, and to generate the expected code.

Reply via email to