This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Add new type traits for type pack indexes
ClosedPublic

Authored by scott.linder on Apr 16 2021, 11:32 AM.

Details

Summary

Similar versions of these already exist, this effectively just just
factors them out into STLExtras. I plan to use these in future patches.

Diff Detail

Event Timeline

scott.linder created this revision.Apr 16 2021, 11:32 AM
scott.linder requested review of this revision.Apr 16 2021, 11:32 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 16 2021, 11:32 AM

Moved tests to STLExtrasTest.cpp from STLShimsTest.cpp

Harbormaster completed remote builds in B99227: Diff 338185.

Are there (future) STL equivalents of TypesAreDistinct or FirsntIndexOfType?

llvm/include/llvm/ADT/STLExtras.h
151–154

Could this be replaced with:

return llvm::find(Matches, true) - std::begin(Matches);

or something like that?
(similarly below in "AreTypesDistinct")?

Hmm, what's the purpose of the first element of the array being 'false', and then iterating from the second element and subtracting one from the index before returning?

Oh, that's to support the zero-length case? Fair enough. I don't mind either way, but maybe it'd be simpler/more obvious if that were done via specialization? - oh, what happens if you put the buffer value at the end rather than the beginning. In this algorithm you could put "true" at the end (and remove "false" from the start) and then it'd return 1 when sizeof...(Ts) is zero?

163

