Age | Commit message (Collapse) | Author | Files | Lines |
|
- A GT_LCL_VAR may have a zeroOffset field
- Add an assert to prevent building field sequences with duplicates
- Fix fgMorphField when we have a zero offset field
Improve fgAddFieldSeqForZeroOffset
- Add JItDump info
- Handle GT_LCL_FLD
Changing the sign of an int constant also remove any field sequence information.
Added method header comment for fgAddFieldSeqForZeroOffset
Changed when we call fgAddFieldSeqForZeroOffset to be before the call to fgMorphSmpOp.
Prefer calling fgAddFieldSeqForZeroOffset() to GetZeroOffsetFieldMap()->Set()
|
|
Fixes #23538
|
|
* Extract `impAppendStmt` and `impExtractLastStmt`.
* Delete `BEG_STMTS` fake stmt.
Use new functions to keep the list updated.
* Retype `impTreeList` and `impTreeLast` as statements.
Rename `impTreeList` and `impTreeLast` to show that they are statements.
* Fix fields that have to be stmt.
* Start using GenTreeStmt.
Change `optVNAssertionPropCurStmt` to use GenTreeStmt.
Replace `GenTree* stmt = block->bbTreeList` with `GenTreeStmt* stmt = block->firstStmt()`.
Save results of `FirstNonPhiDef` as `GenTreeStmt`.
* Replace do-while with for loop.
* Change type inside VNAssertionPropVisitorInfo.
* Delete unused args fron `optVNConstantPropOnTree`.
* Update fields to be stmt.
Update optVNConstantPropCurStmt to use Stmt.
Change `lvDefStmt` to stmt.
Update LoopCloning structs.
Update `optDebugLogLoopCloning`.
Make `compCurStmt` a statement.
Update declaration name in `BuildNode`.
* Clean simple cpp files.
Clean valuenum.
Clean ssabuilder.
Clean simd.
Clean optcse.
Clean loopcloning.
Clean copyprop.
Clean optimizer part1.
* Start cleaning importer, morph, flowgraph, gentree.
* Continue clean functons.
Clean assertionprop.
Clean morph.
Clean gentree.
Clean flowgraph.
Clean compiler.
Clean rangecheck.
Clean indirectcalltransofrmer.
Clean others.
* Create some temp stmt.
* Delete unnecessary noway_assert and casts.
* Init `impStmtList` and `impLastStmt` in release.
* Response review 1.
|
|
* Clean `valuenum.cpp`.
* Clean `emitarm64.cpp`.
* Clean `lsraarm64.cpp`.
* Clean `lsraarmarch.cpp`.
* Clean `lowerarmarch.cpp`.
* Clean `lower.cpp`.
* Clean `ssabuilder.cpp`.
* Clean `simd.cpp`.
* Clear `simdcodegenxarch.cpp`.
* Clean `lowerxarch.cpp`.
* Clean `scopeinfo.cpp`.
|
|
This reverts commit 6cb120cc74ca61fc314e3cc43007778d2aafd041.
|
|
* Clean `valuenum.cpp`.
* Clean `emitarm64.cpp`.
* Clean `lsraarm64.cpp`.
* Clean `lsraarmarch.cpp`.
* Clean `lowerarmarch.cpp`.
* Clean `lower.cpp`.
* Clean `ssabuilder.cpp`.
* Clean `simd.cpp`.
* Clear `simdcodegenxarch.cpp`.
* Clean `lowerxarch.cpp`.
* Clean `scopeinfo.cpp`.
* Clean `hwintrinsiccodegenxarch.cpp`.
|
|
|
|
|
|
fgValueNumberAddExceptionSetForIndirection had a bug
where INDIR(ADD(x, <big_offset>)) had NullReferenceException(x)
added instead of NullReferenceException(ADD(x, <big_offset>)).
Fixes #20358.
|
|
Fix ISA checking to work with desktop.
Also fix Value Numbering jitdump to not assert for struct types without a handle.
|
|
This is to support dotnet/corert#6688. They don't exist in CoreCLR (yet).
|
|
|
|
|
|
|
|
for the VNF_NullPtrExc
|
|
value number
|
|
|
|
Change VNUnpackExc to always write an exception set to pvnx
|
|
* accesible -> accessible
* acheive -> achieve
* actutl -> actual
* appied -> applied
* apropriate -> appropriate
* aprox -> approx
* aquired -> acquired
* argumemts -> arguments
* Argumens -> Arguments
* argumetn -> argument
|
|
This has two parts:
## Part 1
CoreRT represents native type handles differently from CoreCLR - on CoreCLR, `RuntimeTypeHandle` is a wrapper over `RuntimeType` and RyuJIT is aware of that. On CoreRT, `RuntimeTypeHandle` wraps the native type handle, not a `RuntimeType`.
The knowledge is hardcoded in importer when importing the sequence "ldtoken foo / call Type.GetTypeFromHandle" - importer just removes the call and bashes the result of ldtoken to be a reference type. CoreRT had to avoid reporting `Type.GetTypeFromHandle` as an intrinsic because of that.
I'm adding another helper that lets RyuJIT avoid hardcoding that knowledge. Instead of just bashing the return type, we swap the helper call.
## Part 2
Native type handle equality checks need to go through a helper, unless the EE side says it's okay to compare native type handles directly.
|
|
Change the default return value for new GenTree nodes to false
This allows new nodes to be added without immediately implementing
the compile time folding logic.
Added method header comment for CanEvalForConstantArgs
|
|
|
|
The problem here was that we have an indirection of a LclVar that was a pointer to an array element whose type is a struct.
The following discussion refers to the test case GitHub_18259/GitHub_18259.cs
We recorded that the struct field F1.F0 is assigned 1234u.
With the bug all subsequent reads of vr7.F0 return this value.
We miss the update to zero because we didn't add the Zero Field sequence value to the LclVar vr7
Added Test case GitHub_18259.cs
Added Test case GitHub_20838.cs
|
|
Fixes #18672
Test case is here: JIT/Regression/JitBlue/GitHub_18672/GitHub_18672.cs
|
|
* Extract argInfo building from fgMorphArgs
This extracts the code to build the `fgArgInfo` on a call from the code that modifies the arguments.
Eliminated a pre-existing repeated traversal of the argList by changing `EvalToTmp` to take the `fgArgTabEntry` which the caller always has available.
|
|
New method that add exception sets:
fgValueNumberAddExceptionSet
- fgValueNumberAddExceptionSetForIndirection
- fgValueNumberAddExceptionSetForDivision
- fgValueNumberAddExceptionSetForOverflow
- fgValueNumberAddExceptionSetForCkFinite
Refactoring work added methods:
VNEvalShouldFold - method to decide if constant folding should be performed
EvalUsingMathIdentity - Uses math identities to simplify value number exoressions
Renamed fgValueNumberHelperMethVNFunc to fgValueNumberJitHelperMethodVNFunc
Removed the suffixes from the method headers comments
|
|
* Make `structType` optional in `getFieldType`.
The declaration in corinfo.h says: "if 'structType' == 0, then don't bother the structure info". However, `getFieldTypeInternal ` did not check this case.
* Do not bother the structure info when we do not need it from `getFieldType`.
|
|
|
|
|
|
|
|
Revise the exeception gernerating value number functions:
VNF_OverflowEXc, VNF_CastOvf, VNF_ARithmeticExc, VNF_DivideByZeroExc and ConvertOverflowExc
added support methods for VNNormalValue
Extended GetVNGuncForOper to support overflow operations and additional unsigned operations:
And added value number functions for
- unsigned comparisons, unsigned add, sub and mul
- overflow add, sub, mul
New method: VMCheckAscending to validate that exception sets maintain the ascending ordfer property.
New method: VMExcSetIntersection and VMExcIsSubset
Changed the constant folding logic in VNForFunc to avoid folding when the operation will unconditionally throw when folded.
Explicitly specialize some EvalOp<> calls
Added several new method headers comments in ValueNum.cpp
Clear the unsigned flag when bashing nodes into GT_COMMA or GT_NOP nodes
Removed GT_NOP and GT_COMMA cases from GetVNFuncForOper
Added enum VNOperKind
Added support for the unsigned multiply VNFunc used on 32-bit target
|
|
Rework the EvalOp generic-template methods
|
|
|
|
GTF_IND_ARR_LEN was set by the importer in minopts/debug mode and used only by value numbering, which does not run in minopts/debug mode.
GTF_FLD_NULLCHECK was also set by the importer and not used anywhere. fgMorphField has its own opinion about when an explicit null check is needed.
|
|
GTF_ICON_FTN_ADDR) for function address in Compiler::fgValueNumberHelperCallFunc in src/jit/valuenum.cpp
|
|
replaced EvalOpIntegral with EvalOpSpecialized
|
|
|
|
numbers
Support the dumping of exception set
Added full method header comments for VNNormVal and VNWithExc
Removed extra spew for fieldSeq
Removed several unnecessary fgCurMemoryVN assigned printf
Added noway_asserts when dealing with a GT_ASG for a LHS that is a GT_PHI_ARG, GT_BLK or GT_OBJ
|
|
It was previously used for Assign-Op forms of assignment
which we no longer use in the RyuJIT.
|
|
|
|
This function is relatively expensive due to the many checks it does. Adding an LclVarDsc "in SSA" bit that is set during SSA construction by calling fgExcludeFromSsa only once per variable results in 0.35% drop in instructions retired.
Most of the checks done in fgExcludeFromSsa are implied by lvTracked and they could probably be converted to asserts. But lvOverlappingFields is not implied by lvTracked so even if all redundant checks are converted to asserts fgExcludeFromSsa still needs 2 checks rather than just one.
Incidentally, this difference between tracked variables and SSA variables results in SSA and value numbers being assigned to some variables that are actually excluded from SSA - SsaBuilder::RenameVariables and fgValueNumber assign numbers to all live in fgFirstBB variables that require initialization without checking fgExcludeFromSsa first. Structs with overlapping fields are not common but properly excluding them is still enough to save 0.15% memory when compiling corelib.
- Replace calls to fgExcludeFromSsa with calls to lvaInSsa (the old name is kind of weird, it has nothing to do with the flow graph and "exclude" results in double negation)
- Move fgExcludeFromSsa logic to SsaBuild::IncludeInSsa and use it to initialize LclVarDsc::lvInSsa for all variables
- Change RenameVariables and fgValueNumber to call lvaInSsa before assigning numbers to live in fgFirstBB variables
|
|
|
|
Eliminate duplicate SSA number bookkeeping
|
|
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
|
|
We use a unique prefix character when printing value numbers in dumps: i.e. $1c0
This define is used with string concatenation to put this in printf format strings
|
|
arithmetic expressions on ARM32 and ARM64
|
|
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.
|
|
With the advent of #18819 we may now see GT_NULLCHECK nodes with operands
that also can cause exceptions.
Handle this in value numbering.
Closes #18937.
|
|
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
|