palpar via llvm-dev
2018-Sep-14 18:57 UTC
[llvm-dev] Function calls keep increasing the stack usage
Sorry I missed that important detail. The relevant part of the command line is: -cc1 -S -triple i386-pc-win32 I don't expect it matters if it's for Windows or Linux in this case. On Fri, Sep 14, 2018 at 9:16 PM David Blaikie <dblaikie at gmail.com> wrote:> Can't say I've observed that behavior (though I'm just building from > top-of-tree rather than 6.0, compiling for x86-64 on linux), perhaps you > could provide more detail (what target are you compiling for - possibly > provide the -cc1 command line, etc). > > bar: # @bar > .cfi_startproc > # %bb.0: # %entry > pushq %rbp > .cfi_def_cfa_offset 16 > .cfi_offset %rbp, -16 > movq %rsp, %rbp > .cfi_def_cfa_register %rbp > subq $16, %rsp > movl $1, %edi > movl $2, %esi > callq foo > movl $3, %edi > movl $4, %esi > movl %eax, -4(%rbp) # 4-byte Spill > callq foo > movl %eax, -8(%rbp) # 4-byte Spill > addq $16, %rsp > popq %rbp > .cfi_def_cfa %rsp, 8 > retq > > > Or on 32-bit X86: > > bar: # @bar > .cfi_startproc > # %bb.0: # %entry > pushq %rbp > .cfi_def_cfa_offset 16 > .cfi_offset %rbp, -16 > movq %rsp, %rbp > .cfi_def_cfa_register %rbp > subq $16, %rsp > movl $1, %edi > movl $2, %esi > callq foo > movl $3, %edi > movl $4, %esi > movl %eax, -4(%rbp) # 4-byte Spill > callq foo > movl %eax, -8(%rbp) # 4-byte Spill > addq $16, %rsp > popq %rbp > .cfi_def_cfa %rsp, 8 > retq > > > 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/c11ad652/attachment.html>
David Blaikie via llvm-dev
2018-Sep-14 19:02 UTC
[llvm-dev] Function calls keep increasing the stack usage
Still not seeing it on ToT, so maybe it's been fixed? $ clang-tot -cc1 -S -triple i386-pc-win32 stack.c ... _bar: subl $16, %esp movl $1, (%esp) movl $2, 4(%esp) calll _foo movl $3, (%esp) movl $4, 4(%esp) movl %eax, 12(%esp) calll _foo movl %eax, 8(%esp) addl $16, %esp retl $ clang-tot --version clang version 8.0.0 (trunk 342200) (llvm/trunk 342202) Target: x86_64-unknown-linux-gnu Thread model: posix On Fri, Sep 14, 2018 at 11:57 AM palpar <palparni at gmail.com> wrote:> Sorry I missed that important detail. The relevant part of the command > line is: > -cc1 -S -triple i386-pc-win32 > I don't expect it matters if it's for Windows or Linux in this case. > > On Fri, Sep 14, 2018 at 9:16 PM David Blaikie <dblaikie at gmail.com> wrote: > >> Can't say I've observed that behavior (though I'm just building from >> top-of-tree rather than 6.0, compiling for x86-64 on linux), perhaps you >> could provide more detail (what target are you compiling for - possibly >> provide the -cc1 command line, etc). >> >> bar: # @bar >> .cfi_startproc >> # %bb.0: # %entry >> pushq %rbp >> .cfi_def_cfa_offset 16 >> .cfi_offset %rbp, -16 >> movq %rsp, %rbp >> .cfi_def_cfa_register %rbp >> subq $16, %rsp >> movl $1, %edi >> movl $2, %esi >> callq foo >> movl $3, %edi >> movl $4, %esi >> movl %eax, -4(%rbp) # 4-byte Spill >> callq foo >> movl %eax, -8(%rbp) # 4-byte Spill >> addq $16, %rsp >> popq %rbp >> .cfi_def_cfa %rsp, 8 >> retq >> >> >> Or on 32-bit X86: >> >> bar: # @bar >> .cfi_startproc >> # %bb.0: # %entry >> pushq %rbp >> .cfi_def_cfa_offset 16 >> .cfi_offset %rbp, -16 >> movq %rsp, %rbp >> .cfi_def_cfa_register %rbp >> subq $16, %rsp >> movl $1, %edi >> movl $2, %esi >> callq foo >> movl $3, %edi >> movl $4, %esi >> movl %eax, -4(%rbp) # 4-byte Spill >> callq foo >> movl %eax, -8(%rbp) # 4-byte Spill >> addq $16, %rsp >> popq %rbp >> .cfi_def_cfa %rsp, 8 >> retq >> >> >> 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/b8e72fbf/attachment.html>
palpar via llvm-dev
2018-Sep-14 19:20 UTC
[llvm-dev] Function calls keep increasing the stack usage
Thanks for checking, I suppose it may have been fixed then, I don't have the latest version to try it now. Curious what could have fixed it, because X86FastISel::fastLowerCall() still has the calls to getRegForValue() (or maybe that's not the problem). On Fri, Sep 14, 2018 at 10:02 PM David Blaikie <dblaikie at gmail.com> wrote:> Still not seeing it on ToT, so maybe it's been fixed? > > $ clang-tot -cc1 -S -triple i386-pc-win32 stack.c > ... > _bar: > subl $16, %esp > movl $1, (%esp) > movl $2, 4(%esp) > calll _foo > movl $3, (%esp) > movl $4, 4(%esp) > movl %eax, 12(%esp) > calll _foo > movl %eax, 8(%esp) > addl $16, %esp > retl > > $ clang-tot --version > clang version 8.0.0 (trunk 342200) (llvm/trunk 342202) > Target: x86_64-unknown-linux-gnu > Thread model: posix > > > > > On Fri, Sep 14, 2018 at 11:57 AM palpar <palparni at gmail.com> wrote: > >> Sorry I missed that important detail. The relevant part of the command >> line is: >> -cc1 -S -triple i386-pc-win32 >> I don't expect it matters if it's for Windows or Linux in this case. >> >> On Fri, Sep 14, 2018 at 9:16 PM David Blaikie <dblaikie at gmail.com> wrote: >> >>> Can't say I've observed that behavior (though I'm just building from >>> top-of-tree rather than 6.0, compiling for x86-64 on linux), perhaps you >>> could provide more detail (what target are you compiling for - possibly >>> provide the -cc1 command line, etc). >>> >>> bar: # @bar >>> .cfi_startproc >>> # %bb.0: # %entry >>> pushq %rbp >>> .cfi_def_cfa_offset 16 >>> .cfi_offset %rbp, -16 >>> movq %rsp, %rbp >>> .cfi_def_cfa_register %rbp >>> subq $16, %rsp >>> movl $1, %edi >>> movl $2, %esi >>> callq foo >>> movl $3, %edi >>> movl $4, %esi >>> movl %eax, -4(%rbp) # 4-byte Spill >>> callq foo >>> movl %eax, -8(%rbp) # 4-byte Spill >>> addq $16, %rsp >>> popq %rbp >>> .cfi_def_cfa %rsp, 8 >>> retq >>> >>> >>> Or on 32-bit X86: >>> >>> bar: # @bar >>> .cfi_startproc >>> # %bb.0: # %entry >>> pushq %rbp >>> .cfi_def_cfa_offset 16 >>> .cfi_offset %rbp, -16 >>> movq %rsp, %rbp >>> .cfi_def_cfa_register %rbp >>> subq $16, %rsp >>> movl $1, %edi >>> movl $2, %esi >>> callq foo >>> movl $3, %edi >>> movl $4, %esi >>> movl %eax, -4(%rbp) # 4-byte Spill >>> callq foo >>> movl %eax, -8(%rbp) # 4-byte Spill >>> addq $16, %rsp >>> popq %rbp >>> .cfi_def_cfa %rsp, 8 >>> retq >>> >>> >>> 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/dcdc3afb/attachment.html>