Skip to content

Conversation

reactormonk
Copy link
Contributor

Works, but I'm not sure if it's a proper fix. Might break because of if d.k == locNone.

Araq added a commit that referenced this pull request Feb 9, 2014
@Araq Araq merged commit e6cdccc into nim-lang:devel Feb 9, 2014
Araq added a commit that referenced this pull request Apr 7, 2014
Clyybber pushed a commit to Clyybber/Nim that referenced this pull request Sep 16, 2023
## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants