Thanks Ian, Richard.
I have some modified code which seems to be along the same lines as
what you all suggested.  However, I am still having troubles.  Mainly,
I see the array in the callee but the contents are still empty, and I
verified by looking at the asm dump of the resulting code.

On Fri, Feb 1, 2013 at 8:09 PM, Richard Biener
<richard.guent...@gmail.com> wrote:
> On Fri, Feb 1, 2013 at 5:03 AM, Matt Davis <mattdav...@gmail.com> wrote:
>> Hello,
>> I have a routine that creates a local array containing pointers to
>> global data.  At runtime, when this array is passed to a function, I
>> do not see the pointers to the global objects.  The GIMPLE does show
>> that the array is declared with the addresses of the globals as the
>> elements to the array, and that looks fine to me.  But at runtime,
>> when this array is passed to a callee function, the callee receives
>> the array, but its contents are not the addresses of the globals.
>>
>> After looking at the corresponding assembly, this makes sense, as I do
>> not see the assembly building the array before it passes the array to
>> the callee.  I do not see the asm code assigning the elements of the
>> array to be that of the global pointers.  I suppose there is a flag I
>> need to set? If not, I suppose I can always build the array as a
>> series of assignments.
>>
>> Here is how I build the local array.  Note, if I build this array as a
>> global with static-linkage, then everything works fine:
>>
>> tree create_array(const region_t reg, gimple stmt)
>> {
>>     unsigned i, n_elts;
>>     const type_info_t *ti;
>>     tree type, unique, decl;
>>     VEC(constructor_elt,gc) *entries = NULL;
>>
>>     n_elts = VEC_length(tree, reg->unique_types);
>>     type = build_array_type_nelts(ptr_type_node, n_elts);
>>
>>     FOR_EACH_VEC_ELT(tree, reg->unique_types, i, unique)
>>     {
>>         ti = get_type_info(reg, unique);
>>         CONSTRUCTOR_APPEND_ELT(
>>             entries, NULL, build1(ADDR_EXPR, ptr_type_node, ti->decl));
>>     }
>>
>>     decl = create_tmp_var(type, "testarray");
>>     DECL_INITIAL(decl) = build_constructor(type, entries);
>>
>>     return decl;
>> }
>>
>> Do I have to explicitly create assignment statements for each element,
>> since my array is local?  As I mention above, if I make my array
>> global, everything is fine.
>
> Locals with DECL_INITIAL need to be lowered in GIMPLE to make the
> initialization explicit.  What you can do is output the constructor as
> constant (supposed all elements are constant) using tree_output_constant_def.
> See how gimplification handles initializers of locals.

I did look through the gimplification stuff.  And I added a
"tree_output_constant_def" on my DECL_INITIAL as suggested by Richard.
As Ian suggested, I created a DECL_EXPR for this array that I am generating.

The new code is the following:

    /* Build the constructor for the array */
    FOR_EACH_VEC_ELT(tree, reg->unique_types, i, unique)
    {
        ti = get_type_info(reg, unique);
        CONSTRUCTOR_APPEND_ELT(
            entries, NULL, build1(ADDR_EXPR, ptr_type_node, ti->decl));
    }

    /* Create the VAR_DECL for the array, set the constructor and force it to
     * be generated at local scope.
     */
    decl = create_tmp_var(type, "testarray");
    DECL_INITIAL(decl) =
tree_output_constant_def(build_constructor(type, entries));
    return build1_loc(gimple_location(stmt), DECL_EXPR, type, decl);


I use the DECL_EXPR_DECL() of the returned value as I would have
normally used 'decl' in my previous listing.  Looking at the gimple
dump and assembly,  I see the gimple code now containing a pointer to
a label for the declaration (thanks to tree_output_constant_def).  In
the resulting asm, I do not see this label anywhere.

-Matt

Reply via email to