Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #68773 > unrolled thread

alloca()-support

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2019-09-30 14:02 +0200
Last post2019-10-05 14:08 -0700
Articles 20 on this page of 110 — 21 participants

Back to article view | Back to comp.lang.c++


Contents

  alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 14:02 +0200
    Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-09-30 07:02 -0700
      Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:09 +0200
        Re: alloca()-support Bo Persson <bo@bo-persson.se> - 2019-09-30 17:29 +0200
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 17:33 +0200
      Re: alloca()-support gazelle@shell.xmission.com (Kenny McCormack) - 2019-09-30 16:26 +0000
    Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:12 +0300
      Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:16 +0200
        Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:30 +0300
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:44 +0200
            Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 00:36 +0300
              Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:28 +0200
                Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 16:08 +0300
                  Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 15:42 +0200
      Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 14:30 +0000
        Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:33 +0300
          Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-09-30 16:56 +0200
      Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-09-30 15:29 +0000
        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 17:31 +0200
          Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 07:03 +0000
            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 10:57 +0200
              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 18:49 +0000
                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:20 +0200
                  Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 20:39 +0000
                  Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:15 +0000
                    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:28 +0200
                      Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:29 +0000
      Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-09-30 11:14 -0700
    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:04 +0200
      Re: alloca()-support William Ahern <william@25thandClement.com> - 2019-09-30 11:01 -0700
        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:19 +0200
      Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-09-30 22:26 +0300
        Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 19:46 +0000
      Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:32 +0200
        Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-10-01 09:08 +0300
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 08:35 +0200
    Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 18:48 +0200
      Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:51 +0200
        Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 18:55 +0200
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:58 +0200
            Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 19:53 +0200
              Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-09-30 11:13 -0700
              Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 19:38 +0000
                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:41 +0200
                  Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 15:19 +0000
                    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 17:31 +0200
                      Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 18:58 +0000
                        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:24 +0200
                          Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:28 +0000
                            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:30 +0200
                              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:36 +0000
                                Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:01 +0200
                              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:42 +0000
                                Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:10 +0200
                                  Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:13 +0200
                      Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 21:10 +0200
                        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:25 +0200
                          Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 20:44 +0000
                          Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 23:26 +0200
                            Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-01 21:08 -0600
                              Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:19 +0200
                            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:39 +0200
                              Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:34 +0200
                          Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:14 +0200
                      Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:18 +0200
                        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 15:21 +0200
                          Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 04:09 +0000
                            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 07:48 +0200
                              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 05:49 +0000
                                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 07:52 +0200
                                  Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 06:46 +0000
                                    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 10:59 +0200
                Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 13:39 +0200
                  Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-03 13:23 +0000
                  Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-03 15:38 +0200
                    Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-03 14:51 +0000
                      Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-04 09:49 +0200
                    Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 21:47 +0200
                      Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-04 09:53 +0200
                    Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 21:52 +0200
              Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:39 +0200
          Re: alloca()-support James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-09-30 21:36 -0400
        Re: alloca()-support Philipp Klaus Krause <pkk@spth.de> - 2019-09-30 19:14 +0200
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 19:16 +0200
            Re: alloca()-support Robert Wessel <robertwessel2@yahoo.com> - 2019-10-01 00:18 -0500
              Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:43 +0200
              Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-10-01 02:42 -0700
                Re: alloca()-support James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-10-01 08:11 -0400
                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 14:53 +0200
        Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 17:52 +0000
      Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-09-30 11:20 -0600
        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 19:42 +0200
          Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 20:02 +0200
        Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 19:54 +0200
          Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-09-30 14:28 -0600
            Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 09:38 +0200
        Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 20:01 +0200
          Re: alloca()-support Manfred <noname@add.invalid> - 2019-10-01 17:45 +0200
    Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 00:03 -0700
      Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-10-02 11:30 +0300
      Re: alloca()-support Ian Collins <ian-news@hotmail.com> - 2019-10-02 21:34 +1300
        Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 01:36 -0700
          Re: alloca()-support Ian Collins <ian-news@hotmail.com> - 2019-10-02 21:41 +1300
            Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 02:28 -0700
    Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-02 02:35 -0700
      Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 02:43 -0700
      Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 16:26 +0300
        Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-02 12:33 -0700
          Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-03 01:47 +0300
            Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-05 14:08 -0700

Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →


#68807

