the TiAlloc() and TiFree() code path.
The rationale of the changes:
Performing the one-time initialization check (first call to
mmapTileStore()) for every TiAlloc() is unnecessary if the decision code
is reworked to allow NULL pointers to exist in the computation and still
make the correct decision.
Use of 'unsigned long' for pointer arithmetic is not compatible with _WIN64
compiler model LLP64. Changed to 'pointertype'.
The computations addition/subtraction/greater-than were performed
multiple times. Seemed a convoulted method when a single operation
should be good enough.
The use of a single-linked-list with HEAD and TAIL does not make sense.
My gut is telling me that for the purpose of memory allocation a LIFO is
better as a free-and-reuse of the most recently freed item is more likely
to already be in the CPU cache and the oldest freed item is more likely
to have been evicted from CPU cache. So given the use of a custom
allocator and no support to reclaim/compact or manage fragmentation
other factor didn't carry any weight.
Technically TiAlloc() returns undefined memory and the first action of
the caller is to write new values, but the point remains that write is
more likely to cause eviction of something else from cache with the
original FIFO scheme.
Due to the free list use during TiFree() there is a write to each alloc
which will make the cache-line hotter in the cache (less likely to have
been evicted) when using LIFO scheme than FIFO scheme.
Further more the use of HEAD and TAIL had a far more complex
TileStoreFree() than was necessary even for such a list. A 4 line
method turned into 7 with multiple conditions tested when branching.
The TileStoreFreeList/TileStoreFreeList_end were public symbols which may
also impact the freedom the compiler has to optimise around them.
Using LIFO single-linked-list resulted in the removal of
TileStoreFreeList_end and associated simplification.
Use of 'static' for the methods mmapTileStore() and getTimeFromTileStore()
these are not public API so adding the 'static' give the compiler a hint
these methods maybe inlined as they are not accessile from outside this
compliation unit.
The -O3 assembly result looks quite healthy in achieving the original
goal of instruction and branch reductions with the compiler able to
inline all 3 methods into a single TiAlloc().
This is reducing nearby calls to TiGetClient() API when the value
can be looked up one time and stored in a local variable to make
other decisions about.
This is due to TiGetClient() potentially having a slightly higher
cost to call than previously, this is a kind of peephole
optimization approach (if I can see multiple getters used within
the window it got optmized).
'ticlient' was used for retrieval as ClientData so that future
greps across the codebase for `ti_client` should only match naked
access.
All naked access to `ti_client` now uses the function-like-macro
to encapsulate this action. This macro existed before this just
makes all sites utilize it.
Added additional INT and PTR variants to remove the programmer
load on thinking about casing and casts polluting the point
of use. So the use now looks cleaner.
Equivalent prototypes:
void TiSetClient(Tile*, ClientData)
void TiSetClientINT(Tile*, intptr_t) /* pointertype */
void TiSetClientPTR(Tile*, void*)
ClientData TiGetClient(Tile*)
intptr_t TiGetClientINT(Tile*) /* pointertype */
void *TiGetClientPTR(Tile*)
macro. Based on observation of cells in PDKs where ORIGIN and/or
FOREIGN are non-zero, added code that forces a correction of LEF
macro coordinates to match the GDS coordinates, with an
equivalent negative shift of the LEF macro ORIGIN to compensate.
Normally, both ORIGIN and FOREIGN will be zero and the added code
will do nothing. Note that this code does not handle the
additional optional orientation. A LEF macro with a different
coordinate system than its GDS is already weird; a LEF macro
with a different rotation than its GDS is hopefully something
that nobody ever does in practice. If needed, I'll cross that
bridge when I come to it.
manhattan shapes (especially minimum-sized ones) to be eliminated,
as these can survive a shrink-grow operation intended to get rid
of such shapes. This implementation may not be in its final form
but should suffice for now.
instance names in both the selection and in the root edit CellDef,
and then wipes duplicate names from the selection and regenerates
unique IDs. This avoids the unexpected behavior displayed by
magic in which a "copy" function renames the *original* instance
and gives the original name to the copied instance. This is not
only unexpected, but causes an error in which "undo" after
multiple copies fails to remove earlier copies because the name
change was not recorded, and the instance can no longer be found
by name.
After futher review of this function it looks like the existing
fclose() is not in the correct place, and recent patches have
added fclose() to this function in better places (covering all
returns) but did not take into account the existing misplaced
fclose().
LefHelper_DBTechNameType_LefLower() identified and introduced during
conversion to const data usage.
Only side-effect is some log messages will use original verbatim token
now instead of lowercase version (but this seems ok when file parsing,
to quote the problematic information source verbatim)