This is an archive of the discontinued LLVM Phabricator instance.

[AST] Stuff more data into FunctionTypeBitfields
AbandonedPublic

Authored by riccibruno on Aug 13 2018, 4:01 AM.

Details

Summary

Since FunctionTypeBitfields is already > 32 bits wide we might
as well stuff the remaining bits from FunctionProtoType into it.

The patch is very mechanical, but changes the maximum number of
parameters from 2^15-1 to 2^14-1 to fit into FunctionTypeBitfields,
This requires stealing 2 bits from the number of types in a dynamic
exception spec. The maximum number of types in a dynamic exception
spec is therefore limited to 127 (unless limited by something else in clang).

Also the member unsigned RefQualifier : 2; is moved in
FunctionTypeBitfields. This is intentional and done to avoid
the unsigned boundary.

Diff Detail

Repository
rC Clang

Event Timeline

riccibruno created this revision.Aug 13 2018, 4:01 AM
erichkeane added inline comments.
include/clang/AST/Type.h
1527

This concerns me a bit with variadic templates. I realize implimits says 256 but IMO variadic templates makes this a fairly easy limit to hit. I guess that 4096 is probably sufficient, though I'd like to hear someone else's opinion.

1530

IMO (and @rsmith should respond here instead), if we were looking to steal bits from anywhere, this would be it. Exception-specifications that use types ares are deprecated in the language and I'm not sure anyone ever used them anyway.

lib/AST/Type.cpp
2863

I would be unbelievably surprised if this change is worth-while. I can't see a situation where this getNumParams call doesn't get inlined.

riccibruno added inline comments.Aug 13 2018, 6:16 AM
include/clang/AST/Type.h
1530

Yes this seems a good idea. We could steal 2 bits (or more) from
here to restore the 14 bits in NumParams. I can't imagine that
someone will miss not being able to specify > 512 types
in an exception specification.

lib/AST/Type.cpp
2863

It was just for consistency with the other changes,
but perhaps it do not belongs to this patch.

riccibruno marked 5 inline comments as done.
riccibruno edited the summary of this revision. (Show Details)

Bumped the number of bits for parameters from 12 to 14,
stealing from NumExceptions. This means that now (unless
limited by something else in clang) the maximum number
of types in a dynamic exception spec is 127, and the
maximum number of function parameters is 16383.

We should absolutely have static assertions to check that these bit-field types don't get larger than 32 bits. A lot of the subclass layouts have been tweaked to fit that (packing into the tail padding of Type on 64-bit targets), so accidentally overflowing to use more bits in the base is going to lead to a lot of bloat.

@rsmith Could you comment on whether limiting the number of types
in a dynamic exception specification to 127 is acceptable ? I had
to steal two bits from NumExceptions to make all the fields fit.
If this is a bad idea then a possibility would be to put
NumExceptions in a trailing object.

Our experience is that we keep adding more complexity to FunctionType, so it'd be nice if the bits weren't pressed up against the absolute limit. Dynamic exception specifications are really common, but only in the zero-exceptions case, so as long as we can efficiently represent and detect that I think putting the rest of the count out-of-line is fine.

riccibruno planned changes to this revision.Aug 16 2018, 5:26 AM

I Will put NumExceptions in a trailing object. However it seems
that FunctionProtoType can be substantially cleaned up by converting
it to use llvm::TrailingObjects instead of manually doing the casts+arithmetic.

Therefore I plan to first convert FunctionProtoType to use llvm::TrailingObjects
and then resubmit this patch with the appropriate modifications.