FromSoviet_Mario <SovietMario@CCCP.MIR>
Date2019-09-30 19:53 +0200
Message-ID<qmtfeh$gno$1@dont-email.me>
In reply to#68801
On 30/09/2019 18:58, Bonita Montero wrote:
>>>> Since when (if at any time) was variable size automatic 
>>>> array supported ?
> 
>>> Since C99.
> 
>> for curiosity, this feature has one or more of the 
>> limitations I feared ... or even none of them ?
> 
> Yes, you could run out of stack-space, maybe hitting a 
> guard-page
> in the best case so that you wouldn't corrupt any other data.

uhm, I didn't mean THAT kind of risk (unavoidable), but the 
possible difficulties in defining variables beyond the point 
of declaration of the variable-size array.

I can't figure out how the compiler would reference them in 
standard efficient ways (use of registers).

Anyway, the difference with alloca () would be in a safer 
management of possible collisions and running out of stack 
space ? (compared with the plain declarations) ?

> 


-- 
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)

[toc] | [prev] | [next] | [standalone]


#68812

FromKeith Thompson <kst-u@mib.org>
Date2019-09-30 11:13 -0700
Message-ID<lneezx3b6b.fsf@kst-u.example.com>
In reply to#68807
Soviet_Mario <SovietMario@CCCP.MIR> writes:
> On 30/09/2019 18:58, Bonita Montero wrote:
>>>>> Since when (if at any time) was variable size automatic 
>>>>> array supported ?
>> 
>>>> Since C99.
>> 
>>> for curiosity, this feature has one or more of the 
>>> limitations I feared ... or even none of them ?
>> 
>> Yes, you could run out of stack-space, maybe hitting a 
>> guard-page
>> in the best case so that you wouldn't corrupt any other data.
>
> uhm, I didn't mean THAT kind of risk (unavoidable), but the 
> possible difficulties in defining variables beyond the point 
> of declaration of the variable-size array.
>
> I can't figure out how the compiler would reference them in 
> standard efficient ways (use of registers).
>
> Anyway, the difference with alloca () would be in a safer 
> management of possible collisions and running out of stack 
> space ? (compared with the plain declarations) ?

No.  Neither VLAs nor alloca() provide any protection against running
out of space.  Both have undefined behavior if there isn't enough memory
for the allocation.

alloca() (which, again, is non-standard) is a function that returns a
pointer.  It has no provision to return a null pointer on failure.

Defining a VLA, on the other hand, creates an array object to which you
can meaningfully apply sizeof.

Also, space allocated by alloca() is deallocated on return from the
enclosing function, not at the end of the enclosing block.

Since alloca() is a function, it can be invoked in contexts where a VLA
can't be created.  If you call alloca() as part of a function argument,
it's likely to corrupt the stack.

VLAs were introduced in C99 and made optional in C11 and are not
supported, except perhaps as an extension, in C++.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#68818

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-09-30 19:38 +0000
Message-ID<lRskF.22050$XA2.21391@fx05.iad>
In reply to#68807
Soviet_Mario <SovietMario@CCCP.MIR> writes:
>On 30/09/2019 18:58, Bonita Montero wrote:
>>>>> Since when (if at any time) was variable size automatic 
>>>>> array supported ?
>> 
>>>> Since C99.
>> 
>>> for curiosity, this feature has one or more of the 
>>> limitations I feared ... or even none of them ?
>> 
>> Yes, you could run out of stack-space, maybe hitting a 
>> guard-page
>> in the best case so that you wouldn't corrupt any other data.
>
>uhm, I didn't mean THAT kind of risk (unavoidable), but the 
>possible difficulties in defining variables beyond the point 
>of declaration of the variable-size array.
>
>I can't figure out how the compiler would reference them in 
>standard efficient ways (use of registers).


     mov %rsp, %rax     # rax now has starting address of alloca() region
     sub %rcx, %rsp     # rcx is the number of bytes being allocated.

....

     mov %rsp, %rbx     # rbx now has starting address of second alloca() region
     sub %rdx, %rsp     # rdx is the number of bytes being allocated
....
     ret                # all alloca storage is deallocated

(AT&T form)

It can always spill rax or rbx to the stack under register pressure.

[toc] | [prev] | [next] | [standalone]


#68830

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 07:41 +0200
Message-ID<qmuov1$n71$2@news.albasani.net>
In reply to#68818
>       mov %rsp, %rax     # rax now has starting address of alloca() region

The compiler usually uses RPB to remember the frame-pointer-address
at the prolog of the function. EBP is more suitable because it can
be restored in one step by the x86 LEAVE-instruction.

>       sub %rcx, %rsp     # rcx is the number of bytes being allocated.
> ....

[toc] | [prev] | [next] | [standalone]


#68855

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-10-01 15:19 +0000
Message-ID<J7KkF.4573$KB2.3280@fx02.iad>
In reply to#68830
Bonita Montero <Bonita.Montero@gmail.com> writes:
>>       mov %rsp, %rax     # rax now has starting address of alloca() region
>
>The compiler usually uses RPB to remember the frame-pointer-address
>at the prolog of the function. EBP is more suitable because it can
>be restored in one step by the x86 LEAVE-instruction.

So what?  The RSP is restored automatically by the ret instruction.

int f(unsigned long len)
{
    char *f = alloca(len);

    for (int i=0; i < 0; i++) {
        *f++ = '\0';
    }
    return 0;
}

gcc output:

0000000000400540 <f>:
#include <alloca.h>
#include <stdlib.h>

int f(unsigned long len)
{
  400540:       55                      push   %rbp
  400541:       48 89 e5                mov    %rsp,%rbp
  400544:       48 83 ec 20             sub    $0x20,%rsp
  400548:       48 89 7d e8             mov    %rdi,-0x18(%rbp)
    char *f = alloca(len);
  40054c:       48 8b 45 e8             mov    -0x18(%rbp),%rax
  400550:       48 8d 50 0f             lea    0xf(%rax),%rdx
  400554:       b8 10 00 00 00          mov    $0x10,%eax
  400559:       48 83 e8 01             sub    $0x1,%rax
  40055d:       48 01 d0                add    %rdx,%rax
  400560:       b9 10 00 00 00          mov    $0x10,%ecx
  400565:       ba 00 00 00 00          mov    $0x0,%edx
  40056a:       48 f7 f1                div    %rcx
  40056d:       48 6b c0 10             imul   $0x10,%rax,%rax


  400571:       48 29 c4                sub    %rax,%rsp <===== Alloca(len)
  400574:       48 89 e0                mov    %rsp,%rax <===== Remember f in %rax


  400577:       48 83 c0 0f             add    $0xf,%rax  <===== Align it
  40057b:       48 c1 e8 04             shr    $0x4,%rax
  40057f:       48 c1 e0 04             shl    $0x4,%rax
  400583:       48 89 45 f8             mov    %rax,-0x8(%rbp)  <== And save in stack frame

    for (int i=0; i < 0; i++) {
  400587:       c7 45 f4 00 00 00 00    movl   $0x0,-0xc(%rbp)
  40058e:       eb 13                   jmp    4005a3 <f+0x63>
        *f++ = '\0';
  400590:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  400594:       48 8d 50 01             lea    0x1(%rax),%rdx
  400598:       48 89 55 f8             mov    %rdx,-0x8(%rbp)
  40059c:       c6 00 00                movb   $0x0,(%rax)

  40059f:       83 45 f4 01             addl   $0x1,-0xc(%rbp)
  4005a3:       83 7d f4 00             cmpl   $0x0,-0xc(%rbp)
  4005a7:       78 e7                   js     400590 <f+0x50>
        *f++ = '\0';
    }
    return 0;
  4005a9:       b8 00 00 00 00          mov    $0x0,%eax
}
  4005ae:       c9                      leaveq 
  4005af:       c3                      retq   

>
>>       sub %rcx, %rsp     # rcx is the number of bytes being allocated.
>> ....

[toc] | [prev] | [next] | [standalone]


#68856

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 17:31 +0200
Message-ID<qmvrfu$j5$1@news.albasani.net>
In reply to#68855
>> The compiler usually uses RPB to remember the frame-pointer-address
>> at the prolog of the function. EBP is more suitable because it can
>> be restored in one step by the x86 LEAVE-instruction.

> So what?  The RSP is restored automatically by the ret instruction.

Yes, but LEAVE does three instructions in one step. Usually this
results in the same uOPs, but it is only one slot in the decoder.

[toc] | [prev] | [next] | [standalone]


#68862

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-01 18:58 +0000
Message-ID<LlNkF.594801$Nw3.562943@fx40.am4>
In reply to#68856
On 2019-10-01, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> The compiler usually uses RPB to remember the frame-pointer-address
>>> at the prolog of the function. EBP is more suitable because it can
>>> be restored in one step by the x86 LEAVE-instruction.
>
>> So what?  The RSP is restored automatically by the ret instruction.
>
> Yes, but LEAVE does three instructions in one step. Usually this
> results in the same uOPs, but it is only one slot in the decoder.
I never saw any compiler that uses `leave`. Especially since RBP doesn't
have to be used as optimization...


-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#68867

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 21:24 +0200
Message-ID<qn095f$3qm$1@news.albasani.net>
In reply to#68862
>> Yes, but LEAVE does three instructions in one step. Usually this
>> results in the same uOPs, but it is only one slot in the decoder.

> I never saw any compiler that uses `leave`.

MSVC and gcc always use LEAVE when you have dynamic stack-frames
with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:

#include <stddef.h>

void f( size_t s )
{
	int volatile a[s];
	a[s - 1] = 123;
}


     .file    "x.c"
     .text
     .p2align 4,,15
     .globl    f
     .type    f, @function
f:
.LFB0:
     .cfi_startproc
     leaq    18(,%rdi,4), %rax
     pushq    %rbp
     .cfi_def_cfa_offset 16
     .cfi_offset 6, -16
     subq    $1, %rdi
     andq    $-16, %rax
     movq    %rsp, %rbp
     .cfi_def_cfa_register 6
     subq    %rax, %rsp
     movl    $123, (%rsp,%rdi,4)
     leave
     .cfi_def_cfa 7, 8
     ret
     .cfi_endproc
.LFE0:
     .size    f, .-f
     .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
     .section    .note.GNU-stack,"",@progbits

[toc] | [prev] | [next] | [standalone]


#68879

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-02 04:28 +0000
Message-ID<MHVkF.568895$bS1.507387@fx13.am4>
In reply to#68867
On 2019-10-01, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>
>>> Yes, but LEAVE does three instructions in one step. Usually this
>>> results in the same uOPs, but it is only one slot in the decoder.
>
>> I never saw any compiler that uses `leave`.
>
> MSVC and gcc always use LEAVE when you have dynamic stack-frames
> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>
> #include <stddef.h>
>
> void f( size_t s )
> {
> 	int volatile a[s];
> 	a[s - 1] = 123;
> }
>
>
>      .file    "x.c"
>      .text
>      .p2align 4,,15
>      .globl    f
>      .type    f, @function
> f:
> .LFB0:
>      .cfi_startproc
>      leaq    18(,%rdi,4), %rax
>      pushq    %rbp
>      .cfi_def_cfa_offset 16
>      .cfi_offset 6, -16
>      subq    $1, %rdi
>      andq    $-16, %rax
>      movq    %rsp, %rbp
>      .cfi_def_cfa_register 6
>      subq    %rax, %rsp
>      movl    $123, (%rsp,%rdi,4)
>      leave
>      .cfi_def_cfa 7, 8
>      ret
>      .cfi_endproc
> .LFE0:
>      .size    f, .-f
>      .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>      .section    .note.GNU-stack,"",@progbits
Yes, this is against optimisations as you use volatile...

-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#68882

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-02 06:30 +0200
Message-ID<qn1950$hai$3@news.albasani.net>
In reply to#68879
>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>
>> #include <stddef.h>
>>
>> void f( size_t s )
>> {
>> 	int volatile a[s];
>> 	a[s - 1] = 123;
>> }
>>
>>
>>       .file    "x.c"
>>       .text
>>       .p2align 4,,15
>>       .globl    f
>>       .type    f, @function
>> f:
>> .LFB0:
>>       .cfi_startproc
>>       leaq    18(,%rdi,4), %rax
>>       pushq    %rbp
>>       .cfi_def_cfa_offset 16
>>       .cfi_offset 6, -16
>>       subq    $1, %rdi
>>       andq    $-16, %rax
>>       movq    %rsp, %rbp
>>       .cfi_def_cfa_register 6
>>       subq    %rax, %rsp
>>       movl    $123, (%rsp,%rdi,4)
>>       leave
>>       .cfi_def_cfa 7, 8
>>       ret
>>       .cfi_endproc
>> .LFE0:
>>       .size    f, .-f
>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>       .section    .note.GNU-stack,"",@progbits

> Yes, this is against optimisations as you use volatile...

I use volatile to prevent the compiler from optimizing away the
function body.

[toc] | [prev] | [next] | [standalone]


