Age | Commit message (Collapse) | Author | Files | Lines |
|
Check for `lvLRACandidate` instead of `!lvDoNotEnregister` when checking whether `this` may be enregistered and has an Interval.
|
|
|
|
Fix #25433
|
|
For the JIT32_GCENCODER the this pointer must be either kept in a single register or on the stack.
Fix #24166
|
|
Moving VariableLiveRanges classes outside Compiler class
|
|
* Fix Arm64 UpperVector save/restore
Change the general handling of end-of-block restores so that we always have a RefPosition on which to allocate the register needed on Arm64.
Fix #23885
|
|
* Support for Arm64 Vector ABI
Extend HFA support to support vectors as well as floating point types.
This requires that the JIT recognize vector types even during crossgen,
so that the ABI is supported consistently.
Also, fix and re-enable the disabled Arm64 Simd tests.
Fix #16022
|
|
|
|
* Don't Free UpperVector
UpperVector regs are freed at their time of use, and shouldn't be freed when the last RefPosition is encountered.
Also, we need to specify all 3 operands for vinsertf128
Fix #23861
Fix #23904
Fix #23804
|
|
Improve Upper Vector Save/Restore
In order to avoid saving and restore the upper half of large vectors around every
call even if they are not used, separately model the upper half of large vector
lclVars, and track whether the large vector lclVar is partially-spilled, in which
case its upper half resides in its upper half Interval's location.
Fix #18144
|
|
* LSRA cleanup
These are zero-diff changes. Some cleanup, some in preparation for improvemetns to save/restore of upper vectors.
|
|
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
|
|
* Defining VariableLiveRange class
* Adding some typedefs to avoid rewriting
* Defining VariableLiveDescriptor class
* Initializing VariableLiveRange structures before BasicBlock code is being generated
* Getting a siVarLoc for variable homes from a given LclVarDsc and stack level
* Defining VariableLiveKeeper class
* Reporting VariableLiveRanges on changes of variable livenesss or variable homes
* Adding USING_VARIABLE_LIVE_RANGE flag to enable disable VariableLiveRange
* Send VariableLiveRanges to debugger
* Reporting variable homes on prolog
* Wrong argument
* Miss to change variable homes count before sending them to debugger
* Adding dumper of VariableLiveRanges for each blocks and end of code generation
* Close all open VaribleLiveRanges on last BasicBlock
* Changing order of properties initialization on VariableLiveRange constructor
* Type error on assignation
* Rephrasing comments, moving dumps and fixing typos
* Changing const VARSET_TP* for VARSET_VALARG_TP on args
* Variable home was variable location in VariableLiveRange context
* Rephrase and rename of VariableLiveKeeper properties
* Missing some renames
* Adding const where BasicBlock should not be modified
* siBeginBlock and siInit have support for debug code for VariableLiveRange and siScope info
* Adding USING_VARIABLE_LIVE_RANGE flags on methods definition.
* Variable home -> variable location
* Renaming and rephrasing names and uses of VariableLiveRange
* Moving LiveRangeDumper ctor to class declation
* Removing destructors
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Removing blank spaces and reordering functions inside class definition
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Miss to increment the index after refactoring
* Logic for keeping the last BasicBlock end IL offset is shared between siScope and VariableLiverange for debug code
* Missing to print on debug the last block VariableLiveRanges
* Avoid updating VariableLiveRange when unspilling and dying at the same assembly instruction
* Rephrasing #ifs and #ifdefs
* Calling VariableLiveKeeper in one line
* Avoid copying siVarLoc on genSetScopeInfo
* Removing unused args from eeSetLVinfo
* Changing VariableLiveKeeper ctor
* Typo
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Updating VariableLiveDescriptor ctor
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Error on first argument
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Changing reference for pointer
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Renaming assembly offset -> native offset
* removing unnecesary comments and asserts
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Update VariableLiveRange dump message
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Moving VariableLiveRanges classes inside VariableLiveKeeper
* Wrong flag name
* Adding documentation about how we track variables for debug info
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Adding opened issues to doc file
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Changing dump tittle
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Renaming VariableLiveKeeper property
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Update documentation
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Updating comments on flags
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
* Setting Scope Info as default way of tracking variables for debug info
Signed-off-by: Brian Bohe <brianbohe@gmail.com>
|
|
* Spill tree temp large vectors around calls
The code was there to handle lclVars, but there was an implicit assumption that non-lclVar large vector tree temps would never be live across a call.
Fixes the GitHub_20657 failure in #22253
|
|
* Propagate preferences
Instead of selecting a single relatedInterval for preferencing,
follow the chain of relatedIntervals (preferenced intervals).
Change when preferences are propagated to the relatedInterval;
do it in allocateRegisters, so that we can update it when we see a last use.
Also tune when and how intervals are preferenced, including allowing multiple
uses on an RMW node to have the target as their preference.
Fixes #11463
Contributes to #16359
|
|
When handling critical edges, live-in and live-out reg masks must contain both halves of double regs.
|
|
* Add a repro test.
* Fix the issue.
* Add comments
|
|
* Fix the strange `ifdef ` placement.
* Fix comments/refactoring of `LinearScan::BuildReturn`.
* Delete `FixupIfSIMDLocal`.
Do not change `LCL_FLD(long)` back to `LCL_VAR(simd8)`,
|
|
A multireg COPY will only have a valid register for indices that require copying. Thus, the `GetRegCount` method must return the highest index that has a valid register.
Fix #20063
|
|
On x86, `MUL_LONG` wasn't considered a multi-reg node, as it should be, so that when it gets spilled or copied, the additional register will be correctly handled.
Also, the ARM and X86 versions of genStoreLongLclVar should be identical and shared (neither version were handling the copy of a `MUL_LONG`).
Finally, fix the LSRA dumping of multi-reg nodes.
Fix #19397
|
|
|
|
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
|
|
|
|
Arm64: Fix handling of IP0 & IP1
|
|
This is a preparatory change for auditing and controlling how local
variable ref counts are observed and manipulated.
See #18969 for context.
No diffs seen locally. No TP impact expected.
There is a small chance we may see some asserts in broader testing
as there were places in original code where local ref counts were
incremented without checking for possible overflows. The new APIs
will assert for overflow cases.
|
|
These are sometimes mandated to be allocated to certain nodes, but they were not in the list of allocatable registers (REG_VAR_ORDER). This led to special handling in LSRA, which, it turns out, was incomplete. This resulted in failures for JitStressRegs=0x200.
Based on the discussion in #14607, this adds IP0 to RBM_CALLEE_TRASH_NOGC, and fixes the REG_VAR_ORDER.
Fix #14607, Fix #16359, Fix #17861
|
|
`BuildUse` was setting the regNumber for all of the uses of a multi-reg node to the main/first regNum. This was missed because this results in a def/use conflict on that reg (the def was set correctly), which is generally resolved in favor of the def. The exception is when there is a kill of the register in between, in which case the use tries to allocate the register its been assigned, causing the `farthestRefPhysRegRecord != nullptr` assert (aka "a register can't be found to spill").
This fixes the specific issue, and adds additional asserts to identify future/additional such issues.
The new asserts depend upon all the regNums being appropriately when/if any are set, which wasn't always the case prior to register allocation.
Fix #18153
|
|
Don't change PUTARG_REG spill type on arm64
|
|
Fix #18746
|
|
Make Compiler and CodeGen objects smaller
|
|
This is no longer used after #16517
|
|
Temporaries are only used during register allocation and code generation. They waste space (136 bytes) in the compiler object during inlining.
|
|
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
|
|
* Corrected a few typos in the documentation and comments
* Corrected a few typos in the documentation and comments
* Corrected a few typos in the documentation and comments
* Corrected a few typos in the documentation and comments
* Corrected a few typos in the documentation and comments
* Corrected a few typos in the documentation and comments
|
|
Need to build a use for each reg.
Also, dump the defList if it's not empty at end of block.
|
|
* [ARM64|Windows|Vararg] Add FEATURE_ARG_SPLIT
Enable splitting >8 byte <= 16 byte structs for arm64 varargs
between x7 and virtual stack slot 0.
* Force notHfa for vararg methods
* Correctly pass isVararg
* Correct var name
|
|
* Fix enregistered lclFld bug
In `impFixupStructReturnType()`, don't transform to `GT_LCL_FLD` if we have a scalar lclVar.
Also, to avoid future bad codegen, add verification and recovery code to Lowering.
Fix #18408
* Extract the full conditions for whether a lclVar is a reg candidate, so it can be called from the assert in Lowering.
* Review feedback
|
|
* acquringing -> acquiring
* Activ -> Active
* activley -> actively
* acutal -> actual
* bIncomingIPAdddefed -> bIncomingIPAddRefed
* adddr -> addr
* readding -> reading
* Addfunction -> AddFunction
* additionnal -> additional
* Additonal -> Additional
* Additonally -> Additionally
* Addresss -> Address
* addtion -> addition
* aded -> added
* aditional -> additional
* adjustements -> adjustments
* Adress -> Address
* afer -> after
* aformentioned -> aforementioned
* afte -> after
* agains -> against
* agaisnt -> against
* aggresively -> aggressively
* aggreates -> aggregates
* aggregious -> egregious
* aginst -> against
* agregates -> aggregates
* Agressive -> Aggressive
* ahve -> have
* ajdust -> adjust
* ajust -> adjust
* alement -> element
* algoritm -> algorithm
* alighnment -> alignment
* alignmant -> alignment
* constraits -> constraints
* Allcator -> Allocator
* alllocate -> allocate
* alloacted -> allocated
* allocatate -> allocate
* allocatoror -> allocator
* alloctaed -> allocated
* alloction -> allocation
* alloted -> allotted
* allt he -> all the
* alltogether -> altogether
* alocate -> allocate
* alocated -> allocated
* Alocates -> Allocates
* alogrithm -> algorithm
* aloocate -> allocate
* alot -> a lot
* alwasy -> always
* alwyas -> always
* alwys -> always
|
|
* Create RefPositions without TreeNodeInfo
* Remove all references to TreeNodeInfo
* Fix function header comments
|
|
Remove JIT LEGACY_BACKEND code
All code related to the LEGACY_BACKEND JIT is removed. This includes all code related to x87 floating-point code generation. Almost 50,000 lines of code have been removed.
Remove legacyjit/legacynonjit directories
Remove reg pairs
Remove tiny instruction descriptors
Remove compCanUseSSE2 (it's always true)
Remove unused FEATURE_FP_REGALLOC
|
|
The JIT write barrier helpers have a custom calling convention that
avoids killing most registers. The JIT was not taking advantage of
this, and thus was killing unnecessary registers when a write barrier
was necessary. In particular, some integer callee-trash registers
are unaffected by the write barriers, and no floating-point register
is affected.
Also, I got rid of the `FEATURE_WRITE_BARRIER` define, which is always
set. I also put some code under `LEGACY_BACKEND` for easier cleanup
later. I removed some unused defines in target.h for some platforms.
|
|
ARM: Fix reg resolution for doubles
|
|
|
|
|
|
ARM: call compRsvdRegCheck later
|
|
When a `RefTypeFixedReg` is encountered for a floating point register, if it is currently holding a double constant, we need to free both halves - but the current register be either half.
|
|
1) When an odd float register becomes free, we may need to add the corresponding (even) double register to `targetRegsReady` (this was the bug)
2) When an even float register becomes free, we can't add it to `targetRegsReady` unless it's other half is also free.
|
|
|
|
|
|
For RyuJIT backend, the number of locals can change due to decomposition and lowering.
So, determine whether to reserve a register for accessing large state displacements just prior to register allocation.
This requires ensuring that the stack offset for promoted longs is fixed up, as for promoted reg structs on ARM64.
This is all a bit more difficult on LEGACY_BACKEND because the register allocator can change its mind about whether or not it's going to have a frame, so that is left as before.
|