Announcement

Collapse
No announcement yet.

Fedora 29 Might Make Change To Eliminate Unnecessary Linking

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Weasel
    replied
    Originally posted by F.Ultra View Post
    Well that really does make no sense, in fact every C compiler must already support an internal norestrict since "char *" and "unsigned char *" are allowed to alias any other pointer according to the specifications and thus are already hardwired to be norestrict. restrict however might introduce some headache in a C++ world with all the overloading etc that they do there but I cannot make any informed opinion there since I'm not a C++ programmer and know far too little of the language.
    restrict is a so-called "top level" qualifier in most cases, so overloading doesn't really apply.

    Top-level means stuff like "const int", which applies to the type itself, unlike "const int*" which applies to what it points to. A top-level constant pointer is "int* const" in this case. Such top-level qualifiers cannot be overloaded against, so you can't overload based on "int*" and "int* const". Same with restrict (restrict applies to the pointer, not to what it points to).

    Even in C you can define new types, with struct (C++ is much more powerful here though), so even a C compiler has to disambiguate this way anyway (not for overloading, but the type-based alias analysis needs to be able to handle "custom types").

    Note that "may_alias" attribute applies to the underlying type, confusingly. Don't know why, lol. So you need to apply it to the "int" in the previous case, not to the pointer!

    Leave a comment:


  • F.Ultra
    replied
    Originally posted by coder View Post
    What I've heard (don't know if it's true, or just speculation) about the C++ committee's rejection of restrict is that they thought it was too easy to misuse and break your program in unpredictable and hard-to-find ways.

    It seems to me that argument would apply even more-so to relaxing alias analysis requirements even further.
    Well that really does make no sense, in fact every C compiler must already support an internal norestrict since "char *" and "unsigned char *" are allowed to alias any other pointer according to the specifications and thus are already hardwired to be norestrict. restrict however might introduce some headache in a C++ world with all the overloading etc that they do there but I cannot make any informed opinion there since I'm not a C++ programmer and know far too little of the language.

    Leave a comment:


  • Weasel
    replied
    Originally posted by coder View Post
    Kind of like intptr_t, which is defined in unistd.h as a sort of short cut for having a union with both an int and pointer member?
    Sort of but not exactly. intptr_t can be used to reinterpret the value of a pointer as an integer, but you still shouldn't "write" to a pointer's value via a intptr_t, it will still have aliasing issues.

    intptr_t is not a union, it's just an integer typedef that's guaranteed to be at least the same size as a pointer (e.g. int32_t when sizeof(void*)==4, int64_t when sizeof(void*)==8, etc). It can be useful in many cases like, for example, when implementing a double-linked list storing only one next/prev field being the XOR of them, or when aligning pointers (doing bitwise AND on the intptr_t and then back to pointer), etc.

    Originally posted by coder View Post
    What I've heard (don't know if it's true, or just speculation) about the C++ committee's rejection of restrict is that they thought it was too easy to misuse and break your program in unpredictable and hard-to-find ways.

    It seems to me that argument would apply even more-so to relaxing alias analysis requirements even further.
    Well that was for the C committee, and besides, norestrict cannot break anything, all it can do is hinder some optimizations. But it can't "break" anything no matter how it's used.

    restrict can, though, but honestly, I couldn't care less of the C++ committee's stupid opinions. Nobody forces anyone to use restrict, who do they think they are, every C++ programmer's mom or what? To decide that something is too dangerous as an option? As if C++ programmers can't decide for themselves. Committee needs to fuck off, really pissing me off with their audacity.

    But at least GCC supports it as an extension, which is good. So this isn't a big deal to me. Still wish the committee would treat other programmers as equals when it comes to their own responsibility than thinking they're their parents trying to hand-hold them.
    Last edited by Weasel; 25 July 2018, 08:37 AM. Reason: intptr_t is signed, corrected typedefs

    Leave a comment:


  • coder
    replied
    Originally posted by F.Ultra View Post
    However what we really need is the reverse of 'restrict' and for compiler optimizations it would be even better to be able to define which of your different pointers that actually can alias instead of the half way GCC solution where every instance of your type will be seen as aliasable.
    What I've heard (don't know if it's true, or just speculation) about the C++ committee's rejection of restrict is that they thought it was too easy to misuse and break your program in unpredictable and hard-to-find ways.

    It seems to me that argument would apply even more-so to relaxing alias analysis requirements even further.

    Leave a comment:


  • coder
    replied
    Originally posted by Weasel View Post
    With typedefs I meant adding some sort of common base header where you make typedefs for basic types, call them something like uint32_tA (or whatever, A being 'alias', up to you), and of course for your own types (structs) you'd have to do it though. The capitalization is not necessary but it's easier to read (?) and probably won't conflict with anyone else's header...
    Kind of like intptr_t, which is defined in unistd.h as a sort of short cut for having a union with both an int and pointer member?

    Leave a comment:


  • Weasel
    replied
    Originally posted by F.Ultra View Post

    They might have improved on it in later GCC:s, I'm currently stuck on 5.4.0 due to Ubuntu 16.04LTS and there it's only supported via typedefs. While typedefs works it's #1 ugly as sin and #2 not portable. Unfortunately even Linus Torvalds didn't succeed back in 1999 to get the C standards committee to add a "norestrict" keyword, I recommend to read the entire mail chain from this link for any one interested in the issue https://yarchive.net/comp/norestrict.html

    Too bad that there actually exists people on that usenet group that responds "well use memcpy() and hope that your compiler optimizes it away" as a rationale for not adding "norestrict" :-)
    I wasn't aware that Linus tried to push for it. I have a long hatred for standards bodies (not just C, but also C++), it's clear they are biased to what they consider "the workflow". This is one of those examples where I absolutely hate them for it. memcpy is not a freaking solution, even if it's optimized away, because it's ugly as hell, and the resulting code is a mess, especially if you do it a lot. So I fully agree about the memcpy approach being a retarded "workaround".

    With typedefs I meant adding some sort of common base header where you make typedefs for basic types, call them something like uint32_tA (or whatever, A being 'alias', up to you), and of course for your own types (structs) you'd have to do it though. The capitalization is not necessary but it's easier to read (?) and probably won't conflict with anyone else's header...

    Leave a comment:


  • F.Ultra
    replied
    Originally posted by Weasel View Post
    Uhm, no, you don't have to go out of your way to not check for stuff. You're asking GCC to add extra checks for situations like this, which is a completely different thing and by no means "going out of your way" to break it on purpose. It's them not wanting to do it to satisfy people who won't code properly.

    Mind you, this check was already added, for different reasons (other optimizations when it's the same type). But it simplifies the compiler and makes it compile far faster if it can confirm early that these 2 memory references will never alias, because they're different types. And indeed why should they not take advantage of it when it's undefined behavior in the first place and not documented as a compiler extension?

    I mean, it's also about intent. For instance, how would you document this behavior in the compiler? "Obvious" is not a documentation, and neither is "common sense". You have to be specific and exact in the documentation. i.e. in which situations it applies to, exactly, and so on. Needless complexity when adding an attribute makes it even more "obvious" as to the intent. If it's undefined behavior in the language, they must document it as a GCC extension and must be precise about it.
    Well I can live without the "obvious" aliasing if C-std at least added a "norestrict" keyword.

    Originally posted by Weasel View Post
    Like I said before you have no idea how compilers are internally. Adding "special cases" for code patterns like the above is not a good idea unless the result is worth it, which it is not here since it can't even be documented precisely.

    It may be obvious to YOU, but the alias oracle in GCC is pretty generic and works on the internal representations (RTL instructions or GIMPLE). In this particular case, it can keep track of what aliases on the stack as special optimizations but like i said it's faster if they just instantly assume they won't alias -- you know, aliasing checks are pretty extensive for high optimizations, you have to check each memory reference with another to see if it's a dead store or whatever. That's slow compilation, and for what? For people who want to have undefined behavior?

    It's also annoying for people who think with memory groups like me. I prefer to see explicit may_alias (or a friendly macro) because then I know it can alias. char is already annoying because it's a special exception in the language.
    Yeah, I can drop the obvious thing. But a "norestrict" would not add any overhead since GCC already must do this internally for char and unsigned char (and for any __may_alias).

    In the end I think that you and me simply work with completely different sets of data, in my line of work I have to perform type aliasing all the time due to how data is sent to my systems so just like the Linux Kernel all the typedefs and memcpy() makes the code ugly and harder to read (and readability is important) while the optimization gains on x86 is quite small (not like on Power where it can be huge).

    Leave a comment:


  • F.Ultra
    replied
    Originally posted by Weasel View Post
    Well the may_alias attribute is exactly that. You even use it the same way, except that it has (had?) some bugs without using a typedef, so you should probably just make some typedefs for it and be done with it. (anyway those are compiler bugs)
    They might have improved on it in later GCC:s, I'm currently stuck on 5.4.0 due to Ubuntu 16.04LTS and there it's only supported via typedefs. While typedefs works it's #1 ugly as sin and #2 not portable. Unfortunately even Linus Torvalds didn't succeed back in 1999 to get the C standards committee to add a "norestrict" keyword, I recommend to read the entire mail chain from this link for any one interested in the issue https://yarchive.net/comp/norestrict.html

    Too bad that there actually exists people on that usenet group that responds "well use memcpy() and hope that your compiler optimizes it away" as a rationale for not adding "norestrict" :-)

    Leave a comment:


  • Weasel
    replied
    Originally posted by F.Ultra View Post
    However what we really need is the reverse of 'restrict' and for compiler optimizations it would be even better to be able to define which of your different pointers that actually can alias instead of the half way GCC solution where every instance of your type will be seen as aliasable.
    Well the may_alias attribute is exactly that. You even use it the same way, except that it has (had?) some bugs without using a typedef, so you should probably just make some typedefs for it and be done with it. (anyway those are compiler bugs)

    Leave a comment:


  • F.Ultra
    replied
    Originally posted by coder View Post
    If you're happy with it only working in such trivial cases, and then mysteriously breaking when some internal threshold is crossed or heuristic is broken, well, let's say I don't share that position.
    Yes that would of course be a problem but for that to happen you would have to do say dynamic adds to a pointer so it suddenly goes into an area covered by another pointer since static increments/decrements is easy for the compiler to track. clang+icc+vcc (and that vcc have managed to do this while being the crappiest C compiler in history is telling) have managed to not create breakage here.

    However what we really need is the reverse of 'restrict' and for compiler optimizations it would be even better to be able to define which of your different pointers that actually can alias instead of the half way GCC solution where every instance of your type will be seen as aliasable.

    Leave a comment:

Working...
X