summaryrefslogtreecommitdiff
path: root/src/jit/morph.cpp
AgeCommit message (Collapse)AuthorFilesLines
2019-09-26Fail to explicitly tail call on x86 unix. (#25032)Jarret Shook1-2/+6
* Fail to explicitly tail call on x86 unix. * Correctly return 100 * Correct return value * Add noway assert in morphTailCall to avoid morphing slow tail calls on unix. * Address feedback
2019-06-24Extend the assert for zero-offset fields (#25341)Michal Strehovský1-2/+2
CoreRT has an [actual field](https://github.com/dotnet/corert/blob/ba3ba929c88bd80ec5d4dd9cf6917471ad8fa180/src/System.Private.CoreLib/src/System/Object.CoreRT.cs#L30) for the method table table pointer in `System.Object`. CoreCLR does shenanigans when laying out `System.Object` to leave a pointer-sized hole instead. I think the zero-offset field is triggering these asserts.
2019-06-19Fix Issue #25134 - AssertionProp incorrectly removes cast from uintBrian Sullivan1-1/+1
Add additional check for the GT_UNSIGNED flag + Ran clang-format + Code review feedback, use IsUnsigned()
2019-06-05Cleanup block stores and test for 24846 (#24950)Carol Eidt1-11/+2
* Cleanup block stores and test for 24846 Fix zero-length assert/bad codegen for initblk. Remove redundant assertions in codegen and those that don't directly relate to codegen requirements. Eliminate redundant LEA that was being generated by `genCodeForCpBlk`. Rename `genCodeFor[Cp|Init]Blk` to `genCodeFor[Cp|Init]BlkHelper` to parallel the other forms. Fix the test case for #24846.
2019-05-31Handle a zero byte cpblk (#24871)Carol Eidt1-1/+4
Fix #24846
2019-05-16Ensure that SIMD fields are correctly typed (#24377)Carol Eidt1-68/+43
When a struct field is imported, its type needs to be normalized. Also, the LHS of a struct init, even if a SIMD type, should not be transformed to a non-block node, except in the case of a SIMD local, in which case it must be transformed to a simple assignment. Also, add an assert to catch this kind of bug in liveness. Fix #24336
2019-04-23Added additional comment explaining ChnageOper(GT_LCL_FLD) and NotAFieldBrian Sullivan1-9/+12
2019-04-19Code review feedbackBrian Sullivan1-29/+6
2019-04-19Fixes for Zero Offset field sequence trackingBrian Sullivan1-63/+170
- 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()
2019-04-17Merge pull request #24067 from briansull/desktop-fix2Brian Sullivan1-2/+2
Fix for Desktop build break
2019-04-17Restrict morph add rearrangement. (#23984)Eugene Rozenfeld1-40/+44
Morph has transformations ((x + const) + y) => ((x + y) + const) and ((x + const1) + (y + const2)) => ((x + y) + (const1 + const2)) If x or y is a GC pointer and one of the int operands may be negative, this may result in a byref temp that points outside of the ref object. If the code is in a non-interruptible region and a GC happens, the byref won't be updated. This change disallows the transformations if one of the non-const operands is a GC pointer. Fixes #23792.
2019-04-17Fix for Desktop build breakBrian Sullivan1-2/+2
2019-04-17Add lvIsImplicitByRef information to lvaSetStruct (#19223)Jarret Shook1-47/+12
Before implicit byrefs were tracked by setting lvIsParam and lvIsTemp. This change explicitly adds a flag for implicitByRef instead of overloading. In addition, it fixes the decision to copy an implicitByRef for arm64 varargs. Temporarily bump weight on byref params to match old behavior and avoid codegen diffs. Re-enabled various tests and parts of tests. Closes #20046 Closes #19860
2019-04-16Arm64 vector ABI (#23675)Carol Eidt1-74/+116
* 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
2019-04-12JIT: update byref null check logic to handle field chains (#23850)Andy Ayers1-9/+22
The jit was not properly accumulating offsets when figuring out if a byref should be null checked. Use a non-null MorphAddressContext as indication that GT_FIELD and GT_IND nodes are actually part of an ongoing address computation. During field morphing propagate the current address context to the child node, instead of starting a new one. Fixes #23791.
2019-03-29Use GenTreeStmt* where it is implied. (#22963)Sergey Andreenko1-106/+101
* 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.
2019-03-28Struct & SIMD improvements (#22255)Carol Eidt1-91/+56
* [WIP] Struct & SIMD improvements - Enable CSE of struct values when handle is available (and add code to get the handle of HW SIMD types) - Don't require block nodes for SIMD assignments - Don't set `GTF_GLOB_REF` on `GT_OBJ` if it is local - Set `lvRegStruct` on promoted SIMD fields - Add tests for #19910 (fixed with this PR) and #3539 & #19438 (fixed with #21314) - Additional cleanup Fix #19910
2019-03-18Fix explicit constructor calls and Remove multi-line comments (#23162)Sinan Kaya1-38/+38
* fix implicit constructor call * extern c format patch * muti-line * Remove direct constructor call * Conversion * Need paranthesis * Return value on resize * declspec(Thread) * Ignore warnings for GCC * Formatting issues * Move cast to constant
2019-03-16JIT: clear stub register assignment for tail calls via helper (#23288)Andy Ayers1-0/+12
When we have a VSD tail call via a helper, the stub arg is passed as a normal arg to the helper and moved to the right special register by the copy routine that the helper invokes. So the jit does not need to pass the stub value in the special register when calling the helper. The stub arg gets set to that register by default, so we now unset it for the tail call via helper case. Closes #18943.
2019-03-13Fix for Issue 21231Brian Sullivan1-2/+18
When transferring a Zero offset from one GenTree node to another, we need to check if there already is a FieldSeq and append to it. Added third parameter 'kind' to JitHashTable::Set, and Added enum SetKind Only allow Set to overwrite an existing entry when kind is set to Overwrite. Added validation for all calls to JitHashTable::Set asserting that we don't expect the key to already exist or that we passed Overwrite indicating that we expect to handle it properly. Added two test cases for Issue 21231
2019-03-04JIT: remove unneeded ref count updating traversal from optimizer (#22954)Andy Ayers1-6/+1
The ref count update traversal in the optimizer is not doing anything, so remove it. This was overlooked when we changed away from incremental updates in #19345. Also: fix up comments and documentation to reflect the current approach to local var ref counts.
2019-03-04Merge pull request #22791 from CarolEidt/Fix19256Carol Eidt1-10/+21
Fix condition for calling EvalArgsToTemps
2019-02-28Set flag in comp info to signal that a caller has >8 byte struct args (#22775)Jarret Shook1-2/+7
* Set flag in comp info to signal that a caller has >8 byte struct args This will be used by fgCanFastTailCall to correctly determine whether an arm64 or x64 linux caller/callee can fastTailCall. It is also a workaround to #12468 to catch early any slot shuffling that would happen in LowerFastTailCall. Which currently assumes all parameters are one slot size. * Address feedback * Apply format patch * Add comment * apply new format patch
2019-02-26JIT: In morph, only call DefinesLocal on assignments (#22753)Andy Ayers1-1/+10
When checking for local assertions to kill in morph, only call `DefinesLocal` on `GT_ASG` nodes. Also, assert that we never see LIR style assignments. Resolves #22747.
2019-02-26Fix condition for calling EvalArgsToTempsCarol Eidt1-10/+21
`fgArgInfo::ArgsComplete()` checks for additional conditions requiring temps that are not checked for in the body of `fgMorphArgs()`. However, if there are no register args, it won't be called. Fix #19256
2019-02-08Force results of rejected multi-reg-returning tail-call candidates to temp. ↵Eugene Rozenfeld1-0/+52
(#22364) * Force results of rejected multi-reg-returning tail-call candidates to temp. Issue #20269 ran into an assert when trying to merge returns, one of which is a call to a multi-reg-returning method. The repro in the bug is a pmi of `System.Reflection.Metadata`. I added a simple repro test case. Results of calls to multi-reg-returning methods are expected to be saved to temps. Normally it's ensured by `impFixupCallStructReturn`; however, it doesn't do that for tail-call candidates. This change forces results of calls to multi-reg-returning methods to temps if the tail call is rejected late in morph. Fixes #20269.
2019-02-06Allow lcl_var structs to be widened to primitive types on unix amd64. (#22437)Jarret Shook1-4/+5
* Allow lcl_var structs to be widened to primitive types on unix amd64. The already happens on armarch * Apply format patch
2019-01-30Remove GTF_ADDR_ONSTACK and IsVarAddr.Eugene Rozenfeld1-5/+7
IsVarAddr was checking GTF_ADDR_ONSTACK to determine if the GT_ADDR node is an address of a local. This change removes both GTF_ADDR_ONSTACK and IsVarAddr and uses IsLocalAdrExpr instead. IsLocalAddrExpr uses opcodes to determine if GT_ADDR node is a local address. GTF_ADDR_ONSTACK flag is ancient, added before 2002 so I couldn't find the checkin that introduced it. I changed the assert to a check and an assignment since simplifications inside fgMorphArgs between https://github.com/dotnet/coreclr/blob/1a1e4c4d5a8030cb8d82a2e5b06c2ab357b92534/src/jit/morph.cpp#L3709 (which causes https://github.com/dotnet/coreclr/blob/1a1e4c4d5a8030cb8d82a2e5b06c2ab357b92534/src/jit/morph.cpp#L3057) and https://github.com/dotnet/coreclr/blob/1a1e4c4d5a8030cb8d82a2e5b06c2ab357b92534/src/jit/morph.cpp#L3790 may result in more GT_ADDR nodes recognized by IsLocalAdrExpr. x86 and x64 pmi frameworks had no code diffs and some gcinfo reductions (15 methods with gcinfo diffs in x86). Fixes #22190.
2019-01-28Fix various fgMorphInitBlock issues (#21820)mikedn1-178/+233
* Fix various fgMorphInitBlock issues * Remove unnecessary destAddr variable * Extend/fix comment headers
2019-01-23Fix accidental assignment inside an assert. (#22148)Calum Grant1-1/+1
2019-01-14Improvements for object stack allocation.Eugene Rozenfeld1-4/+0
This change enables object stack allocation for more cases. 1. Objects with gc fields can now be stack-allocated. 2. Object stack allocation is enabled for x86. ObjectAllocator updates the types of trees containing references to possibly-stack-allocated objects to TYP_BYREF or TYP_I_IMPL as appropriate. That allows us to remove the hacks in gcencode.cpp and refine reporting of pointers: the pointer is not reported when we can prove that it always points to a stack-allocated object or is null (typed as TYP_I_IMPL); the pointer is reported as an interior pointer when it may point to either a stack-allocated object or a heap-allocated object (typed as TYP_BYREF); the pointer is reported as a normal pointer when it points to a heap-allocated object (typed as TYP_REF). ObjectAllocator also adds flags to indirections: GTF_IND_TGTANYWHERE when the indirection may be the heap or the stack (that results in checked write barriers used for writes) or the new GTF_IND_TGT_NOT_HEAP when the indirection is null or stack memory (that results in no barrier used for writes).
2019-01-10Merge pull request #21815 from CarolEidt/Fix752890Carol Eidt1-4/+4
[x86] Make copies of odd-size struct arguments
2019-01-09PR FeedbackCarol Eidt1-3/+1
2019-01-09Merge pull request #20772 from mikedn/ir-cleanupBruce Forstall1-11/+8
Some IR cleanup
2019-01-08Copy address-taken SIMD intrinsic (#21884)Carol Eidt1-6/+6
* Copy address-taken SIMD intrinsic This occurs, for example, when boxing the result of a SIMD intrinsic. This was being handled for the HW intrinsic case, but not the SIMD Vector intrinsics. Also, eliminate `OperIsSimdHWIntrisic` since it redundantly checks for the case of a SIMD result, even though it was always called in a context where the result is known to be a struct type. Fix #21854
2019-01-04JIT: encapsulate general checks for optimizationAndy Ayers1-6/+7
Add methods that answer the general question of whether or not the jit is optimizing the code it produces. Use this to replace composite checks for minopts and debug codegen (the two modes where the jit is not optimizing).
2019-01-04[x86] Make copies of odd-size structsCarol Eidt1-2/+4
PR #21304 inadvertently disabled this code for x86. This led to AV failures on desktop, but the same code silently loads the larger size on coreclr without AV'ing. Add an assert that we don't see this kind of node in x86 codegen.
2019-01-04JIT: don't optimize struct copies for call args in debug or minopts (#21792)Andy Ayers1-29/+48
The jit will opportunistically optimize away copies for some struct call arguments, if that argument is a "last use" for the struct (and some other conditions apply). In cases like #21544 this leads to confusing debug experiences as inputs to a call appear to be modified by the call. Also we really should not be optimizing the code this way in debug or in minopts codegen modes. So, block this optimization for debug and minopts. Closes #21544.
2018-12-22Fix ArrayStack's call to default constructor for <T>. (#21624)Sergey Andreenko1-16/+4
* Add ArrayStack::Empty * Add ArrayStack::BottomRef * Delete unused `ReverseTop`. * do not use default constructor.
2018-12-20Don't morph volatile IND(ADDR(LCL_VAR)) (#20843)mikedn1-125/+135
Besides the fact that volatile indirections aren't supposed to be removed doing so in this case results in incorrect code being generated. The GT_IND node has GTF_DONT_CSE set and this gets copied to the GT_LCL_VAR node. Later this prevents the insertion of a normalization cast because GTF_DONT_CSE on a GT_LCL_VAR node is assumed to mean that the variable address is being taken.
2018-12-18Transform SIMD8 to FIELD_LIST if promotedCarol Eidt1-1/+1
Fix #21546
2018-12-12Merge pull request #21304 from CarolEidt/NonObjSIMDCarol Eidt1-221/+248
Don't require BLK nodes for SIMD
2018-12-10Eliminate GenTreeRegVar and GT_REG_VAR and RegVar (#18317)Julius R Friedman1-2/+1
Issue #18201 / Hackathon
2018-12-10Don't require BLK nodes for SIMDCarol Eidt1-221/+248
Eliminate most cases where an OBJ or BLK node is required for SIMD values. The exception is the case where a value produced by an intrinsic (SIMD or HWIntrinsic) is used as an argument but the argument is of a different SIMD type (e.g. a different baseType),
2018-12-06Merge pull request #21314 from CarolEidt/DontPromoteHwVectorCarol Eidt1-1/+1
Don't struct-promote opaque vectors
2018-12-06Guarded devirtualization foundations (#21270)Andy Ayers1-20/+44
Lay the groundwork for guarded devirtualization of virtual and interface calls in the jit. Introduce the notion of a guarded devirtualization candidate and identify these if regular devirtualization fails. Use simple heuristics to produce a class to guess for. Require that the method that would be invoked if the class guess is correct be a plausible inline candidate. Generalize the calli transformer to become an indirect call transformer. This runs after importation because it needs to introduce control flow and runs before inlining so that the new direct calls it introduces can be inlined. Implement the transformation to duplicate the call site, devirtualize on the side where the class is now known exactly, and turn the resulting direct call into an inline candidate. Add a motivation and design document.
2018-12-01Don't struct-promote opaque vectorsCarol Eidt1-1/+1
The hardware vector types: `Vector64<T>`, `Vector128<T>` and `Vector256<T>` are declared as having one or more fields of `ulong`. However, the JIT shouldn't be promoting these fields to local variables. It is almost never the right type, and the intrinsics in any case are not designed to cooperate with promoted fields (i.e. an index of a `Vector<ulong>` won't map to the promoted lclVar). Most importantly, it causes all copies of the vector to be done as 64-bit integer loads and stores. Finally, it will be important, as we support vector ABIs, to distinguish the handling of the fixed-size vectors (`Vector2`, `Vector3` and `Vector4`) which *are* considered to be normal structs of N floats, from the opaque types which will be passed in vector registers.
2018-11-27Merge pull request #21151 from CarolEidt/Fix21080Carol Eidt1-13/+44
Use LclFld for full-width cpblk of different types
2018-11-26Use LclFld for full-width cpblk of different typesCarol Eidt1-13/+44
This issue arose because the source tree was a struct with a single double field, and the destination was a struct with a single long field. Copy prop replaced the lclVar in the source, which was under a `IND(ADDR)` with a lclVar that was not address taken, although it was marked `GTF_DONT_CSE`. Replacing the src tree with a `GT_LCL_FLD` addresses this issue. Also, ensure that the target is marked `DoNotEnregister` if it isn't referenced as the same size/type. Fix #21080 Fix #21064
2018-11-26Fixing a few small issues with the SIMD vs SIMD HWIntrinsics (#21097)Tanner Gooding1-2/+3
* Fixing the simdHandleCache to add entries for Vector64FloatHandle and Vector128FloatHandle * Fixing two places that were calling just OperIsSIMD() rather than OperIsSIMDorSimdHWintrinsic()