cgen: fix redundant initialization of temporaries #896
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 thedeclaration, and optionally (indicated by the
needsInit
parameter)default-initializes the location.
Redundant initializations
destination location is empty (
fixupCall
/genClosureCall
; thishappens, for example, for
f(rvoCall())
), the created temporary wasinitialized. This is redundant, however, as the called procedure is
responsible for resetting the result location (if needed)
expected (
fixupCall
), the temporary was initialized, but this isunnecessary, as its immediately assigned to after
(
genObjConst
; happens, for example, forf(Obj(...)))
, the typeheader fields were initialized twice. This is because
getTemp
callsconstructLoc
, which by default always initializes type headersIn addition,
constructLoc
(which was unconditionally used bygetTemp
) 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 plusthe
constructLoc
call are removed fromgetTemp
; its usage sites arenow responsible for initializing the temporary. The
isTemp
parameterfor
constructLoc
is also not needed anymore and is thus removed.All usage sites of
getTemp
are audited for whether they rely on theinitialization of scalars or type fields previously performed by
getTemp
, but none does.