#68883

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-02 04:36 +0000
Message-ID<mPVkF.569662$R83.227680@fx23.am4>
In reply to#68882
On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>
>>> #include <stddef.h>
>>>
>>> void f( size_t s )
>>> {
>>> 	int volatile a[s];
>>> 	a[s - 1] = 123;
>>> }
>>>
>>>
>>>       .file    "x.c"
>>>       .text
>>>       .p2align 4,,15
>>>       .globl    f
>>>       .type    f, @function
>>> f:
>>> .LFB0:
>>>       .cfi_startproc
>>>       leaq    18(,%rdi,4), %rax
>>>       pushq    %rbp
>>>       .cfi_def_cfa_offset 16
>>>       .cfi_offset 6, -16
>>>       subq    $1, %rdi
>>>       andq    $-16, %rax
>>>       movq    %rsp, %rbp
>>>       .cfi_def_cfa_register 6
>>>       subq    %rax, %rsp
>>>       movl    $123, (%rsp,%rdi,4)
>>>       leave
>>>       .cfi_def_cfa 7, 8
>>>       ret
>>>       .cfi_endproc
>>> .LFE0:
>>>       .size    f, .-f
>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>>       .section    .note.GNU-stack,"",@progbits
>
>> Yes, this is against optimisations as you use volatile...
>
> I use volatile to prevent the compiler from optimizing away the
> function body.
"
Linus Torvalds has expressed his displeasure in the past over VLA usage
for arrays with predetermined small sizes, with comments like "USING
VLA'S IS ACTIVELY STUPID! It generates much more code, and much slower
code (and more fragile code), than just using a fixed key size would
have done." [6] With the Linux 4.20 kernel, Linux kernel is effectively
VLA-free.[7] 
"

-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#68887

FromDavid Brown <david.brown@hesbynett.no>
Date2019-10-02 10:01 +0200
Message-ID<qn1lhf$bsm$1@dont-email.me>
In reply to#68883
On 02/10/2019 06:36, Melzzzzz wrote:
> On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>>
>>>> #include <stddef.h>
>>>>
>>>> void f( size_t s )
>>>> {
>>>> 	int volatile a[s];
>>>> 	a[s - 1] = 123;
>>>> }
>>>>
<snip>
>>
>>> Yes, this is against optimisations as you use volatile...
>>
>> I use volatile to prevent the compiler from optimizing away the
>> function body.

There are usually better ways to get this, such as giving a return value
that depends on the function inputs.  If you have to use "volatile" to
ensure you are generating code that can be examined, then minimise its
use rather than making the whole array volatile.

(In a test function that used the VLA for calculations, gcc still
generated a "leave" instruction.)

> "
> Linus Torvalds has expressed his displeasure in the past over VLA usage
> for arrays with predetermined small sizes, with comments like "USING
> VLA'S IS ACTIVELY STUPID! It generates much more code, and much slower
> code (and more fragile code), than just using a fixed key size would
> have done." [6] With the Linux 4.20 kernel, Linux kernel is effectively
> VLA-free.[7] 
> "
> 

VLA's with pre-determined small sizes result in /identical/ code to
arrays with fixed sizes.

void foo1(void) {
	const int arr_size = 12;
	int arr[arr_size];
	...
}

void foo2(void) {
	#define ARR_SIZE 12
	int arr[ARR_SIZE];
	...
}


"foo1" has a VLA with a predetermined small size, while "foo2" has a
normal array with fixed size.  These are different as far as the C
language is concerned, but identical in the generated code.


I /think/ what Torvalds is trying to say is that if you know that the
size "n" of your VLA is going be at most "max_n", and you know "max_n"
is small, then you should use a fixed size array of size "max_n" instead
of a VLA.  I believe that has both advantages and disadvantages.  When
the array is of fixed size (i.e., known at compile time - even if it is
technically a VLA) the code for allocating and deallocating the space is
simpler.  Code for accessing the contents of the array or other data
might be a little simpler.  But it is all just one-time calculations.
Code that is run repeatedly - and if you have an array, you probably
have a loop - is going to be identical.

So you get the trade-off between a few extra instructions for the
variable VLA, balanced against the benefits of reduced cache use from a
smaller array.  I'd not like to be categorical about which is best - it
would need measuring.


If the VLA is making the code fragile, then I expect it would be equally
fragile with a fixed size array.


(Fixed size arrays are also easier for analysis of stack usage, if that
is important.)

[toc] | [prev] | [next] | [standalone]


#68885

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-02 04:42 +0000
Message-ID<4VVkF.657428$t92.267489@fx25.am4>
In reply to#68882
On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>
>>> #include <stddef.h>
>>>
>>> void f( size_t s )
>>> {
>>> 	int volatile a[s];
>>> 	a[s - 1] = 123;
>>> }
>>>
>>>
>>>       .file    "x.c"
>>>       .text
>>>       .p2align 4,,15
>>>       .globl    f
>>>       .type    f, @function
>>> f:
>>> .LFB0:
>>>       .cfi_startproc
>>>       leaq    18(,%rdi,4), %rax
>>>       pushq    %rbp
>>>       .cfi_def_cfa_offset 16
>>>       .cfi_offset 6, -16
>>>       subq    $1, %rdi
>>>       andq    $-16, %rax
>>>       movq    %rsp, %rbp
>>>       .cfi_def_cfa_register 6
>>>       subq    %rax, %rsp
>>>       movl    $123, (%rsp,%rdi,4)
>>>       leave
>>>       .cfi_def_cfa 7, 8
>>>       ret
>>>       .cfi_endproc
>>> .LFE0:
>>>       .size    f, .-f
>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>>       .section    .note.GNU-stack,"",@progbits
>
>> Yes, this is against optimisations as you use volatile...
>
> I use volatile to prevent the compiler from optimizing away the
> function body.
Try more realistic example:
float read_val();
float process(int,float*);
float read_and_process(int n)
{
        float vals[n];

            for (int i = 0; i < n; ++i)
                        vals[i] = read_val();

                return process(n, vals);
}

Where is `leave` now?
-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#68888

FromDavid Brown <david.brown@hesbynett.no>
Date2019-10-02 10:10 +0200
Message-ID<qn1m1i$f8t$1@dont-email.me>
In reply to#68885
On 02/10/2019 06:42, Melzzzzz wrote:
> On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>>
>>>> #include <stddef.h>
>>>>
>>>> void f( size_t s )
>>>> {
>>>> 	int volatile a[s];
>>>> 	a[s - 1] = 123;
>>>> }
>>>>
>>>>
>>>>       .file    "x.c"
>>>>       .text
>>>>       .p2align 4,,15
>>>>       .globl    f
>>>>       .type    f, @function
>>>> f:
>>>> .LFB0:
>>>>       .cfi_startproc
>>>>       leaq    18(,%rdi,4), %rax
>>>>       pushq    %rbp
>>>>       .cfi_def_cfa_offset 16
>>>>       .cfi_offset 6, -16
>>>>       subq    $1, %rdi
>>>>       andq    $-16, %rax
>>>>       movq    %rsp, %rbp
>>>>       .cfi_def_cfa_register 6
>>>>       subq    %rax, %rsp
>>>>       movl    $123, (%rsp,%rdi,4)
>>>>       leave
>>>>       .cfi_def_cfa 7, 8
>>>>       ret
>>>>       .cfi_endproc
>>>> .LFE0:
>>>>       .size    f, .-f
>>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>>>       .section    .note.GNU-stack,"",@progbits
>>
>>> Yes, this is against optimisations as you use volatile...
>>
>> I use volatile to prevent the compiler from optimizing away the
>> function body.
> Try more realistic example:
> float read_val();
> float process(int,float*);
> float read_and_process(int n)
> {
>         float vals[n];
> 
>             for (int i = 0; i < n; ++i)
>                         vals[i] = read_val();
> 
>                 return process(n, vals);
> }
> 
> Where is `leave` now?
> 

The compiler will use it if it is convenient, and not use it otherwise.
 This sample code /does/ generate "leave" with gcc :

int f(int s )
{
    int a[s];
    for (int i = 0; i < s; i++) a[i] = i;
    int t = 0;
    for (int i = 0; i < s; i++) t += a[i];
    return t;
}

(clang does not generate a "leave" - it generates its usual unrolled
vector monstrosities that are highly efficient for huge loop counts, and
terrible for tiny counts.)


Basically, it seems that "leave" is equivalent to "mov %ebp, %esp" then
"pop %ebp".  If the compiler would otherwise have generated these
instructions, then it uses "leave".  If not, then it doesn't.  "leave"
appears to be marginally more efficient than the separate instructions -
enough so to use it when there is the option, but not enough to go out
of its way to use it.

(The matching "enter" instruction is much slower than manual
manipulation of the registers, and is thus avoided.)

[toc] | [prev] | [next] | [standalone]


#68907

