[clang] [Clang] Improve EmitClangAttrSpellingListIndex (PR #114899)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 7 06:35:16 PST 2024
erichkeane wrote:
> Hi @erichkeane, thanks for your detailed review and comments.
>
> I had some thoughts about your optimized approach which I would like to share.
>
> I agree that falling back to full string comparisons is "safe" but non-optimal. However, performing "first different character" comparison might get complicated if you have more than 2 different spelling names with the same size.
>
> An example case is `AT_NoSanitizeSpecific` with - "no_sanitize_thread" and "no_sanitize_memory" (size 18). In this case it is easy to check for the differing character by using `std::mismatch`. However, a case where there are 3 such strings (like "aaaba", "aaacb", "aaabc") would involve generation of a much more complex conditional. Although rare, I'm not sure if we can ignore this situation. We may sacrifice readability of the emitter code / debuggability of the `.inc` file at the cost of minimal optimizations (full string comparisons now happen in only 6 cases).
>
> I'm happy to add the FIXME note, but would like to hear what you think.
So the conditional actually doesn't have to be all that difficult. You need N-1 comparisons to differentiate (though you m ight end up with duplicates). For example, in your 3 strings example if differentiating the first one, my algorithm would generate Str.size() == 5 && Str[3] == 'b' && Str[3] == 'b' (since that is the difference character for each). It is simple enough join with an 'and' and a loop, as long as we don't care about duplicates.
As far as debugability/readability of emitted code: it isn't really a concern here. Once we get the tablegen 'right' (which traditionally doesn't take much effort/testing), no one ever gets into here again. The spelling-identification one uses a trie, and it is a giant mess of undebugability :)
>
> To address a previous comment -
>
> > This seems to have missed a bunch, see alloc_size and allocating and alloc_align, all of which are the same spellings, but you're checking the name anyway (in the .inc file you linked).
>
> I'm confident that my earlier approach did not perform string comparisons for "alloc_size", "allocating" and "alloc_align". The 2 tests that were failing were because I assumed that spellings with the same name would have consecutive indices. This failed for `AT_unused`. But I concede that the earlier loop did not leverage the `.size()` for a more optimal comparison :) This way is definitely better.
>
Got it! It wasn't clear based on the old implementation what was happening, just from the GIST that something wasn't working.
> [Gist](https://gist.github.com/chinmaydd/1733a9a84932a45678c47f31be4d64d7) contains updated output.
That GIST looks about right. I see as you mentioned, ~6 different comparisons, which isn't too bad. Definitely an improvement.
https://github.com/llvm/llvm-project/pull/114899
More information about the cfe-commits
mailing list