On Thursday, 31 July 2014 at 10:14:06 UTC, Marc Schütz wrote:
On Thursday, 31 July 2014 at 08:23:44 UTC, Daniel Murphy wrote:
"Daniel Murphy" wrote in message news:[email protected]...

> Wait, what? I thought the whole point of enforce is that it > will *not*
> be removed by the compiler, no matter what?

No, the compiler is free to remove it if it can prove it will never be triggered. eg if the condition is checking a ubyte < 1000. If the assert in that example is never false, then the enforce is dead code.

Actually, thinking about this some more...

In this program the enforce can be removed

assert(x < y);
enforce(x < y);

But not in this one:

enforce(x < y);
assert(x < y);

because the compiler does need to take control flow into account when applying the information in the assert. In this case the assert does not actually give the compiler any new information.

No, if assert means "I promise that x < y where assert() is called", then "x < y" also holds when "enforce()" is called, because x and y cannot have changed between the two calls.

I think this is the biggest problem with optimizing whilst removing the check. It seems like if you remove the check and assume that the check was true then you get really wonky stuff like checks before the assert being removed.

One solution that would still provide some optimization benefits is to make the optimizations as if the check is still their. Meaning that only things after the assert could be optimized based on the contents of the assert.

I think that is an extension of what Daniel is saying. The assert optimization needs to take into account control flow, but It needs to take into account its own control flow as well(even if the control flow is not actually inserted).

so...

enforce(x);
assert(x);

would not remove the enforce.... because the x would only be known to be true after the assert because of the check in assert, even if the check is not added it would optimize as if it was added.

Reply via email to