FromMel <mel@zzzzz.com>
Date2019-10-02 15:13 +0200
Message-ID<almarsoft.1283905241101098670@news.albasani.net>
In reply to#68888
On Wed, 2 Oct 2019 10:10:26 +0200, David Brown 
<david.brown@hesbynett.no> wrote:
> On 02/10/2019 06:42, Melzzzzz wrote:
> > On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
> >>>> MSVC and gcc always use LEAVE when you have dynamic 
stack-frames
> >>>> with VLAs (gcc) or alloca(). Here's an example of gcc with 
VLAs:
> >>>>
> >>>> #include <stddef.h>
> >>>>
> >>>> void f( size_t s )
> >>>> {
> >>>> 	int volatile a[s];
> >>>> 	a[s - 1] = 123;
> >>>> }
> >>>>
> >>>>
> >>>>       .file    "x.c"
> >>>>       .text
> >>>>       .p2align 4,,15
> >>>>       .globl    f
> >>>>       .type    f, @function
> >>>> f:
> >>>> .LFB0:
> >>>>       .cfi_startproc
> >>>>       leaq    18(,%rdi,4), %rax
> >>>>       pushq    %rbp
> >>>>       .cfi_def_cfa_offset 16
> >>>>       .cfi_offset 6, -16
> >>>>       subq    $1, %rdi
> >>>>       andq    $-16, %rax
> >>>>       movq    %rsp, %rbp
> >>>>       .cfi_def_cfa_register 6
> >>>>       subq    %rax, %rsp
> >>>>       movl    $123, (%rsp,%rdi,4)
> >>>>       leave
> >>>>       .cfi_def_cfa 7, 8
> >>>>       ret
> >>>>       .cfi_endproc
> >>>> .LFE0:
> >>>>       .size    f, .-f
> >>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
> >>>>       .section    .note.GNU-stack,"",@progbits
> >>
> >>> Yes, this is against optimisations as you use volatile...
> >>
> >> I use volatile to prevent the compiler from optimizing away the
> >> function body.
> > Try more realistic example:
> > float read_val();
> > float process(int,float*);
> > float read_and_process(int n)
> > {
> >         float vals[n];
> > 
> >             for (int i = 0; i < n; ++i)
> >                         vals[i] = read_val();
> > 
> >                 return process(n, vals);
> > }
> > 
> > Where is `leave` now?
> > 


> The compiler will use it if it is convenient, and not use it 
otherwise.
>  This sample code /does/ generate "leave" with gcc :


> int f(int s )
> {
>     int a[s];
>     for (int i = 0; i < s; i++) a[i] = i;
>     int t = 0;
>     for (int i = 0; i < s; i++) t += a[i];
>     return t;
> }


> (clang does not generate a "leave" - it generates its usual unrolled
> vector monstrosities that are highly efficient for huge loop 
counts, and
> terrible for tiny counts.)




> Basically, it seems that "leave" is equivalent to "mov %ebp, %esp" 
then
> "pop %ebp".  If the compiler would otherwise have generated these
> instructions, then it uses "leave".  If not, then it doesn't.  
"leave"
> appears to be marginally more efficient than the separate 
instructions -
> enough so to use it when there is the option, but not enough to go 
out
> of its way to use it.


> (The matching "enter" instruction is much slower than manual
> manipulation of the registers, and is thus avoided.)

This is not reallistic example as well.

-- 
Press any key to continue or any other to quit 

[toc] | [prev] | [next] | [standalone]


#68864

FromDavid Brown <david.brown@hesbynett.no>
Date2019-10-01 21:10 +0200
Message-ID<qn08bp$7n0$1@dont-email.me>
In reply to#68856
On 01/10/2019 17:31, Bonita Montero wrote:
>>> The compiler usually uses RPB to remember the frame-pointer-address
>>> at the prolog of the function. EBP is more suitable because it can
>>> be restored in one step by the x86 LEAVE-instruction.
> 
>> So what?  The RSP is restored automatically by the ret instruction.
> 
> Yes, but LEAVE does three instructions in one step. Usually this
> results in the same uOPs, but it is only one slot in the decoder.

I don't know this case, but typically on modern cpus "complex"
instructions like "leave" are slower than manual expanding the
instructions using "pop", "ret", etc.

The easiest way to find out is to do a test compile (godbolt.org is
great for it) making sure you have cpu-specific tuning flags and
optimisations enabled, and look at the output.  The compiler writers
know better than most of us which instruction patterns are the most
efficient.

[toc] | [prev] | [next] | [standalone]


