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.

> 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”. :-)

Thanks,
Richard

Reply via email to