|
Message-ID: <20130827142159.GQ20515@brightrain.aerifal.cx> Date: Tue, 27 Aug 2013 10:21:59 -0400 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: Re: Optimized C memset On Tue, Aug 27, 2013 at 11:50:40AM +0200, Jens Gustedt wrote: > Am Dienstag, den 27.08.2013, 05:17 -0400 schrieb Rich Felker: > > So far, my experience is that compilers which advertise themseleves as > > "GNU C" compilers have all the semantic features of GCC 3 at the very > > least. Is this an invalid assumption? > > for gcc versions less than 4, probably, I don't remember an exception > for that. For version in the 4, there are several such examples. I just checked and confirmed that cparser/libfirm and pcc both support the may_alias attribute. I would assume clang does. > > > To make this easier to maintain, I'd suggest to introduce a special > > > feature test macro, something like __has_may_alias__, and have that > > > set at the beginning of the file in a section that is clearly > > > dedicated to compile time feature detection. Other compilers may have > > > different syntax for such a feature (a _Pragma comes in mind) and may > > > be detected quite differently than by gcc version numbering. > > > > Where would you suggest it be added? The result of the check is only > > used in one place, so I don't see how > > > I'd wouldn't have an #else case to the detection but do > > #ifndef may_alias > # if 100*__GNUC__+__GNUC_MINOR__ >= 302 > # define may_alias __attribute__((__may_alias__)) > # endif > #endif > > #ifdef may_alias > # define __has_may_alias__ > #else > # define may_alias > #endif > > This is not much more complicated than what you have and makes it easy > to add other cases, without having to maintain the __has_may_alias__ > feature macro itself. At this point, __has_may_alias__ is not used for anything. So I fail to see how the above is any different from what I wrote in the source file. > > If on the other hand you're suggesting that I should be more > > conservative and check not just for __GNUC__, but also for the > > availability of __may_alias__, in the actual code body (rather than > > just the typedefs), then it may make more sense. > > yes, I thought in these lines. that code should be handled well by any > modern compiler that you can convince to not playing games with > aliasing, here. So the fact that you tested it with gcc-like compilers > is merely an artefact. If you're saying testing __has_may_alias__ rather than __GNUC__ buys us more portability, I don't see a reason to believe this. A hypothetical non-GNUC compiler might need an actual pointer variable (rather than cast through a pointer type with may_alias on it) to avoid the aliasing violation, or it might require a special attribute on the function indicating that the whole function has immunity from the aliasing rules, or any number of other possibilities. The general approach in musl to these sort of things (compiler and machine dependency) is not to design around some hypothetical abstract level of generality, but to be general to all known existing targets, and adapt to increase generality only when needed. (And, whenever possible, have a 100% portable fallback that relies on nothing compiler- or machine-specific.) The logic for accessing the libc struct in src/internal/libc.h is the best example of this approach. I guess what I'm saying is that I don't want more complex ifdeffery to support optimizations on some hypothetical non-GCC compiler that does may_alias in a way different from GCC, unless such a compiler actually exists, since any "solution" we try to make now to the problem of additional generality might not even solve the problem if/when such a compiler exists. > > > Such specific feature test macros is the way that clang goes, and from > > > my experience this is much easier to maintain and to understand when > > > you stumble on such #ifdef'ed code. You not only know that this needs > > > a special version of a compiler, but also for what reason. > > > > Oh, I agree it's much cleaner. Sadly, though, GCC doesn't seem to give > > us that information... > > yes, for gcc you'd always have to detect features in the way you are > doing it know. But I'd think that feature detection should be > separated from the use of the features. The uses might be spread over > several places, but the detection should be done in one well > detectable spot in the source code. The trade-off is between some duplication of the logic for which version of the code can be used, and added barrier to reading the code. One of the things I think our users like about musl versus glibc is that, for the vast majority of the code, you can fully determine what it's doing without reading other implementation-specific files that define magic macros for things you might not understand -- and that you can take the code and drop it into another project without having to find all the implementation-internal headers it depends on. If something needs to be changed about the logic for may_alias, a simple grep -r will find all the source files it's in and makes it easy to change several occurrences. So I tend to think preserving readability and ease of reuse are more important than avoiding duplication, but if others agree with you, I wouldn't be entirely opposed to adding a "string_impl.h" or similar header with some shared preprocessor logic for all of the string functions that might be doing sketchy things with aliasing and alignment. I'd appreciate comments on this matter from others on which way we should go. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.