Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/coreclr/jit/morph.cpp')
-rw-r--r--src/coreclr/jit/morph.cpp108
1 files changed, 30 insertions, 78 deletions
diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp
index a40cc67b451..15ceeb5f013 100644
--- a/src/coreclr/jit/morph.cpp
+++ b/src/coreclr/jit/morph.cpp
@@ -3147,7 +3147,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
{
GenTree** parentArgx = &arg.EarlyNodeRef();
- // Morph the arg node, and update the parent and argEntry pointers.
+ // Morph the arg node and update the node pointer.
GenTree* argx = *parentArgx;
if (argx == nullptr)
{
@@ -4548,8 +4548,8 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr)
{
unsigned arrRefTmpNum = lvaGrabTemp(true DEBUGARG("arr expr"));
arrRefDefn = gtNewTempAssign(arrRefTmpNum, arrRef);
- arrRef = gtNewLclvNode(arrRefTmpNum, arrRef->TypeGet());
- arrRef2 = gtNewLclvNode(arrRefTmpNum, arrRef->TypeGet());
+ arrRef = gtNewLclvNode(arrRefTmpNum, lvaGetDesc(arrRefTmpNum)->TypeGet());
+ arrRef2 = gtNewLclvNode(arrRefTmpNum, lvaGetDesc(arrRefTmpNum)->TypeGet());
}
else
{
@@ -4563,8 +4563,8 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr)
{
unsigned indexTmpNum = lvaGrabTemp(true DEBUGARG("index expr"));
indexDefn = gtNewTempAssign(indexTmpNum, index);
- index = gtNewLclvNode(indexTmpNum, index->TypeGet());
- index2 = gtNewLclvNode(indexTmpNum, index->TypeGet());
+ index = gtNewLclvNode(indexTmpNum, lvaGetDesc(indexTmpNum)->TypeGet());
+ index2 = gtNewLclvNode(indexTmpNum, lvaGetDesc(indexTmpNum)->TypeGet());
}
else
{
@@ -4807,7 +4807,7 @@ GenTree* Compiler::fgMorphExpandStackArgForVarArgs(GenTreeLclVarCommon* lclNode)
}
GenTree* argNode;
- if (varTypeIsStruct(lclNode))
+ if (lclNode->TypeIs(TYP_STRUCT))
{
argNode = gtNewObjNode(lclNode->GetLayout(this), argAddr);
}
@@ -4887,7 +4887,7 @@ GenTree* Compiler::fgMorphExpandImplicitByRefArg(GenTreeLclVarCommon* lclNode)
unsigned offset = lclNode->GetLclOffs() + fieldOffset;
var_types argNodeType = lclNode->TypeGet();
ClassLayout* argNodeLayout = nullptr;
- if (varTypeIsStruct(argNodeType))
+ if (argNodeType == TYP_STRUCT)
{
argNodeLayout = lclNode->GetLayout(this);
}
@@ -4909,7 +4909,7 @@ GenTree* Compiler::fgMorphExpandImplicitByRefArg(GenTreeLclVarCommon* lclNode)
GenTree* newArgNode;
if (!isAddress)
{
- if (varTypeIsStruct(argNodeType))
+ if (argNodeType == TYP_STRUCT)
{
newArgNode = gtNewObjNode(argNodeLayout, addrNode);
}
@@ -8505,7 +8505,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call)
// [tmp + vtabOffsOfIndirection]
GenTree* tmpTree1 = gtNewOperNode(GT_ADD, TYP_I_IMPL, gtNewLclvNode(varNum1, TYP_I_IMPL),
gtNewIconNode(vtabOffsOfIndirection, TYP_I_IMPL));
- tmpTree1 = gtNewOperNode(GT_IND, TYP_I_IMPL, tmpTree1, false);
+ tmpTree1 = gtNewOperNode(GT_IND, TYP_I_IMPL, tmpTree1);
tmpTree1->gtFlags |= GTF_IND_NONFAULTING;
tmpTree1->gtFlags |= GTF_IND_INVARIANT;
@@ -8519,7 +8519,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call)
GenTree* asgVar2 = gtNewTempAssign(varNum2, tmpTree2); // var2 = <expression>
// This last indirection is not invariant, but is non-faulting
- result = gtNewOperNode(GT_IND, TYP_I_IMPL, gtNewLclvNode(varNum2, TYP_I_IMPL), false); // [var2]
+ result = gtNewOperNode(GT_IND, TYP_I_IMPL, gtNewLclvNode(varNum2, TYP_I_IMPL)); // [var2]
result->gtFlags |= GTF_IND_NONFAULTING;
result = gtNewOperNode(GT_ADD, TYP_I_IMPL, result, gtNewLclvNode(varNum2, TYP_I_IMPL)); // [var2] + var2
@@ -8532,7 +8532,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call)
{
// result = [vtab + vtabOffsOfIndirection]
result = gtNewOperNode(GT_ADD, TYP_I_IMPL, vtab, gtNewIconNode(vtabOffsOfIndirection, TYP_I_IMPL));
- result = gtNewOperNode(GT_IND, TYP_I_IMPL, result, false);
+ result = gtNewOperNode(GT_IND, TYP_I_IMPL, result);
result->gtFlags |= GTF_IND_NONFAULTING;
result->gtFlags |= GTF_IND_INVARIANT;
}
@@ -8549,7 +8549,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call)
// result = [result + vtabOffsAfterIndirection]
result = gtNewOperNode(GT_ADD, TYP_I_IMPL, result, gtNewIconNode(vtabOffsAfterIndirection, TYP_I_IMPL));
// This last indirection is not invariant, but is non-faulting
- result = gtNewOperNode(GT_IND, TYP_I_IMPL, result, false);
+ result = gtNewOperNode(GT_IND, TYP_I_IMPL, result);
result->gtFlags |= GTF_IND_NONFAULTING;
}
@@ -9138,7 +9138,7 @@ GenTree* Compiler::fgMorphOneAsgBlockOp(GenTree* tree)
noway_assert(src->IsIntegralConst(0));
noway_assert(destVarDsc != nullptr);
- src = gtNewZeroConNode(asgType, CORINFO_TYPE_FLOAT);
+ src = gtNewZeroConNode(asgType);
}
else
#endif
@@ -11403,97 +11403,49 @@ DONE_MORPHING_CHILDREN:
}
case GT_ADDR:
-
- // Can not remove op1 if it is currently a CSE candidate.
- if (gtIsActiveCSE_Candidate(op1))
+ // Can not remove a GT_ADDR if it is currently a CSE candidate.
+ if (gtIsActiveCSE_Candidate(tree))
{
break;
}
- if (op1->OperGet() == GT_IND)
+ // Perform the transform ADDR(IND(...)) == (...).
+ if (op1->OperIsIndir())
{
- // Can not remove a GT_ADDR if it is currently a CSE candidate.
- if (gtIsActiveCSE_Candidate(tree))
- {
- break;
- }
-
- // Perform the transform ADDR(IND(...)) == (...).
GenTree* addr = op1->AsIndir()->Addr();
- noway_assert(varTypeIsI(addr));
-
- DEBUG_DESTROY_NODE(op1);
- DEBUG_DESTROY_NODE(tree);
-
- return addr;
- }
- else if (op1->OperGet() == GT_OBJ)
- {
- // Can not remove a GT_ADDR if it is currently a CSE candidate.
- if (gtIsActiveCSE_Candidate(tree))
- {
- break;
- }
-
- // Perform the transform ADDR(OBJ(...)) == (...).
- GenTree* addr = op1->AsObj()->Addr();
-
- noway_assert(varTypeIsGC(addr->gtType) || addr->gtType == TYP_I_IMPL);
+ noway_assert(varTypeIsI(genActualType(addr)));
DEBUG_DESTROY_NODE(op1);
DEBUG_DESTROY_NODE(tree);
return addr;
}
- else if ((op1->gtOper == GT_COMMA) && !optValnumCSE_phase)
+ // Perform the transform ADDR(COMMA(x, ..., z)) == COMMA(x, ..., ADDR(z)).
+ else if (op1->OperIs(GT_COMMA) && !optValnumCSE_phase)
{
- // Perform the transform ADDR(COMMA(x, ..., z)) == COMMA(x, ..., ADDR(z)).
- // (Be sure to mark "z" as an l-value...)
-
ArrayStack<GenTree*> commas(getAllocator(CMK_ArrayStack));
for (GenTree* comma = op1; comma != nullptr && comma->gtOper == GT_COMMA; comma = comma->gtGetOp2())
{
commas.Push(comma);
}
- GenTree* commaNode = commas.Top();
- tree = op1;
- commaNode->AsOp()->gtOp2->gtFlags |= GTF_DONT_CSE;
-
- // If the node we're about to put under a GT_ADDR is an indirection, it
- // doesn't need to be materialized, since we only want the addressing mode. Because
- // of this, this GT_IND is not a faulting indirection and we don't have to extract it
- // as a side effect.
- GenTree* commaOp2 = commaNode->AsOp()->gtOp2;
- if (commaOp2->OperIsBlk())
- {
- commaOp2->SetOper(GT_IND);
- }
- if (commaOp2->gtOper == GT_IND)
- {
- commaOp2->gtFlags |= GTF_IND_NONFAULTING;
- commaOp2->gtFlags &= ~GTF_EXCEPT;
- commaOp2->gtFlags |= (commaOp2->AsOp()->gtOp1->gtFlags & GTF_EXCEPT);
- }
-
- op1 = gtNewOperNode(GT_ADDR, TYP_BYREF, commaOp2);
- commaNode->AsOp()->gtOp2 = op1;
- // Originally, I gave all the comma nodes type "byref". But the ADDR(IND(x)) == x transform
- // might give op1 a type different from byref (like, say, native int). So now go back and give
- // all the comma nodes the type of op1.
+ GenTree* commaNode = commas.Top();
+ GenTree* addr = gtNewOperNode(GT_ADDR, TYP_BYREF, commaNode->AsOp()->gtOp2);
+ commaNode->AsOp()->gtOp2 = addr;
+ // Retype the comma nodes to match "addr" and update their side effects.
while (!commas.Empty())
{
GenTree* comma = commas.Pop();
- comma->gtType = op1->gtType;
+ comma->gtType = addr->TypeGet();
#ifdef DEBUG
comma->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
#endif
gtUpdateNodeSideEffects(comma);
}
- return tree;
+ return op1;
}
break;
@@ -12389,7 +12341,7 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node)
if (GenTreeVecCon::IsHWIntrinsicCreateConstant(node, simd32Val))
{
- GenTreeVecCon* vecCon = gtNewVconNode(node->TypeGet(), node->GetSimdBaseJitType());
+ GenTreeVecCon* vecCon = gtNewVconNode(node->TypeGet());
for (GenTree* arg : node->Operands())
{
@@ -13626,8 +13578,8 @@ GenTree* Compiler::fgMorphModToSubMulDiv(GenTreeOp* tree)
GenTree* dividend = div->IsReverseOp() ? opB : opA;
GenTree* divisor = div->IsReverseOp() ? opA : opB;
- div->gtOp1 = gtClone(dividend);
- div->gtOp2 = gtClone(divisor);
+ div->gtOp1 = gtCloneExpr(dividend);
+ div->gtOp2 = gtCloneExpr(divisor);
var_types type = div->gtType;
GenTree* const mul = gtNewOperNode(GT_MUL, type, div, divisor);
@@ -17333,7 +17285,7 @@ bool Compiler::fgMorphArrayOpsStmt(MorphMDArrayTempCache* pTempCache, BasicBlock
// Side-effect; create a temp.
// unsigned newIdxLcl = m_compiler->lvaGrabTemp(true DEBUGARG("MD array index copy"));
unsigned newIdxLcl = m_pTempCache->GrabTemp(idx->TypeGet());
- GenTree* newIdx = m_compiler->gtNewLclvNode(newIdxLcl, idx->TypeGet());
+ GenTree* newIdx = m_compiler->gtNewLclvNode(newIdxLcl, genActualType(idx));
idxToUse[i] = newIdx;
idxToCopy[i] = newIdxLcl;
anyIdxWithSideEffects = true;