News for hackers. Stuff that matters.
Re:Why Const Doesn't Make C Code Faster by dmitrygr on Monday August 19, 2019 @05:06PM (#20741832)
gcc has some attributes to help with that, for example try __attribute__((pure)) on funcs that will always return the same thing for the same inputs (given the same global state) and do not modify said input or state (and thus can be called more or fewer times than programmer wrote). Usually gcc will be quite aggressive with optimizations if you use that.

For even more aggressiveness, try __attribute__((const)) which tells it that the func accesses NOTHING but the params, not even global vars. Of course this is quite limiting. You can also use this as a trick when YOU know that the only accessed global state is itself constant but gcc does not know that. This can produce substantial savings in number of calls of funcs that, for example, do lookups in large constant data tables, like table-based versions of sin() and cos().

In the example the article gives, adding __attribute__((pure)) to constFunc() does produce the behaviour author wanted and then some

LWN has more: https://lwn.net/Articles/285332/

Re:Why Const Doesn't Make C Code Faster by Ididntdothis on Monday August 19, 2019 @05:11PM (#20741863)
Does it enforce these attributes or are they just a promise by the code author?
Re:Why Const Doesn't Make C Code Faster by WalterBright on Monday August 19, 2019 @05:47PM (#20742126)
D has a `pure` attribute for functions, and yes it is enforced. It's enforced even to the point where it becomes a PITA, but when you manage to make functions pure, you know it's solid.

One pain point with pure functions is you can't insert debug logging statements. D has a special case for that - purity for a statement isn't checked if it is prefixed with the `debug` keyword:

    pure int square(int x) {
        debug printf("called square\n");
        return x * x;
    }
which is very, very handy.
Re:Why Const Doesn't Make C Code Faster by Ididntdothis on Monday August 19, 2019 @06:00PM (#20742219)
This seems a very pragmatic solution.
Re:Why Const Doesn't Make C Code Faster by einpoklum on Tuesday August 20, 2019 @02:37AM (#20744335)
Isn't that erroneous, in the sense that printf() has side-effects, breaking the "pure" promise?
Re:Why Const Doesn't Make C Code Faster by WalterBright on Tuesday August 20, 2019 @04:42AM (#20744892)
Indeed it does break the pure promise. But it's only for debugging builds.
Re:Why Const Doesn't Make C Code Faster by Y_Y on Tuesday August 20, 2019 @02:20AM (#20744268)
The same "trick" is especially handy in a pure-by-design language like Haskell. There you have the `trace` function which prints to stdout while pretending not to. It's similarly useful, even if it may get called zero or many times. Is the same true of D's debug?
Re:Why Const Doesn't Make C Code Faster by WalterBright on Tuesday August 20, 2019 @02:39AM (#20744346)
No, in D any statement prefixed with `debug` does not get its purity checked. `debug` prefixed code is enabled via a command line switch, otherwise it is excised.

I.e. it's for conditionally inserting debugging code where you don't care about purity, you just want to find the bug.

Re:Why Const Doesn't Make C Code Faster by SomeOldThrow on Monday August 19, 2019 @07:39PM (#20742694)
This means you can't re-order the computation, though, or memoize it—at least not the the extent it's possible without IO.
Re:Why Const Doesn't Make C Code Faster by mhh__ on Monday August 19, 2019 @08:06PM (#20742818)
The use of the debug {} block in D is opt-in e.g. the compiler only includes those statements when given the debug flag

https://d.godbolt.org/z/Rwu4Cq (remove "-d-debug" to see)

Re:Why Const Doesn't Make C Code Faster by Doxin on Thursday August 22, 2019 @05:51AM (#20766303)
Furthermore AFAIK things prefixed with debug don't get compiled into release binaries either.
Re:Why Const Doesn't Make C Code Faster by Gibbon1 on Monday August 19, 2019 @07:41PM (#20742699)
I wonder does that mean you could also enforce freeing memory allocated by a pure function as well?
Re:Why Const Doesn't Make C Code Faster by mhh__ on Monday August 19, 2019 @07:59PM (#20742785)
I'm not sure what you mean?

Allocators are often pure in D, they probably shouldn't be but that would mean allocating outside the function which would be ugly and probably buggy too

Re:Why Const Doesn't Make C Code Faster by Gibbon1 on Monday August 19, 2019 @08:14PM (#20742862)
Obviously a pure function can allocate memory on the stack. I would think it could also allocate memory on the heap, iff it was guaranteed that the memory was freed before the function exits. Was thinking that would be something the compiler would do.

Forgive me I'm just a small brained firmware programmer.

