@@ -8796,150 +8796,6 @@ GenTree* Compiler::fgMorphOneAsgBlockOp(GenTree* tree)
8796
8796
return tree;
8797
8797
}
8798
8798
8799
- //------------------------------------------------------------------------
8800
- // fgMorphBlockOperand: Canonicalize an operand of a block assignment
8801
- //
8802
- // Arguments:
8803
- // tree - The block operand
8804
- // asgType - The type of the assignment
8805
- // blockLayout - The struct layout of the block (for STRUCT "asgType"s)
8806
- // isBlkReqd - true iff this operand must remain a block node
8807
- //
8808
- // Return Value:
8809
- // Returns the morphed block operand
8810
- //
8811
- // Notes:
8812
- // This does the following:
8813
- // - Ensures that a struct operand is a block node or lclVar.
8814
- // - Ensures that any COMMAs are above ADDR nodes.
8815
- // Although 'tree' WAS an operand of a block assignment, the assignment
8816
- // may have been retyped to be a scalar assignment.
8817
- //
8818
- GenTree* Compiler::fgMorphBlockOperand(GenTree* tree, var_types asgType, ClassLayout* blockLayout, bool isBlkReqd)
8819
- {
8820
- GenTree* effectiveVal = tree->gtEffectiveVal();
8821
-
8822
- if (asgType != TYP_STRUCT)
8823
- {
8824
- unsigned blockWidth = genTypeSize(asgType);
8825
-
8826
- if (effectiveVal->OperIsIndir())
8827
- {
8828
- if (!isBlkReqd)
8829
- {
8830
- GenTree* addr = effectiveVal->AsIndir()->Addr();
8831
- if ((addr->OperGet() == GT_ADDR) && (addr->gtGetOp1()->TypeGet() == asgType))
8832
- {
8833
- effectiveVal = addr->gtGetOp1();
8834
- }
8835
- else if (effectiveVal->OperIsBlk())
8836
- {
8837
- effectiveVal->SetOper(GT_IND);
8838
- }
8839
- }
8840
- effectiveVal->gtType = asgType;
8841
- }
8842
- else if (effectiveVal->TypeGet() != asgType)
8843
- {
8844
- if (effectiveVal->IsCall())
8845
- {
8846
- #ifdef DEBUG
8847
- GenTreeCall* call = effectiveVal->AsCall();
8848
- assert(call->TypeGet() == TYP_STRUCT);
8849
- assert(blockWidth == info.compCompHnd->getClassSize(call->gtRetClsHnd));
8850
- #endif
8851
- }
8852
- else
8853
- {
8854
- GenTree* addr = gtNewOperNode(GT_ADDR, TYP_BYREF, effectiveVal);
8855
- effectiveVal = gtNewIndir(asgType, addr);
8856
- }
8857
- }
8858
- }
8859
- else
8860
- {
8861
- assert(blockLayout != nullptr);
8862
-
8863
- GenTreeIndir* indirTree = nullptr;
8864
- GenTreeLclVarCommon* lclNode = nullptr;
8865
- bool needsIndirection = true;
8866
-
8867
- if (effectiveVal->OperIsIndir())
8868
- {
8869
- indirTree = effectiveVal->AsIndir();
8870
- GenTree* addr = effectiveVal->AsIndir()->Addr();
8871
- if ((addr->OperGet() == GT_ADDR) && (addr->gtGetOp1()->OperGet() == GT_LCL_VAR))
8872
- {
8873
- lclNode = addr->gtGetOp1()->AsLclVarCommon();
8874
- }
8875
- }
8876
- else if (effectiveVal->OperGet() == GT_LCL_VAR)
8877
- {
8878
- lclNode = effectiveVal->AsLclVarCommon();
8879
- }
8880
- else if (effectiveVal->OperIs(GT_LCL_FLD))
8881
- {
8882
- needsIndirection = false;
8883
- assert(ClassLayout::AreCompatible(effectiveVal->AsLclFld()->GetLayout(), blockLayout));
8884
- }
8885
- else if (effectiveVal->IsCall())
8886
- {
8887
- needsIndirection = false;
8888
- #ifdef DEBUG
8889
- GenTreeCall* call = effectiveVal->AsCall();
8890
- assert(call->TypeGet() == TYP_STRUCT);
8891
- assert(blockLayout->GetSize() == info.compCompHnd->getClassSize(call->gtRetClsHnd));
8892
- #endif
8893
- }
8894
- #ifdef TARGET_ARM64
8895
- else if (effectiveVal->OperIsHWIntrinsic())
8896
- {
8897
- needsIndirection = false;
8898
- #ifdef DEBUG
8899
- GenTreeHWIntrinsic* intrinsic = effectiveVal->AsHWIntrinsic();
8900
- assert(intrinsic->TypeGet() == TYP_STRUCT);
8901
- assert(HWIntrinsicInfo::IsMultiReg(intrinsic->GetHWIntrinsicId()));
8902
- #endif
8903
- }
8904
- #endif // TARGET_ARM64
8905
-
8906
- if (lclNode != nullptr)
8907
- {
8908
- const LclVarDsc* varDsc = lvaGetDesc(lclNode);
8909
- if (varTypeIsStruct(varDsc) && ClassLayout::AreCompatible(varDsc->GetLayout(), blockLayout))
8910
- {
8911
- if (effectiveVal != lclNode)
8912
- {
8913
- JITDUMP("Replacing block node [%06d] with lclVar V%02u\n", dspTreeID(tree), lclNode->GetLclNum());
8914
- effectiveVal = lclNode;
8915
- }
8916
- needsIndirection = false;
8917
- }
8918
- else
8919
- {
8920
- // This may be a lclVar that was determined to be address-exposed.
8921
- effectiveVal->gtFlags |= (lclNode->gtFlags & GTF_ALL_EFFECT);
8922
- }
8923
- }
8924
-
8925
- if (needsIndirection)
8926
- {
8927
- if ((indirTree != nullptr) && (indirTree->OperIsBlk() || !isBlkReqd))
8928
- {
8929
- effectiveVal->gtType = asgType;
8930
- }
8931
- else
8932
- {
8933
- effectiveVal = gtNewStructVal(blockLayout, gtNewOperNode(GT_ADDR, TYP_BYREF, effectiveVal));
8934
- gtUpdateNodeSideEffects(effectiveVal);
8935
- }
8936
- }
8937
- }
8938
-
8939
- assert(effectiveVal->TypeIs(asgType) || (varTypeIsSIMD(asgType) && varTypeIsStruct(effectiveVal)));
8940
- return effectiveVal;
8941
- }
8942
-
8943
8799
#ifdef FEATURE_SIMD
8944
8800
8945
8801
//--------------------------------------------------------------------------------------------------------------
@@ -9365,19 +9221,12 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA
9365
9221
}
9366
9222
#endif
9367
9223
9368
- // We can't CSE the LHS of an assignment. Only r-values can be CSEed.
9369
- // Previously, the "lhs" (addr) of a block op was CSE'd. So, to duplicate the former
9370
- // behavior, allow CSE'ing if is a struct type (or a TYP_REF transformed from a struct type)
9371
- // TODO-1stClassStructs: improve this.
9372
- if (op1->IsLocal() || (op1->TypeGet() != TYP_STRUCT))
9373
- {
9374
- op1->gtFlags |= GTF_DONT_CSE;
9375
- }
9224
+ // Location nodes cannot be CSEd.
9225
+ op1->gtFlags |= GTF_DONT_CSE;
9376
9226
break;
9377
9227
9378
9228
case GT_ADDR:
9379
-
9380
- /* op1 of a GT_ADDR is an l-value. Only r-values can be CSEed */
9229
+ // Location nodes cannot be CSEd.
9381
9230
op1->gtFlags |= GTF_DONT_CSE;
9382
9231
break;
9383
9232
@@ -10325,17 +10174,11 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA
10325
10174
*/
10326
10175
10327
10176
GenTree* temp;
10328
- GenTree* lclVarTree;
10329
10177
10330
10178
switch (oper)
10331
10179
{
10332
10180
case GT_ASG:
10333
-
10334
- lclVarTree = fgIsIndirOfAddrOfLocal(op1);
10335
- if (lclVarTree != nullptr)
10336
- {
10337
- lclVarTree->gtFlags |= GTF_VAR_DEF;
10338
- }
10181
+ fgAssignSetVarDef(tree);
10339
10182
10340
10183
if (op2->OperIs(GT_CAST))
10341
10184
{
@@ -10347,14 +10190,8 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA
10347
10190
op2 = tree->gtGetOp2();
10348
10191
}
10349
10192
10350
- fgAssignSetVarDef(tree);
10351
-
10352
- /* We can't CSE the LHS of an assignment */
10353
- /* We also must set in the pre-morphing phase, otherwise assertionProp doesn't see it */
10354
- if (op1->IsLocal() || (op1->TypeGet() != TYP_STRUCT))
10355
- {
10356
- op1->gtFlags |= GTF_DONT_CSE;
10357
- }
10193
+ // Location nodes cannot be CSEd.
10194
+ op1->gtFlags |= GTF_DONT_CSE;
10358
10195
break;
10359
10196
10360
10197
case GT_CAST:
0 commit comments