Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not allocate vtable slots to consteval functions #83

Merged
merged 1 commit into from Feb 24, 2020

Conversation

zygoloid
Copy link
Contributor

@zygoloid zygoloid commented Jun 27, 2019

Also clarify that deleted functions do get assigned vtable slots (even though they don't need them), and consolidate three different places and ways in which we enumerate the same set of rules for which functions get vtable slots and when a return type adjustment is necessary, so that we only need to say "non-consteval" in one place.

In passing, fix missing description of where and how to allocate vtable slots to implicit assignment operators (which might override a virtual assignment operator declared in a base class).

Fixes #82

@zygoloid
Copy link
Contributor Author

zygoloid commented Jun 27, 2019

abi.html Outdated Show resolved Hide resolved
Also clarify that deleted functions do get assigned vtable slots (even though they don't need them), and consolidate three different places and ways in which we enumerate the same set of rules for which functions get vtable slots and when a return type adjustment is necessary, so that we only need to say "non-consteval" in one place.

Fixes itanium-cxx-abi#82
@rjmccall
Copy link
Collaborator

No further comment after a month; accepting.

@rjmccall rjmccall merged commit 4b9636f into itanium-cxx-abi:master Feb 24, 2020
@jicama
Copy link
Contributor

jicama commented Jun 30, 2020

I note that clang trunk crashes on this testcase because it still allocates a slot to f().

Avoiding the slot allocation seems like a lot of complication for a feature of minimal utility; what if we allocate a slot normally and just leave it null or pointing to something like __cxa_pure_virtual if we actually write out the vtable?

`
struct A
{
virtual consteval int f() const { return 1; };
};

struct B: A
{
virtual consteval int f() const { return 2; };
virtual void g() { }
};

consteval int f()
{
const A& ar = B();
return ar.f();
}

static_assert (f() == 2);

B b;
`

zygoloid added a commit to llvm/llvm-project that referenced this pull request Jul 1, 2020
For the Itanium C++ ABI, this implements the rule added in
itanium-cxx-abi/cxx-abi#83

For the MS C++ ABI, this implements the direction that seemed most
plausible based on personal correspondence with MSVC developers, but is
subject to change as they decide their ABI rule.
@rjmccall
Copy link
Collaborator

rjmccall commented Jul 2, 2020

I think it's fine to revisit this decision since it looks like nobody has adopted it until recently. @zygoloid, thoughts?

I personally agree with the committed design here: consteval virtual declarations shouldn't add any runtime overhead beyond the fact that the type is required to become polymorphic. I wouldn't expect this to be difficult for implementations. Most of the complexity of the ABI patch here is actually clarifying existing rules.

@zygoloid
Copy link
Contributor Author

zygoloid commented Jul 5, 2020

It seems wasteful to me to allocate a vtable slot that we're never going to use. The other case where we do that (for =delete virtual functions) is a feature that I understand to be explicitly intended to support reserving vtable slots for ABI-compatible extension / retraction of virtual functions, but that's not the case here. The binary size cost of vtables is measurable and important for some applications (particularly the cost of relocations and symbol table entries). Also, the purpose of consteval is to state "code must not be generated for this", and extending that to vtables doesn't seem entirely unreasonable.

That said, I agree with @jicama that this feature is unlikely to ever be widely used and the costs listed above should be considered largely theoretical (and also not fully applicable to this case), so it's probably not worth exchanging a large amount of implementation complexity for it. I went ahead and implemented this in Clang (for both Itanium and, after discussion with some MS folks, the MS ABI), and it was largely straightforward for us, so I suppose the question is just how much implementation complexity we're talking about here. I could imagine this being a bit annoying to support for an implementation whose constant evaluation model works on a lowered representation that operates in terms of vtable accesses; is that the concern?

One other thought: do we consider changing a function from being virtual consteval to being virtual constexpr to be a plausible change, that we would want to permit as an ABI-compatible change if made simultaneously for the declaration and all overriders -- in much the same way that changing from virtual =delete to virtual-but-not-deleted can be done as an ABI-compatible change? If so, I think that would argue strongly in favor of reserving a vtable slot, and adding a __cxa_consteval_virtual entry point for such a slot to optionally invoke. I don't think this seems worth supporting, but perhaps there are use cases for virtual consteval that would motivate this kind of flexibility?

@jicama
Copy link
Contributor

jicama commented Jul 6, 2020 via email

@daveedvdv
Copy link

daveedvdv commented Jul 6, 2020 via email

@jicama
Copy link
Contributor

jicama commented Jul 6, 2020 via email

arichardson pushed a commit to arichardson/llvm-project that referenced this pull request Jul 8, 2020
For the Itanium C++ ABI, this implements the rule added in
itanium-cxx-abi/cxx-abi#83

For the MS C++ ABI, this implements the direction that seemed most
plausible based on personal correspondence with MSVC developers, but is
subject to change as they decide their ABI rule.
mem-frob pushed a commit to draperlaboratory/hope-llvm-project that referenced this pull request Oct 7, 2022
For the Itanium C++ ABI, this implements the rule added in
itanium-cxx-abi/cxx-abi#83

For the MS C++ ABI, this implements the direction that seemed most
plausible based on personal correspondence with MSVC developers, but is
subject to change as they decide their ABI rule.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

need ABI update for consteval virtual functions
4 participants