On Wed, Jun 30, 2021 at 11:00 AM Richard Sandiford
<richard.sandif...@arm.com> wrote:
>
> Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> > Note there's also array_slice<> which could be used to pass non-const
> > vec<>s that are never resized but modified - the only "valid" case of
> > passing a non-const vec<> by value.
>
> Yeah.  We'd need a new constructor for that (the current one only
> takes const vec<>&) but I agree it would be a good thing to do.
>
> I realise you weren't saying otherwise, but: array_slice<> can also be
> used for const vec<>s.  E.g. array_slice<const int> can't be resized
> or modified.
>
> I think array_slice<> is going to be more efficient as well.  E.g.:
>
> void
> f1 (vec<char> &foo)
> {
>   for (unsigned int i = 0; i < foo.length (); ++i)
>     foo[i] += 1;
> }
>
> void
> f2 (array_slice<char> foo)
> {
>   for (unsigned int i = 0; i < foo.size (); ++i)
>     foo[i] += 1;
> }
>
> gives:
>
> 000000000000d150 <f1(vec<char, va_heap, vl_ptr>&)>:
>     d150:       48 8b 07                mov    (%rdi),%rax
>     d153:       31 d2                   xor    %edx,%edx
>     d155:       48 85 c0                test   %rax,%rax
>     d158:       74 26                   je     d180 <f1(vec<char, va_heap, 
> vl_ptr>&)+0x30>
>     d15a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
>     d160:       3b 50 04                cmp    0x4(%rax),%edx
>     d163:       73 12                   jae    d177 <f1(vec<char, va_heap, 
> vl_ptr>&)+0x27>
>     d165:       89 d1                   mov    %edx,%ecx
>     d167:       83 c2 01                add    $0x1,%edx
>     d16a:       80 44 08 08 01          addb   $0x1,0x8(%rax,%rcx,1)
>     d16f:       48 8b 07                mov    (%rdi),%rax
>     d172:       48 85 c0                test   %rax,%rax
>     d175:       75 e9                   jne    d160 <f1(vec<char, va_heap, 
> vl_ptr>&)+0x10>
>     d177:       c3                      retq
>     d178:       0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
>     d17f:       00
>     d180:       c3                      retq
>
> 000000000000d190 <f2(array_slice<char>)>:
>     d190:       85 f6                   test   %esi,%esi
>     d192:       74 18                   je     d1ac 
> <f2(array_slice<char>)+0x1c>
>     d194:       8d 46 ff                lea    -0x1(%rsi),%eax
>     d197:       48 8d 44 07 01          lea    0x1(%rdi,%rax,1),%rax
>     d19c:       0f 1f 40 00             nopl   0x0(%rax)
>     d1a0:       80 07 01                addb   $0x1,(%rdi)
>     d1a3:       48 83 c7 01             add    $0x1,%rdi
>     d1a7:       48 39 c7                cmp    %rax,%rdi
>     d1aa:       75 f4                   jne    d1a0 
> <f2(array_slice<char>)+0x10>
>     d1ac:       c3                      retq
>
> where f1 has to reload the length and base each iteration,
> but f2 doesn't.

Of course but that's unfair - by refrence vec<> vs. by value array_slice<>
plus char * pointer stores which destroy all TBAA ... ;)

>
> > But as noted array_slice<> lacks most of the vec<> API so I'm not sure
> > how awkward that option would be.  We of course can amend its API as
> > well.
>
> Yeah, that'd be good.  The current class follows the principle
> “don't add stuff that isn't needed yet”. :-)

Yes, and that's good of course.

Richard.

> Thanks,
> Richard

Reply via email to