It's https://reviews.llvm.org/D129565 follow-up.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
llvm/include/llvm/ADT/SmallVector.h | ||
---|---|---|
1299 | TODO: add more tests to make sure there is no surprises coming from overloading rules | |
llvm/unittests/ADT/SmallVectorTest.cpp | ||
1139 | That's basically copy of STLExtrasTest.ToVector test body after removing enumerate() calls. I feel it make sense to have it here since to_vector belongs to SmallVector. |
By the way, I think it would be worthwhile to add an ArrayRef constructor to SmallVector, or else drop the existing iterator_range ctor. I've wanted to switch an iterator_range to ArrayRef a few times in the past, and always gave up due to the SmallVector fallout. We should support both or neither.
“Neither” makes some sense to me, since to_vector and to_vector_of are clear and support any range naturally. @dblaikie, any thoughts?
Yeah, I'd tend to lean that way - if std::vector doesn't have generic range-based construction, I'm happy with SmallVector not having it either.
llvm/include/llvm/ADT/SmallVector.h | ||
---|---|---|
1304–1307 | Rather than an overload, can the Size parameter have a default value in the other definition and this overload can be removed? |
Remove WIP tag since overall direction seem to be fine and now all tests are passing (at least locally). Address some comments.
llvm/include/llvm/ADT/SmallVector.h | ||
---|---|---|
1285–1286 | Yes, it's indeed redundant! Interesting, I didn't even bother thinking about removing it since it was present on to_vector before my change. And given that's about widely used SmallVector header I didn't expect that it could have anything superfluous. |
llvm/include/llvm/ADT/SmallVector.h | ||
---|---|---|
1285–1286 | Maybe it predates SmallVector itself having a default? Or maybe it has some hard-to-predict impact on compile time? You might be able to figure that out via a git-blame and/or a look at the original review thread, or you can ask the author that added it (if it was me, I don’t remember :)). Most likely it can just be skipped though. |
llvm/include/llvm/ADT/SmallVector.h | ||
---|---|---|
1304–1307 | The thing is we need to compute default Size from R which is Size's successor on template parameter list. We can reorder list and it would work as long as Size is default: template <typename Out, typename R, unsigned Size = CalculateSmallVectorDefaultInlinedElements< ValueTypeFromRangeType<R>>::value> SmallVector<Out, Size> to_vector_of(R &&Range) { return {std::begin(Range), std::end(Range)}; } However when Size is non-default both preceding types Out, R need to be passed explicitly during instantiation. If I understand it correctly, that was reason for having 2 definitions of to_vector function - for similar reason they couldn't be merged into one. It would be much easier if Size depended on Out instead but except some special scenarios when it's allowed (pointer types), in general I don't think we can rely on this. |
Replace to_vector_of usage with to_vector where possible, improve names in ToVectorOf test case. All comments should be addressed now.
Might be worth submitting this separately/without updating all the callers - so that if a caller has to be reverted for some reason we don't have to revert the functionality and testing, etc, itself? (callers could probably done in reasonable chunks - 10s, maybe 50 at a time? huge patches are a bit awkward (again, in terms of bisecting/reverting/etc) but doing one patch for each caller's probably excessive too - somewhere in between)
llvm/include/llvm/ADT/SmallVector.h | ||
---|---|---|
1286–1287 | Patch might be easier to read if these were removed in a separate patch, if they can be separate? (looks like they should be/are unrelated to the addition of to_vector_of? | |
llvm/unittests/ADT/SmallVectorTest.cpp | ||
1139 | We shouldn't duplicate tests - if to_vector is in SmallVector.h, it should be tested in SmallVectorTest.cpp, not in STLExtrasTest.cpp - so it should probably be moved here, rather than copied - and that could be done in a preliminary/separate commit? | |
1163–1165 | Generally prefer non-member overloads where possible to allow for equal conversions for LHS and RHS. In this case it could be a friend to make it easy to write inline | |
1168–1178 | This seems a bit too specific? Emulating a particular LLVM data type like MDOperand - could this be named/designed more generally/abstractly so as not to be overloaded with the specifics of some LLVM detail? |
Seems like a stretch for the concept/definition of cast<> though I recall there are some novel implementations of cast for other types - so I'm open to an argument to the contrary, that this conversion would be consistent with others implemented via cast<>.
I think cast<> comes with the implication that the conversion is zero-cost (in non-assert builds), which is not the case here. to_vector() is an expensive O(n) operation.
llvm/include/llvm/ADT/SmallVector.h | ||
---|---|---|
1286–1287 | You are right, I can extract it to separate patch. | |
llvm/unittests/ADT/SmallVectorTest.cpp | ||
1139 |
I would agree except the fact that STLExtrasTest.ToVector is not exactly 1-1 copy because it has enumerate() call (STLExtras.h) and I believe it tests both to_vector and enumerate functions. There are following options I see right now:
| |
1163–1165 | Ok. I will fix it. | |
1168–1178 | I thought there would be some value in referring to MDOperand/Metadata classes since that was background for this patch: https://reviews.llvm.org/D129565#3648665 But I get your point - what matters here is just property of MDOperand being convertible to Metadata. I can use 'From' and 'To' names as more appropriate in expressing conversion. |
llvm/unittests/ADT/SmallVectorTest.cpp | ||
---|---|---|
865–868 | This could be a constexpr variable template, maybe? & then the EXPECT_TRUEs testing this could instead be static_assert rather than runtime tests? | |
1168–1178 | Yep, that's the thinking! Maybe we can even remove the fact that one side of this is a pointer, and the other a value? Have both sides be values (eg: SmallVector<From> -> SmallVector<To>)? Shouldn't be any need for so many operations on From or To either (eg: the operator *, operator From * (I'd expect the only conversion should be the To(From) ctor), get(), etc) - probably From and To can be structs, maybe with a single int member that gets copied on conversion, so that can be checked on the other side of the conversion?) | |
1181–1183 | Oh, looks like this is backwards, maybe? I'd expect the source type to be To and the destination type to be From, so more like to_vector_of<To>(SomeFromVector)? | |
1182–1221 | I guess this is how the other to_vectors were already tested? But if you're up for it in a pre or post commit, might be nice to simplify this - like I'm not sure it's necessary to test all these variants. The implementation is generic - it tests anything you can do begin(x) and end(x) on, so we probably only need to test one such type? But if we really want to test 4, perhaps we can avoid rewriting the code and use a type expansion in gunit?) |
llvm/unittests/ADT/SmallVectorTest.cpp | ||
---|---|---|
1182–1221 | I agree it's not necessary so eventually decided to remove ArrayRef variants. |
llvm/unittests/ADT/SmallVectorTest.cpp | ||
---|---|---|
1144 | For now message argument is required, soon after https://reviews.llvm.org/D130689 could be removed. Anyway if needed may be done in separate NFC. |
Why do we need to explicitly pass InlineSize<R>::value? Isn't that the default anyway?