This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
addressability checks in the gimplifier
- From: Olivier Hainque <hainque at adacore dot com>
- To: gcc at gcc dot gnu dot org
- Cc: hainque at adacore dot com
- Date: Fri, 2 Jun 2006 13:01:00 +0200
- Subject: addressability checks in the gimplifier
Hello,
First a short description of a problem we are seeing, then a couple
of related questions on addressability checks in the gimplifier.
>From a simple Ada testcase which I can provide if need be, the front-end
is producing a MODIFY_EXPR with a lhs of the following shape when we get
to gimplify_modify_expr:
<array_range_ref
type <array_type p5__process__T6b
size <var_decl D.632
arg 0 <component_ref
type <array_type p5__short_message__T4b
arg 0 <var_decl sm type <record_type
BLK
size <integer_cst constant invariant 40>
arg 1 <field_decl data type <array_type
external packed bit-field nonaddressable SI
align 1 offset_align 128
offset <integer_cst constant invariant 0>
bit offset <integer_cst constant invariant 1>
arg 1 <integer_cst 0x401d9048 constant invariant 1>
in short, a variable size array_range_ref within a bitfield record component.
The lhs remains of similar shape after gimplification, the rhs is of
variable size as well, and we end up at this point in gimplify_modify_expr:
/* 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);
if (TREE_CODE (from) == CONSTRUCTOR)
return gimplify_modify_expr_to_memset (expr_p, size, want_value);
if (is_gimple_addressable (from))
{
*from_p = from;
return gimplify_modify_expr_to_memcpy (expr_p, size, want_value);
}
}
We get down into gimplify_modify_expr_to_memcpy, which builds ADDR_EXPRs
for both operands, which ICEs later on from expand_expr_addr_expr_1 because
the operand sketched above is not byte-aligned.
The first puzzle to me is that there is no check made that the target
is a valid argument for an ADDR_EXPR. AFAICS, it has been gimplified
with is_gimple_lvalue/fb_lvalue as the predicate/fallback pair, but
this currently doesn't imply the required properties.
I first thought that a is_gimple_addressable (*to_p) addition to the
outer condition would help, but it actually does not because the
predicate is shallow and only checks a very restricted set of
conditions (e.g. any ARRAY_RANGE_REF or COMPONENT_REF is considered
"addressable"). This is actually the reason why the gimplified lhs
tree is considered is_gimple_lvalue, from:
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);
Assuming that the initial tree is valid GENERIC, it would seem that a more
sophisticated addressability checker (recursing down some inner refs and
checking DECL_BIT_FIELD on field decls in COMPONENT_REFs) might be required.
I'm unclear whether this could/should be is_gimple_addressable, as
comments from http://gcc.gnu.org/ml/gcc/2004-07/msg01255.html indicate
that it not designed for this sort of operation.
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.
Thanks very much in advance for your help,
With Kind Regards,
Olivier