[llvm-dev] Function calls keep increasing the stack usage

palpar via llvm-dev llvm-dev at lists.llvm.org
Fri Sep 14 12:09:10 PDT 2018


Thanks for confirming that it seems to be a bug.
I was studying the code you mentioned and X86FastISel::fastLowerCall()
calls getRegForValue() for each argument. Then the second iteration over
the arguments (after it called CCInfo.AnalyzeCallOperands()) may decide to
call X86FastEmitStore() if not VA.isRegLoc() and ArgVal is a constant
(ignoring the register, but that was already marked used I guess by
getRegForValue).
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?view=markup
Could we maybe delay the call to getRegForValue() after the analyze so that
we don't call it when not needed?

On Fri, Sep 14, 2018 at 9:26 PM Reid Kleckner <rnk at google.com> wrote:

> I think this is a bug in fastisel. It sometimes generates unnecessary
> materializations like this. It's unclear why they end up getting spilled,
> though.
>
> On Fri, Sep 14, 2018 at 8:16 AM palpar via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> Hi everyone,
>>
>> I found that LLVM generates redundant code when calling functions with
>> constant parameters, with optimizations disabled.
>>
>> Consider the following C code snippet:
>>
>> int foo(int x, int y);
>>
>> void bar()
>> {
>> foo(1, 2);
>> foo(3, 4);
>> }
>>
>> Clang/LLVM 6.0 generates the following assembly code:
>> _bar:
>> subl $32, %esp
>> movl $1, %eax
>> movl $2, %ecx
>> movl $1, (%esp)
>> movl $2, 4(%esp)
>> movl %eax, 28(%esp)
>> movl %ecx, 24(%esp)
>> calll _foo
>> movl $3, %ecx
>> movl $4, %edx
>> movl $3, (%esp)
>> movl $4, 4(%esp)
>> movl %eax, 20(%esp)
>> movl %ecx, 16(%esp)
>> movl %edx, 12(%esp)
>> calll _foo
>> movl %eax, 8(%esp)
>> addl $32, %esp
>> retl
>>
>> Note how the constants are stored in registers but when saving the
>> parameters on the stack for the call the immediate values are used. The
>> registers are still stored on the stack probably because it's the caller's
>> responsibility once they were used (which seems expected).
>> I think the problem comes from the fact that LLVM unconditionally
>> allocates a register for each parameter value regardless if it's used later
>> or not.
>> If the stack space of the program is sufficiently large this is probably
>> not a problem, but otherwise if there is a large number of such calls,
>> despite not recursive, it can lead to stack overflow. Do you think I should
>> create a bug report for this?
>>
>> (Similarly, the return value of the function could be not saved but the
>> LLVM IR code that Clang generates has the call with assignment so at this
>> point LLVM couldn't possibly know.
>> define void @bar() #0 {
>>   %call = call i32 @foo(i32 1, i32 2)
>>   %call1 = call i32 @foo(i32 3, i32 4)
>>   ret void
>> }
>> )
>>
>> Thanks,
>> Alpar
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180914/1038d021/attachment.html>


More information about the llvm-dev mailing list