Age | Commit message (Collapse) | Author | Files | Lines |
|
* Cleanup DumpStacks
It's not exactly useful to dump all the stacks after pushing to a stack. Nor is it useful to dump all the stack after popping only some, perhaps none, in PopBlockStacks.
Also dump stack from top to bottom, makes it easier to find the top, which is usually what you care about during SSA renaming.
* Stop passing null block to SsaRenameState::Push
It makes no difference if the definition is in the "block before any real blocks..." or at the start of the first block, it's just an unnecessary complication.
* Stop handling byrefStatesMatchGcHeapStates in SsaRenameState
SsaBuilder already handles that, doing it again in SsaRenameState just duplicates logic.
* Stop using "count" as a name for "SSA number"
Worst name ever.
Also use "block" consistently, instead of a mix of "bb" and "block".
* Delete "ConstructedArray", not needed
* Various cleanup
- Change SsaRenameState to a class
- Cleanup remaining function comments
- Move SsaRenameStateForBlock & SsaRenameStateLocDef inside SsaRenameState
- Make EnsureStacks private
- Reorder data members
- Use m_ prefix consistently
* Replace jitstd::list with a custom stack
std::list has a few drawbacks:
- It's a doubly linked list but a singly linked list suffices so every node wastes 8 bytes for an extra pointer.
- The list object itself is relatively large 2 head/tail pointers, node count and memory allocator. There can be hundreds of such objects (one for each local variable) so the smaller the better.
Replace with a simple singly linked, intrusive list based stack.
* Share push code between lclvar and memory
It's pretty much the same logic (the only difference is that in the memory case "top" can't ever be null so by sharing the code we get a redundant null check).
|
|
|
|
We use the following format when print the BasicBlock number: bbNum
This define is used with string concatenation to put this in printf format strings
|
|
This is not used. It is generated by SsaRenameState::CountForUse when the lclvar stack is empty but that cannot happen - SsaBuilder::RenameVariables starts by assigning SSA numbers to all variables that are live at the start of fgFirstBB.
And if it happens, well, there's a bug somewhere and falling back to minopts via a noway_assert is the appropriate thing to do.
|
|
During SSA construction SsaRenameState keeps a definition count for each variable in an array. But each variable has a lvPerSsaData array that does almost the same thing, count the definitions. "Almost" because lvPerSsaData is a JitExpandArray that tracks only the array size and not the number of elements actually stored in the array.
Replace JitExpandArray with purposely designed "array" that is in charge with allocating new SSA numbers and handles their intricacies - RESERVED_SSA_NUM, UNINIT_SSA_NUM and FIRST_SSA_NUM.
This also allows the removal of the allocator from the array. Allocating new SSA numbers happens only during SSA construction and it's reasonable to pass the allocator to AllocSsaNum rather than increasing the size of PerSsaArray and LclVarDsc.
|
|
Passing CompAllocator objects by value is advantageous because it no longer needs to be dynamically allocated and cached. CompAllocator instances can now be freely created, copied and stored, which makes adding new CompMemKind values easier.
Together with other cleanup this also improves memory allocation performance by removing some extra levels of indirection that were previously required - jitstd::allocator had a pointer to CompAllocator, CompAllocator had a pointer to Compiler and Compiler finally had a pointer to ArenaAllocator. Without MEASURE_MEM_ALLOC enabled, both jitstd::allocator and CompAllocator now just contain a pointer to ArenaAllocator. When MEASURE_MEM_ALLOC is enabled CompAllocator also contains a pointer but to a MemStatsAllocator object that holds the relevant memory kind. This way CompAllocator is always pointer sized so that enabling MEASURE_MEM_ALLOC does not result in increased memory usage due to objects that store a CompAllocator instance.
In order to implement this, 2 additional signficant changes have been made:
* MemStats has been moved to ArenaAllocator, it's after all the allocator's job to maintain statistics. This also fixes some issues related to memory statistics, such as not tracking the memory allocated by the inlinee compiler (since that one used its own MemStats instance).
* Extract the arena page pooling logic out of the allocator. It doesn't make sense to pool an allocator, it has very little state that can actually be reused and everyting else (including MemStats) needs to be reset on reuse. What really needs to be pooled is just a page of memory.
Since this was touching allocation code the opportunity has been used to perform additional cleanup:
* Remove unnecessary LSRA ListElementAllocator
* Remove compGetMem and compGetMemArray
* Make CompAllocator and HostAllocator more like the std allocator
* Update HashTable to use CompAllocator
* Update ArrayStack to use CompAllocator
* Move CompAllocator & friends to alloc.h
|
|
Add a new `MemoryKind` to represent "any memory that byrefs may
reference", called `ByrefExposed`. All definition points of `GcHeap`
become also definition points of `ByrefExposed`, and additionally, so do
definitions of address-exposed locals.
Because it is a common case (currently happening in 90% of methods in
System.Private.CoreLib) that a method has no definitions of
address-exposed locals, have liveness detect this condition and set the
new `byrefStatesMatchGcHeapStates` flag accordingly; when the states
match, the same `MemoryPhi`s, defnums, and `PerSsaData` are then shared
between the two memory kinds, to avoid excess allocations/processing.
This change defines `ByrefExposed` memory and its def/use points, and
builds SSA for it, but no optimizations make use of it, so this is a
no-diff change.
|
|
Re-cast the notion of "heap" (in liveness, SSA, and value-numbering) as
one of potentially many `MemoryKind`s, called `GcHeap`. Update names,
comments, data structures, and signatures as appropriate to parameterize
relevant data/methods over `MemoryKind`. This change is a no-diff
refactoring, and currently `GcHeap` is the only `MemoryKind`. Generally,
codepaths which will generically need to process all `MemoryKinds`s
(initializing, dumping, dataflow propagation) now iterate over all
`MemoryKinds`, and codepaths which are sensitive to the semantics of the
specific `MemoryKind` (def/use identification in liveness and value
numbering) are changed to specifically operate on `MemoryKind::GcHeap`.
One notable exception is that `lvMemoryPerSsaData` and `CountForMemoryDef`
are *not* parameterized over `MemoryKind`; there's a single "space" of SSA
defnums for memory defs (though the same tree can incur different defs for
different memory kinds [in which case their defnums will differ]), to
facilitate subsequently sharing SSA nodes across memory kinds when
appropriate.
|
|
This change is the result of running clang-tidy and clang-format on jit
sources.
|
|
Instead of storing pointers to the thread-local compiler instance
and the current logging environment in separate TLS slots, wrap
these values in a struct and store a pointer to the struct in a
single TLS slot. This simplifies and standardizes the JIT's interface
to its TLS storage, especially when it is being statically linked
into another program or library that cannot use standard TLS.
Note that for release builds, the logging environment is not used
and a pointer to the current compiler instance is stored directly
into the JIT's TLS slot as an implementation detail of the TLS
wrapper type.
|
|
|
|
This change fixes some of the warnings in the jitter code on Linux. With this change
combined with an upcoming change in the rest of the codebase, 16 warning disabling
options can be removed.
The issues in the jitter were:
1) Incorrect typedefs for const_reference and const_pointer (the const was ignored)
2) Member initiazalization order in class constructor didn't correspond to the member order in some classes
3) Objects with vtables were copied via memcpy. While this is intentional, cast of the pointers to void*
is required to silence clang warning
4) Comparing values of different enums - there are cases of two enums containing the same values.
5) Casting int to pointer - the cast was legal (forming a handle), adding cast to size_t in between used to fix the warning
6) "static struct" - removed the static keyword
7) Missing return value in methods with _ASSERTE
8) Class name classifier on methods in the .h
9) Specialized template member functions need to be defined out of the class
|
|
[tfs-changeset: 1407945]
|