Re:Why Const Doesn't Make C Code Faster by ricattierger on Tuesday August 20, 2019 @02:31AM (#20744312)
So it seems that you are sort of talking about a function that is memoizable but not pure. Pure has no mutation of any global state. So hypothetically touching the heap means not pure - if somehow others can see it.
Re:Why Const Doesn't Make C Code Faster by boomlinde on Tuesday August 20, 2019 @05:09AM (#20745003)
So where do we draw the line? Of course, no real computer implementation of any language is going to be able to generate fundamentally pure code because in the end they're going to be mutating memory (at the very least the program counter).

That's not a very useful distinction, and usually one talks about "purity" at a conceptual level. The language provides a layer of abstraction in which things can be considered pure (or not), even if the underlying implementation e.g. makes optimizations that require mutation. The language is just a guarantee that you can ignore these aspects of its implementation.

Re:Why Const Doesn't Make C Code Faster by ricattierger on Tuesday August 20, 2019 @10:39AM (#20747498)
I think that is a good point at the end. Pure may be defined in regards to the language. So allocating memory in C may make a function unpure but something other languages may still be pure.
Re:Why Const Doesn't Make C Code Faster by Gibbon1 on Tuesday August 20, 2019 @09:04PM (#20753789)
Rolling it over I think vaguely along the idea that marking a function as pure is a contract that tells the compiler that the function and it's call tree ultimately shouldn't modify external state.

A function that allocates memory isn't pure, except perhaps iff it frees that memory either itself or by compiler magic. Then perhaps it is.

Re:Why Const Doesn't Make C Code Faster by dmitrygr on Monday August 19, 2019 @05:19PM (#20741929)
They are a promise and that is precisely what makes them powerful. It gives GCC info it might not be able to derive, but you know to be true.

You can even promise a func is pure without even implementing it in the same translation unit! That produces lots of improvement. See these two godbolt links:

https://godbolt.org/z/v2zqJI

https://godbolt.org/z/kk3Q3T

Re:Why Const Doesn't Make C Code Faster by einpoklum on Tuesday August 20, 2019 @02:38AM (#20744342)
> You can even promise a func is pure without even implementing it in the same translation unit!

Actually that's the main point, as if it's in the same TU, the compiler can probably figure out a function is pure.

Re:Why Const Doesn't Make C Code Faster by dmitrygr on Tuesday August 20, 2019 @04:38PM (#20751830)
often but not always, for example a function using asm() to access, say, some AES intrinsics is pure (const even) since the output only depends on input, but oftentimes compiler by itself will not declare a function with an asm() block pure or const
Re:Why Const Doesn't Make C Code Faster by einpoklum on Tuesday August 20, 2019 @05:22PM (#20752329)
Well, fair point, but - compilers shouldn't be that lazy :-)
Re:Why Const Doesn't Make C Code Faster by pingyong on Tuesday August 20, 2019 @05:11AM (#20745009)
>__attribute__((const)) which tells it that the func accesses NOTHING but the params, not even global vars.

If you're actually not accessing any global state at all (including making no memory allocation), shouldn't the compiler figure that out anyway? That doesn't seem like something that would be very hard to check for.

Re:Why Const Doesn't Make C Code Faster by gpderetta on Tuesday August 20, 2019 @05:59AM (#20745207)
Not if it is defined in another translation unit and you are not using LTO.
Re:Why Const Doesn't Make C Code Faster by fluffything on Tuesday August 20, 2019 @07:46AM (#20745783)
In other words, the compiler can infer this from the function definition (or at least clang does), but it cannot infer this from a function declaration, because the implementation is missing - unless you are using LTO like the parent mentions.
Re:Why Const Doesn't Make C Code Faster by dmitrygr on Tuesday August 20, 2019 @04:35PM (#20751793)
sometimes it cannot infer it even from function, for example, here is a function that in my particular OS gets me a pointer to my library's globals. To my code the returned pointer never changes, but the compiler has NO way to tell this function is const without my annotation

  void* __attribute__((const)) getGlobals(void) {
    void* ret;

    asm (
      " ldr %0, [r9]      \n"
      " ldr %0, [%0, %1]  \n"
      : "=r"(ret)
      : "I"(MY_MODULE_ID)
      :
    );
    return ret;
  }
Re:Why Const Doesn't Make C Code Faster by gpderetta on Tuesday August 20, 2019 @10:18PM (#20754068)
Good point.
Re:Why Const Doesn't Make C Code Faster by egdod on Monday August 19, 2019 @09:29PM (#20743141)
> try __attribute__((const)) which tells it that the func accesses NOTHING but the params, not even global vars

And it doesn’t do anything unintended if you’re lying to it by accessing the global state that you know to be constant?

Re:Why Const Doesn't Make C Code Faster by dmitrygr on Monday August 19, 2019 @09:43PM (#20743197)
It will only assume that it is safe to skip multiple calls to this function with the same parameters, safe to generate extra calls that you did not write, and safe to skip the entire call if the return value is ignored