Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cgen: fix redundant initialization of temporaries (#896)
## Summary Fix multiple places in the C code generator where temporaries inserted by the C code generator (and not earlier) were redundantly initialized twice. While this is unlikely to have an impact on the performance of the generated binaries, it nonetheless reduces the pressure on the C compiler's optimizer, reduces the amount of work for the NimSkull compiler, and also leads to the C artifacts becoming a bit smaller. ## Details The C code generator creates new temporary variables itself, usually for the purpose of upholding evaluation order expectations. It allocates them through `cgen.getTemp`, which allocates a name, emits the declaration, and optionally (indicated by the `needsInit` parameter) default-initializes the location. ### Redundant initializations * for calls that use the return-value optimization and where the destination location is empty (`fixupCall`/`genClosureCall`; this happens, for example, for `f(rvoCall())`), the created temporary was initialized. This is redundant, however, as the called procedure is responsible for resetting the result location (if needed) * for potentially-raising calls that require a temporary to behave as expected (`fixupCall`), the temporary was initialized, but this is unnecessary, as its immediately assigned to after * for object constructions where the destination locations is empty (`genObjConst`; happens, for example, for `f(Obj(...)))`, the type header fields were initialized twice. This is because `getTemp` calls `constructLoc`, which by default always initializes type headers In addition, `constructLoc` (which was unconditionally used by `getTemp`) always assigned the zero value to non-complex locations (ints, floats, pointers, seqs, etc.), even if `hasTemp` is false, causing many redundant assignments. ### Improved handling Apart from the aforementioned places where setting `needsInit` to 'true' was unnecessary, there was only a single place where the `needsInit` parameter was used (`cgen.resetLoc`). Therefore, the parameter plus the `constructLoc` call are removed from `getTemp`; its usage sites are now responsible for initializing the temporary. The `isTemp` parameter for `constructLoc` is also not needed anymore and is thus removed. All usage sites of `getTemp` are audited for whether they rely on the initialization of scalars or type fields previously performed by `getTemp`, but none does.
- Loading branch information