This is an archive of the discontinued LLVM Phabricator instance.

[llvm][ADT] Make `Twine` aware of `StringLiteral`
ClosedPublic

Authored by jansvoboda11 on Aug 3 2023, 9:17 AM.

Details

Summary

The const char * storage backing StringLiteral has static lifetime. Making Twine aware of that allows us to avoid allocating heap memory in some contexts (e.g. avoid passing it to StringSaver::save() in a follow-up Clang patch).

Diff Detail

Event Timeline

jansvoboda11 created this revision.Aug 3 2023, 9:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 3 2023, 9:17 AM
jansvoboda11 requested review of this revision.Aug 3 2023, 9:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 3 2023, 9:17 AM

I could be mistaken, but I think this is the same as the std::string case -- a combination of already null-terminated (so no allocation) and having a length, so no need to strlen in the StringRef constructors.

Would it make sense to combine them into a single NullTerminatedPtrAndLength representation?

I don't think so. The use-case I'm thinking of is having a bunch of const Twine & objects and wanting to create a SmallVector<const char *> with lifetime that's independent from the strings referenced by the Twine objects (using StringSaver for example). Knowing that the Twine refers to single const char * with static lifetime would allow you to safely skip saving/allocating the string buffer. You can't skip that for std::string, since that might deallocate its buffer. Does that make sense?

benlangmuir accepted this revision.Aug 3 2023, 10:13 AM

I don't think so. The use-case I'm thinking of is having a bunch of const Twine & objects and wanting to create a SmallVector<const char *> with lifetime that's independent from the strings referenced by the Twine objects (using StringSaver for example). Knowing that the Twine refers to single const char * with static lifetime would allow you to safely skip saving/allocating the string buffer. You can't skip that for std::string, since that might deallocate its buffer. Does that make sense?

Got it, sorry I thought this commit was self-contained and you were worried about the case in toNullTerminatedStringRef which would have allocated before but now does not, but I guess you have a follow-on commit that uses this new representation? In that case, LGTM.

This revision is now accepted and ready to land.Aug 3 2023, 10:13 AM
jansvoboda11 edited the summary of this revision. (Show Details)Aug 3 2023, 10:29 AM

Yes, clarified in the patch summary. Thanks!

This revision was landed with ongoing or failed builds.Aug 3 2023, 10:53 AM
This revision was automatically updated to reflect the committed changes.

I'm confused - this patch was motivated by potential improvements to StringSaver, but https://reviews.llvm.org/D157015 says that those improvements can't be made because StringSaver must copy the data?

I'm confused - this patch was motivated by potential improvements to StringSaver, but https://reviews.llvm.org/D157015 says that those improvements can't be made because StringSaver must copy the data?

That's right. This gets used to avoid calling StringSaver in CompilerInvocation.h (D157046).