Any concerns about the quadratic complexity here? Any more efficient way to write this, maybe? (what's the libc++ equivalent implementation look like, I wonder?)

Are there (future) STL equivalents of TypesAreDistinct or FirsntIndexOfType?

There aren't, as far as I'm aware. I didn't do an exhaustive search, but at the very least I don't see anything equivalent in <type_traits>

llvm/include/llvm/ADT/STLExtras.h
151–154

Sure, I think llvm::find would need to be constexpr then? I assume that will ripple through some other things in STLExtras.h, so maybe I should do a pass to add constexpr wherever possible in STLExtras.h? Or in this case would just marking what I need be better?

Putting the extra element at the end and having it defined to return a size >= sizeof...(Ts) seems reasonable, especially as it is just a detail function. I'll make that change, thank you!

163

I couldn't think of any in a constexpr context, but there very well may be.

My hope is that this is only needed once per instantiation of a type that cares about this property. I.e. once you assert that IntrusiveVariant<Foo, Bar, Baz> has distinct alternative types, I believe the compiler does not need to re-check that assertion. Incidentally we previously didn't assert this at all PointerUnion, although it seems to be a requirement?

dblaikie added inline comments.Apr 19 2021, 10:58 AM
llvm/include/llvm/ADT/STLExtras.h
151–154

oh, sure if there's stuff that needs to be constexpr and isn't - if it's not a ton of stuff, can probably include it in this patch (adding the constexpr keyword as needed) - if it's a lot, maybe a separate preliminary patch. (I probably wouldn't bother adding unit tests for constexpr-ness, but treat it as a quasi-NFC change). (if you want to include only what's needed in this patch and also separately submit a patch to constexpr the rest (then maybe some testing may be needed, to ensure all the implementation details got constexpr'd correctly))

scott.linder added inline comments.May 14 2021, 12:16 PM
llvm/include/llvm/ADT/STLExtras.h
151–154

It looks like std::find isn't constexpr until C++20, and llvm::find just wraps it. I think I could change llvm::find to have a standalone implementation and make it constexpr, but I don't know how often this will be useful. Do you have a preference on how I approach this?

dblaikie accepted this revision.May 14 2021, 5:49 PM

Sounds good - thanks!

llvm/include/llvm/ADT/STLExtras.h
151–154

Nah, that's OK. Whichever's cool - making our llvm::find constexpr would be nice (separate patch, though) - but equally if that's beyond what you want to do here - a comment saying "use find once it's constexpr/in C++20" or something like that.

This revision is now accepted and ready to land.May 14 2021, 5:49 PM
This revision was landed with ongoing or failed builds.May 17 2021, 3:29 PM
This revision was automatically updated to reflect the committed changes.

Thank you for reverting, and for the links to the builds! I'll take a look

I also neglected to move the extra element to the end of the array, so I'll make that change when I fix the build failure on Windows

scott.linder added a comment.EditedMay 18 2021, 10:32 AM

This seems like a bug in parameter pack expansion in older versions of MSVC, compare 19.10 https://godbolt.org/z/TMd3K8WoK with 19.14 https://godbolt.org/z/9c9TT8bnb

@stella.stamenova is there any possibility the build bots could be updated to the latest MSVC 2017 update? https://llvm.org/docs/GettingStartedVS.html#software says "Visual Studio 2017 or higher, with the latest Update installed", but I could also see us wanting to support any VS 2017 release if possible.

If we want to support all updates of VS 2017 I can just substitute in the old definition of llvm::TypeIndex in place of the new llvm::FirstIndexOfType, but I might have to think more about how to work around this in llvm::TypesAreDistinct

scott.linder reopened this revision.May 18 2021, 3:42 PM
This revision is now accepted and ready to land.May 18 2021, 3:42 PM

Replace constexpr functions with recursively defined templates, working around
an MSVC bug.

scott.linder requested review of this revision.May 18 2021, 3:43 PM

This seems like a bug in parameter pack expansion in older versions of MSVC, compare 19.10 https://godbolt.org/z/TMd3K8WoK with 19.14 https://godbolt.org/z/9c9TT8bnb

@stella.stamenova is there any possibility the build bots could be updated to the latest MSVC 2017 update? https://llvm.org/docs/GettingStartedVS.html#software says "Visual Studio 2017 or higher, with the latest Update installed", but I could also see us wanting to support any VS 2017 release if possible.

If we want to support all updates of VS 2017 I can just substitute in the old definition of llvm::TypeIndex in place of the new llvm::FirstIndexOfType, but I might have to think more about how to work around this in llvm::TypesAreDistinct

I'd generally be happy to stick with the original requirement. @stella.stamenova - any chance you could update the bot(s) here?

This seems like a bug in parameter pack expansion in older versions of MSVC, compare 19.10 https://godbolt.org/z/TMd3K8WoK with 19.14 https://godbolt.org/z/9c9TT8bnb

@stella.stamenova is there any possibility the build bots could be updated to the latest MSVC 2017 update? https://llvm.org/docs/GettingStartedVS.html#software says "Visual Studio 2017 or higher, with the latest Update installed", but I could also see us wanting to support any VS 2017 release if possible.

If we want to support all updates of VS 2017 I can just substitute in the old definition of llvm::TypeIndex in place of the new llvm::FirstIndexOfType, but I might have to think more about how to work around this in llvm::TypesAreDistinct

I'd generally be happy to stick with the original requirement. @stella.stamenova - any chance you could update the bot(s) here?

I can update these two buildbots (mlir and lldb). I am not sure whether there are other Windows buildbots that were affected and if they can be updated since we don't own them. I'll let you know once they are updated.

@dblaikie @scott.linder I updated VS on both the mlir and lldb windows buildbots (from 15.9.30 to 15.9.36), but this update does not have an update to the compiler and indeed the compiler version was already `Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27045```. You can see from the logs of the broken builds as well:

-- The C compiler identification is MSVC 19.16.27045.0
-- The CXX compiler identification is MSVC 19.16.27045.0

I think the issue is rather C++ 14 vs. C++ 17. It is my understanding that C++ 14 is required for LLVM, but not C++ 17, is that the case?

@dblaikie @scott.linder I updated VS on both the mlir and lldb windows buildbots (from 15.9.30 to 15.9.36), but this update does not have an update to the compiler and indeed the compiler version was already `Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27045```. You can see from the logs of the broken builds as well:

-- The C compiler identification is MSVC 19.16.27045.0
-- The CXX compiler identification is MSVC 19.16.27045.0

I think the issue is rather C++ 14 vs. C++ 17. It is my understanding that C++ 14 is required for LLVM, but not C++ 17, is that the case?

That's my understanding too, but even adding /std:c++14 to the command-line doesn't cause the failure, at least on godbolt: https://godbolt.org/z/zPTGjMsKa

I'm not sure what to make of it now, and I'm not particularly familiar with Windows or MSVC. I'm still amenable to changing the code, but I also fear the changes I made won't actually fix the issue as I am only testing on godbolt. Is there any shortcut to testing with the Windows buildbots? Or do I have to install Windows somewhere and try to reproduce it?

I'm not sure what to make of it now, and I'm not particularly familiar with Windows or MSVC. I'm still amenable to changing the code, but I also fear the changes I made won't actually fix the issue as I am only testing on godbolt. Is there any shortcut to testing with the Windows buildbots? Or do I have to install Windows somewhere and try to reproduce it?

There is no way to test on the official buildbots, you'd have to install Windows. If you have a change that's ready to test, I could run it locally for you.

I'm not sure what to make of it now, and I'm not particularly familiar with Windows or MSVC. I'm still amenable to changing the code, but I also fear the changes I made won't actually fix the issue as I am only testing on godbolt. Is there any shortcut to testing with the Windows buildbots? Or do I have to install Windows somewhere and try to reproduce it?

There is no way to test on the official buildbots, you'd have to install Windows. If you have a change that's ready to test, I could run it locally for you.

Yes, if you could test a change for me I would greatly appreciate it! It would save me a lot of headache

The current diff of this review is what I believe should work on any version of MSVC with /std:c++14

Could you run test the current diff and let me know the results? Thank you!

Rebase and fix uses in PointerUnion.h

@stella.stamenova do you still think you'd be able to test this before it lands, to see if the current version of the patch works on the MSVC build bots?

If not, would it be reasonable for me to land it and revert if it causes issues?

scott.linder added a comment.EditedJun 29 2021, 1:34 PM

This seems like a bug in parameter pack expansion in older versions of MSVC, compare 19.10 https://godbolt.org/z/TMd3K8WoK with 19.14 https://godbolt.org/z/9c9TT8bnb

@stella.stamenova is there any possibility the build bots could be updated to the latest MSVC 2017 update? https://llvm.org/docs/GettingStartedVS.html#software says "Visual Studio 2017 or higher, with the latest Update installed", but I could also see us wanting to support any VS 2017 release if possible.

If we want to support all updates of VS 2017 I can just substitute in the old definition of llvm::TypeIndex in place of the new llvm::FirstIndexOfType, but I might have to think more about how to work around this in llvm::TypesAreDistinct

I'd generally be happy to stick with the original requirement. @stella.stamenova - any chance you could update the bot(s) here?

Would you mind taking a look at the current diff and seeing if it is acceptable? I am fairly confident this will work with any reasonably modern MSVC, and I don't think there is a substantial hit to readability. There may be some compile-time performance cost, but I don't know how to quantify it.

Edit - meant to direct this to @dblaikie, but of course I would also appreciate feedback from anyone!

Ping, @dblaikie are you OK with the patch as-is? I think it is likely not worth the effort of tracking down what MSVC configurations will accept the constexpr version.

dblaikie accepted this revision.Nov 9 2021, 2:23 PM

Ping, @dblaikie are you OK with the patch as-is? I think it is likely not worth the effort of tracking down what MSVC configurations will accept the constexpr version.

Fair enough. I really don't like to workaround unknown issues (ends up with a form of "fear based programming" - "let's not write code that looks like that because there are issues /somewhere/ in there" - haunted graveyards ( https://www.usenix.org/sites/default/files/conference/protected-files/srecon17americas_slides_reese.pdf ) , etc) - so I think there's significant value in figuring out exactly what the limitations are/what's being worked around - but I won't insist on it.

This revision is now accepted and ready to land.Nov 9 2021, 2:23 PM

Ping, @dblaikie are you OK with the patch as-is? I think it is likely not worth the effort of tracking down what MSVC configurations will accept the constexpr version.

Fair enough. I really don't like to workaround unknown issues (ends up with a form of "fear based programming" - "let's not write code that looks like that because there are issues /somewhere/ in there" - haunted graveyards ( https://www.usenix.org/sites/default/files/conference/protected-files/srecon17americas_slides_reese.pdf ) , etc) - so I think there's significant value in figuring out exactly what the limitations are/what's being worked around - but I won't insist on it.

I wholeheartedly agree, but I think it will require (trivially) reproducible developer builds for all supported configurations to make that possible. As it stands, I can't access the builds which reproduce the failure, and my attempts at reproducing it with what I do have access to haven't amounted to anything :(

Thank you for the leeway, I won't make a habit of asking for it

This revision was landed with ongoing or failed builds.Dec 15 2021, 11:26 AM
This revision was automatically updated to reflect the committed changes.