Compiler: force zero initialization of local variables
- make all local variables zero-initialized except if tagged as
@(noinit) - update tests
The generated C code creates something like this for integers:
int32_t from = { 0 };
I was surprised that this was allowed at all, but I think it would be more readable to just generate
int32_t from = 0;
and only generate braces for structs, etc
I did measure the performance and saw no change
I agree this PR needs polishing to this regard. My goal is for you to test the performance impact.
The main issue is probably the initialization of local arrays, especially if they are large. This can be avoided with the @noinit attribute, but I would prefer the analyser to be able to determine that full initialization is unnecessary.
It should easily opt out zero init, already at -O1. This works fine here at least: https://godbolt.org/z/M4sTEr5zv
It should easily opt out zero init, already at -O1. This works fine here at least: https://godbolt.org/z/M4sTEr5zv
Redundant initialization seems easy to handle.
How about this one:
module test;
import stdio local;
fn void main() {
char buf[4096];
snprintf(buf, sizeof(buf), "Hello world");
printf("%s\n", buf);
return 0;
}
That's something that would require @noinit. Note that it would not be correct to elide the implicit zeroing in this case, since the bytes not affected by snprintf will not be modified, and that might be what the programmer intended.
That's something that would require
@noinit. Note that it would not be correct to elide the implicit zeroing in this case, since the bytes not affected bysnprintfwill not be modified, and that might be what the programmer intended.
Indeed snprintf does not affect the bytes beyond offset 11, but since printf never reads them, leaving them uninitialized is a palatable optimisation. This is very similar to the case of unused local variables: I suppose C3 does not initialize them either.
It would be an optimization, but none that the compiler can do without inlining the functions. If it did, then the zero init would be removed I'm sure. Unused local variables are zero init:ed but -O1 will just remove them no problem.
It would be an optimization, but none that the compiler can do without inlining the functions. If it did, then the zero init would be removed I'm sure. Unused local variables are zero init:ed but -O1 will just remove them no problem.
I agree with this approach and that's what I would like to achieve through static analysis in many cases.