[llvm-dev] RFC: [SmallVector] Adding SVec<T> and Vec<T> convenience wrappers.

Duncan P. N. Exon Smith via llvm-dev llvm-dev at lists.llvm.org
Tue Dec 1 16:13:48 PST 2020



> On 2020 Dec  1, at 14:52, Mehdi AMINI <joker.eph at gmail.com> wrote:
> 
> 
> 
> On Tue, Dec 1, 2020 at 2:39 PM Mehdi AMINI <joker.eph at gmail.com <mailto:joker.eph at gmail.com>> wrote:
> 
> 
> On Tue, Dec 1, 2020 at 2:19 PM Chris Lattner via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
>>>> On Nov 17, 2020, at 1:42 PM, David Blaikie <dblaikie at gmail.com <mailto:dblaikie at gmail.com>> wrote:
>>>>>> Thoughts/suggestions:
>>>>>> - Adding the default seems very reasonable to me, and I think that 64 bytes is a good default.  I think you should change the behavior so that SmallVector<LargeThing> defaults to a single inline element instead of zero though.  Perhaps generate a static_assert when it is crazy large.
>>>>> 
>>>>> Out of curiosity: Why a single rather than zero?
>>>> 
>>>> My rationale for this is basically that SmallVector is typically used for the case when you want to avoid an out-of-line allocation for a small number of elements, this was the reason it was created.  While there is some performance benefits of SmallVector<T,0> over std::vector<> they are almost trivial.
>>> 
>>> The performance benefits aren't trivial.
>>> 
>>> std::vector grow operations will refuse to use std::move for some T, a pessimization required by its exception guarantees, even if you're building with `-fno-exceptions`. We had a massive compile-time problem in 2016 related to this that I fixed with 3c406c2da52302eb5cced431373f240b9c037841 by switching to SmallVector<T,0>. You can see the history in r338071 / 0f81faed05c3c7c1fbaf6af402411c99d715cf56.
>>> 
>>> That issue, at least, is fixable without switching from std::vector just by adding noexcept to the appropriate user-defined move constructors.
>> 
>> Sure, once we’ve added noexcept to all types in LLVM/Clang/etc. That’s a pretty long tail though; a lot of work for relatively little gain given that we don’t care about exceptions anyway and we have an optimized vector implementation in tree. 
> 
> Can you spell this out for me?  Why do we need noexcept if we’re building with -fno-exceptions?  What is going on here?
> 
> It isn't clear to me that -fno-exceptions can get the same benefit as noexcept for code that is written with exceptions in mind (I think https://stackoverflow.com/questions/61417534/can-stdvectort-use-ts-move-constructor-if-exceptions-are-disabled <https://stackoverflow.com/questions/61417534/can-stdvectort-use-ts-move-constructor-if-exceptions-are-disabled> explains some of it).
> 
> While it is possible to write a library that optimizes for -fno-exceptions, I am not sure it would be standard-compliant for the STL to do so (and it'd be anyway another code path that the one written in term of `std::move_if_noexcept`).
> 
> Does it make sense or did you see it differently with your question?
> 
> 
> After digging a bit, I found that libcxx was changed last year to optimize with moving in std::vector when -fno-exceptions is present : https://reviews.llvm.org/D62228 <https://reviews.llvm.org/D62228>
> 
> That means that a copy-only class can't be used in vector anymore in clang-10 but it was possible in clang-9 (but only with -fno-exceptions): https://godbolt.org/z/M54bqn <https://godbolt.org/z/M54bqn>
Oh great, I didn't think this landed!

IMO, once all host toolchains we support have the same behaviour it would be safe to start using std::vector again (doing it sooner could give wildly divergent performance characteristics depending on what LLVM was built with).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201201/5236688c/attachment.html>


More information about the llvm-dev mailing list