Dear mailing list:
I am writing GCC code that constructs GIMPLE (after pass_apply_inline
and before pass_all_optimizations) to take the address of each of a
function's parameters and store those addresses in an array. The code
is at the bottom of this message. Right now I need help in dealing
with errors of the form
--
test.c:10: error: invalid operand to unary operator
x_1(D)
--
where x_1(D) is an SSA_NAME for one of the variables I'm trying to
store (in this case, x). The errors appear at -O2. The complaint is
on a NOP_EXPR involving x; the backtrace is
--
#1 0x000000000087dbee in verify_expr (tp=0x2aaaab484208,
walk_subtrees=0x7fffb32ddf50, data=0x0) at /home/sean/fsl/aristotle/
src/modular-gcc/build-svn/../gcc-svn/gcc/tree-cfg.c:3284
#2 0x0000000000a7860c in walk_tree (tp=0x2aaaab484208, func=0x87cf15
<verify_expr>, data=0x0, pset=0x0) at /home/sean/fsl/aristotle/src/
modular-gcc/build-svn/../gcc-svn/gcc/tree.c:7978
#3 0x000000000087f415 in verify_stmt (stmt=0x2aaaab4841e0,
last_in_block=0 '\0') at /home/sean/fsl/aristotle/src/modular-gcc/
build-svn/../gcc-svn/gcc/tree-cfg.c:3407
#4 0x000000000087fbdc in verify_stmts () at /home/sean/fsl/aristotle/
src/modular-gcc/build-svn/../gcc-svn/gcc/tree-cfg.c:3615
#5 0x0000000000a0200b in verify_ssa (check_modified_stmt=1 '\001')
at /home/sean/fsl/aristotle/src/modular-gcc/build-svn/../gcc-svn/gcc/
tree-ssa.c:614
#6 0x00000000007a6860 in execute_function_todo (data=0x420) at /home/
sean/fsl/aristotle/src/modular-gcc/build-svn/../gcc-svn/gcc/passes.c:927
#7 0x00000000007a6315 in do_per_function (callback=0x7a65b2
<execute_function_todo>, data=0x420) at /home/sean/fsl/aristotle/src/
modular-gcc/build-svn/../gcc-svn/gcc/passes.c:770
#8 0x00000000007a68eb in execute_todo (flags=1056) at /home/sean/fsl/
aristotle/src/modular-gcc/build-svn/../gcc-svn/gcc/passes.c:948
#9 0x00000000007a6d6d in execute_one_pass (pass=0x12259a0) at /home/
sean/fsl/aristotle/src/modular-gcc/build-svn/../gcc-svn/gcc/passes.c:
1093
#10 0x00000000007a6dfa in execute_pass_list (pass=0x12259a0) at /home/
sean/fsl/aristotle/src/modular-gcc/build-svn/../gcc-svn/gcc/passes.c:
1123
#11 0x00000000008edc9c in tree_rest_of_compilation
(fndecl=0x2aaaab475a80) at /home/sean/fsl/aristotle/src/modular-gcc/
build-svn/../gcc-svn/gcc/tree-optimize.c:412
--
The relevant part of verify_expr is:
--
static tree
verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
tree t = *tp, x;
bool in_phi = (data != NULL);
if (TYPE_P (t))
*walk_subtrees = 0;
/* Check operand N for being valid GIMPLE and give error MSG if
not. */
#define CHECK_OP(N, MSG) \
do { if (!is_gimple_val (TREE_OPERAND (t, N))) \
{ error (MSG); return TREE_OPERAND (t, N); }} while (0)
switch (TREE_CODE (t))
{
/* snip */
case NOP_EXPR:
case CONVERT_EXPR:
case FIX_TRUNC_EXPR:
case FLOAT_EXPR:
case NEGATE_EXPR:
case ABS_EXPR:
case BIT_NOT_EXPR:
case NON_LVALUE_EXPR:
case TRUTH_NOT_EXPR:
CHECK_OP (0, "invalid operand to unary operator");
break;
--
Here's my code. I freely acknowledge that I may be doing this in a
very bad way; if you can point me toward a replacement for my hand-
rolled build_automatic, or show me the right way to make the array
addressable, or bang me on the head for not executing a fixing-up pass
before or after this code, all these comments are more than welcome.
--
// Returns an automatic variable of the given type.
tree build_automatic(
tree type, /* type of variable */
const char* name) /* name for variable */
{
tree ret = NULL;
ret = build_decl(VAR_DECL, get_identifier(name), type);
DECL_ARTIFICIAL(ret) = 1; /* declared by the compiler */
DECL_IGNORED_P(ret) = 1; /* no debug info */
TREE_READONLY(ret) = 0; /* writable */
DECL_EXTERNAL(ret) = 0; /* defined */
TREE_STATIC(ret) = 0; /* automatic */
TREE_USED(ret) = 1; /* used */
create_var_ann(ret);
return ret;
}
tree build_pointer_array(
tree* parms, /* array of PARAM_DECLs */
int num_parms, /* number of elements in parms */
block_stmt_iterator* iter) /* pointer to a location where I will
place the assignments to the array */
{
tree array_size = build_int_cst(size_type_node, num_parms);
tree array_index_type = build_index_type(array_size);
tree array_type = build_array_type(ptr_type_node,
array_index_type);
TREE_ADDRESSABLE(array_type) = 1;
tree pointer_array = build_automatic(array_type, "pointers");
for(unsigned int i = 0; i < variables->size(); i++)
{
tree index = build_int_cst(array_index_type, i);
tree min_value = TYPE_MIN_VALUE(array_index_type);
tree size_in_align = build_int_cst(size_type_node,
tree_low_cst(TYPE_SIZE(ptr_type_node), 0) / TYPE_ALIGN(ptr_type_node));
tree variable = (*variables)[i].decl;
TREE_ADDRESSABLE(variable) = 1;
tree address = build1(ADDR_EXPR,
build_pointer_type(TREE_TYPE(variable)), variable);
tree left_hand_side = build4(ARRAY_REF, ptr_type_node,
pointer_array, index, min_value, size_in_align);
tree assignment = build2(GIMPLE_MODIFY_STMT,
ptr_type_node, left_hand_side, address);
bsi_insert_before(iter, assignment, BSI_SAME_STMT);
}
return pointer_array;
}
--
Thanks very much for your time!
Sincerely,
Sean Callanan