On Wed, Apr 22, 2015 at 1:45 AM, Steve Ellcey wrote:
> I have a question about inserting code into a function being compiled by
> GCC. Basically I want to set a hard register at the beginning of a
> function like is being done below. If I compile the program below on MIPS
> the $16 register gets set to the result of alloca and even if I optimize
> the routine and nothing else uses p ($16), the set of $16 gets done.
>
> register void *p asm ("$16");
> void *foo(void *a)
> {
> p = alloca(64);
> /* Rest of function. */
> }
>
> But if I try to insert this code myself from inside GCC the setting of $16
> keeps getting optimized away and I cannot figure out how to stop it.
> My code to set the register does this:
>
> ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
> get_identifier ("__alloca_reg"), ptr_type);
> TREE_PUBLIC (ptr_var) = 1;
> DECL_EXTERNAL (ptr_var) = 1;
> SET_DECL_RTL (ptr_var, gen_raw_REG (Pmode, 16));
> DECL_REGISTER (ptr_var) = 1;
> DECL_HARD_REGISTER (ptr_var) = 1;
> TREE_THIS_VOLATILE (ptr_var) = 1;
> TREE_USED (ptr_var) = 1;
> varpool_node::finalize_decl (ptr_var);
This is wrong for sure. You can't have DECL_RTL in GIMPLE.
You will want to set has_local_explicit_reg_vars, DECL_HARD_REGISTER,
and DECL_ASSEMBLER_NAME, and leave it to the middle end to take care
of everything else.
Ciao!
Steven