#68868

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 21:25 +0200
Message-ID<qn096o$3qm$2@news.albasani.net>
In reply to#68864
> I don't know this case, but typically on modern cpus "complex"
> instructions like "leave" are slower than manual expanding the
> instructions using "pop", "ret", etc.

That's wrong.

[toc] | [prev] | [next] | [standalone]


#68872

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-10-01 20:44 +0000
Message-ID<vUOkF.1997$9v2.1600@fx31.iad>
In reply to#68868
Bonita Montero <Bonita.Montero@gmail.com> writes:
>> I don't know this case, but typically on modern cpus "complex"
>> instructions like "leave" are slower than manual expanding the
>> instructions using "pop", "ret", etc.
>
>That's wrong.

From the Intel optimization guide:

The Intel 64 and IA-32 architectures have several commonly used instructions for
parameter passing and procedure entry and exit: PUSH, POP, CALL, LEAVE and RET.
These instructions implicitly update the stack pointer register (RSP), maintaining a
combined control and parameter stack without software intervention. These instruc-
tions are typically implemented by several ops in previous microarchitectures.

The Stack Pointer Tracker moves all these implicit RSP updates to logic contained in
the decoders themselves. The feature provides the following benefits:

ˇ Improves decode bandwidth, as PUSH, POP and RET are single op instructions in Intel Core microarchitecture.
ˇ Conserves execution bandwidth as the RSP updates do not compete for execution resources.
ˇ Improves parallelism in the out of order execution engine as the implicit serial dependencies between ops are removed.
ˇ Improves power efficiency as the RSP updates are carried out on small, dedicated hardware.

Assembly/Compiler Coding Rule 31. (ML impact, M generality) Avoid using
complex instructions (for example, enter, leave, or loop) that have more than four
ľops and require multiple cycles to decode. Use sequences of simple instructions
instead.

Complex instructions may save architectural registers, but incur a penalty of 4 ľops to
set up parameters for the microsequencer ROM.

[toc] | [prev] | [next] | [standalone]


#68874

FromDavid Brown <david.brown@hesbynett.no>
Date2019-10-01 23:26 +0200
Message-ID<qn0gav$qnn$1@dont-email.me>
In reply to#68868
On 01/10/2019 21:25, Bonita Montero wrote:
>> I don't know this case, but typically on modern cpus "complex"
>> instructions like "leave" are slower than manual expanding the
>> instructions using "pop", "ret", etc.
> 
> That's wrong.

As a general point, I don't think it is wrong - but from your posting it
looks like it does not apply in the case of "leave".  At least, gcc uses
it, which is a reasonable indicator that it is more efficient than
separate instructions.

A little googling suggests that the "enter" instruction is slower than
the individual instructions, but that "leave" is quite fast.  There are
plenty of other legacy CISC instructions that are slower than breaking
them apart into equivalent simpler instructions, such as the "LOOP"
instructions.  I'm sure x86 assembly experts could give you more.

I've seen the same thing on other processors too.  IIRC, on the 68060
the hardware integer division instruction was slower than a software
division routine.

[toc] | [prev] | [next] | [standalone]


#68876

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2019-10-01 21:08 -0600
Message-ID<1br23vu9nn.fsf@pfeifferfamily.net>
In reply to#68874
David Brown <david.brown@hesbynett.no> writes:

> On 01/10/2019 21:25, Bonita Montero wrote:
>>> I don't know this case, but typically on modern cpus "complex"
>>> instructions like "leave" are slower than manual expanding the
>>> instructions using "pop", "ret", etc.
>> 
>> That's wrong.
>
> As a general point, I don't think it is wrong - but from your posting it
> looks like it does not apply in the case of "leave".  At least, gcc uses
> it, which is a reasonable indicator that it is more efficient than
> separate instructions.
>
> A little googling suggests that the "enter" instruction is slower than
> the individual instructions, but that "leave" is quite fast.  There are
> plenty of other legacy CISC instructions that are slower than breaking
> them apart into equivalent simpler instructions, such as the "LOOP"
> instructions.  I'm sure x86 assembly experts could give you more.
>
> I've seen the same thing on other processors too.  IIRC, on the 68060
> the hardware integer division instruction was slower than a software
> division routine.

There was a time when it was true.  I'd be pretty surprised if it still
were.

[toc] | [prev] | [next] | [standalone]


Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →

Back to top | Article view | comp.lang.c++


csiph-web