Hoisting built-in call out of loop - LIM pass [tree-ssa-loop-im.c]

Richard Biener richard.guenther@gmail.com
Thu Jun 2 08:26:11 GMT 2022


On Wed, Jun 1, 2022 at 3:59 PM Shubham Narlawar via Gcc <gcc@gcc.gnu.org> wrote:
>
> Hello,
>
> [1] I want to achieve hosting of a custom built-in call out of loop that
> loads an immediate value.
>
>     for (int i = 0; i < 4000; i++) {
>        _9 = (unsigned int) _1;
>        slli_6 = _9 << 8;
>        srli_36 = slli_6 >> 8;
>        li_37 = __builtin_load_immediate (15);        //I want to hoist this
> out of loop which will cause hoisting of add_39 stmt also
>        add_39 = srli_36 + li_37;
>        _10 = __builtin_foo (add_39, 1, _9);
>     }
>
> First 5 instructions in the above loop are being inserted by a custom
> gimple plugin whenever it sees a __builtin_foo().
>
> LICM pass () could hoist below instructions out of loop -
>
>        _9 = (unsigned int) _1;
>        slli_6 = _9 << 8;
>        srli_36 = slli_6 >> 8;
>
> I want to hoist below gimple statement out of loop
>
> li_22 = __builtin_riscv_load_immediate(15);      //BUILTIN_MD
>
> I am generating above builtin call using a custom GCC gimple plugin using -
>
>               tree li_tmp_name = make_temp_ssa_name (integer_type_node,
> NULL, "li");
>               tree load = build_int_cst (unsigned_type_node, 15);
>
>               gcall *li_stmt = gimple_build_call (decl,
> 1);                          //where decl is function_decl
>               gimple_call_set_lhs (li_stmt, li_tmp_name);
>               gimple_call_set_arg (li_stmt, 0, load);
>               gsi_insert_after (&gsi, li_stmt, GSI_NEW_STMT);
>
> How do I make a GIMPLE function call as const such that loop invariant code
> motion hoist it out of the loop.
>
> [2] I tried below approaches to make it happen -
>
> a. I made load_immediate decl as constant but that did not help
> TREE_CONSTANT(decl) = 1
>
> b. I teached licm pass to forcefull move out __builtin_load_immediate() by
> introducing various checks but in the end, it alters function cfg and some
> other pass like ""tree-ssa-loop-manip.c"" crashes here -
>
>           /* We should have met DEF_BB along the way.  */
>           gcc_assert (pred != ENTRY_BLOCK_PTR_FOR_FN (cfun));
>
> From above approaches, making changes in licm pass is proving to be costly
> and inappropriate. Is there any other way I can achieve it? I am guessing
> making it a constant gimple function call with no side effects will be
> hoisted automatically by LICM.
>
> If yes, how can I make a gimple call as constant so that it is hoisted out
> by LICM. Also, please suggest any other approaches to achieve it.

Where you generate the function declaration for the target builtin make sure
to mark it as 'const', which can be done by setting TREE_READONLY on
the function declaration to 1 (see
gcc/c-family/c-attribs.cc:handle_const_attribute).

That should do the trick but will also expose the builtin to the subject
of CSE and DCE (but I guess that's OK).

Richard.

> Thanks and Regards,
> Shubham


More information about the Gcc mailing list