This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Replacing certain operations with function calls


Actually, what I've done is probably something in between what you
were suggesting and what I was initially doing. If we consider the
multiplication, I've modified the define_expand for example to:

(define_expand "muldi3"
  [(set (match_operand:DI 0 "register_operand" "")
        (mult:DI (match_operand:DI 1 "register_operand" "")
                 (match_operand:DI 2 "register_operand" "")))]
 ""
 "
 {
        emit_function_call_2args (DImode, DImode, DImode,
\"my_version_of_mull\", operands[0], operands[1], operands[2]);
        DONE;
 }")

and my emit function is:

void
emit_function_call_2args (
                                enum machine_mode return_mode,
                                enum machine_mode arg1_mode,
                                enum machine_mode arg2_mode,
                                const char *fname,
                                rtx op0,
                                rtx op1,
                                rtx op2)
{
     tree id;
     rtx insn;

     /* Move arguments */
     emit_move_insn (gen_rtx_REG (arg1_mode, GP_ARG_FIRST), op1);
     emit_move_insn (gen_rtx_REG (arg2_mode, GP_ARG_FIRST + 1), op2);

     /* Get name */
     id = get_identifier (fname);

     /* Generate call value */
     insn = gen_call_value (
                        gen_rtx_REG (return_mode, 6),
                        gen_rtx_MEM (DImode,
                           gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (id))),
                        GEN_INT (64),
                        NULL
                        );

     /* Annotate the call to say we are using both argument registers */
     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG
(arg1_mode, GP_ARG_FIRST));
     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG
(arg1_mode, GP_ARG_FIRST + 1));

     /* Emit call */
     emit_call_insn (insn);

     /* Set back return to op0 */
     emit_move_insn (op0, gen_rtx_REG (return_mode, GP_RETURN));
}

First off: does this seem correct?

Second, I have a bit of a worry in the case where, if we consider this C code :

bar (a * b, c * d);

it is possible that the compiler would have normally generated this :

mult output1, a, b
mult output2, c, d
call bar

Which would be problematic for my expand system since this would expand into:

mov output1, a
mov output2, b
call internal_mult
mov output1, return_reg

mov output1, c   #Rewriting on output1...
mov output2, d
call internal_mult
mov output2, return_reg

call bar


However, I am unsure this is possible in the expand stage, would the
expand stage automatically have this instead:

mult tmp1, a, b
mult tmp2, c, d

mov output1, tmp1
mov output2, tmp2
call bar

in which case, I know I can do what I am currently doing.

Thanks again for your help and I apologize for these basic questions...
Jc


On Tue, Sep 1, 2009 at 2:30 PM, Jean Christophe
Beyler<jean.christophe.beyler@gmail.com> wrote:
> I have looked at how other targest use the
> init_builtins/expand_builtins. Of course, I don't understand
> everything there but it seems indeed to be more for generating a
> series of instructions instead of a function call. I haven't seen
> anything resembling what I want to do.
>
> I had also first thought of going directly in the define_expand and
> expanding to the function call I would want. The problem I have is
> that it is unclear to me how to handle (set-up) the arguments of the
> builtin_function I am trying to define.
>
> To go from no function call to :
>
> - Potentially spill output registers
> - Potentially spill scratch registers
>
> - Setup output registers with the operands
> - Perform function call
> - Copy return to output operand
>
> - Potentially restore scratch registers
> - Potentially restore output registers
>
> Seems a bit difficult to do at the define_expand level and might not
> generate good code. I guess I could potentially perform a pass in the
> tree representation to do what I am looking for but I am not sure that
> that is the best solution either.
>
> For the moment, I will continue looking at what you suggest and also
> see if my solution works. I see that, for example, the compiler will
> not always generate the call I need to change. Therefore, it does seem
> that I need another solution than the one I propose.
>
> I'm more and more considering a pass in the middle-end to get what I
> need. Do you think this is better?
>
> Thanks for your input,
> Jc
>
> On Tue, Sep 1, 2009 at 12:34 PM, Ian Lance Taylor<iant@google.com> wrote:
>> Jean Christophe Beyler <jean.christophe.beyler@gmail.com> writes:
>>
>>> I have been also been looking into how to generate a function call for
>>> certain operations. I've looked at various other targets for a similar
>>> problem/solution but have not seen anything. On my target
>>> architecture, we have certain optimized versions of the multiplication
>>> for example.
>>>
>>> I wanted to replace certain mutliplications with a function call. The
>>> solution I found was to do perform a FAIL on the define_expand of the
>>> multiplication for these cases. This forces the compiler to generate a
>>> function call to __multdi3.
>>>
>>> I then go in the define_expand of the function call and check the
>>> symbol_ref to see what function is called. I can then modify the call
>>> at that point.
>>>
>>> My question is: is this a good approach or is there another solution
>>> that you would use?
>>
>> I think that what you describe will work. ?I would probably generate a
>> call to a builtin function in the define_expand. ?Look for the way
>> targets use init_builtins and expand_builtin. ?Normally expand_builtin
>> expands to some target-specific RTL, but it can expand to a function
>> call too.
>>
>> Ian
>>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]