diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 7649dd610fd2..146086dbde87 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -1256,6 +1256,14 @@ struct ArrayInfo : m_elemType(elemType), m_elemStructType(elemStructType), m_elemSize(elemSize), m_elemOffset(elemOffset) { } + + ArrayInfo(var_types elemType, unsigned elemSize, unsigned elemOffset, ClassLayout* elemLayout) + : m_elemType(elemType) + , m_elemStructType(elemLayout == nullptr ? nullptr : elemLayout->GetClassHandle()) + , m_elemSize(elemSize) + , m_elemOffset(elemOffset) + { + } }; // This enumeration names the phases into which we divide compilation. The phases should completely @@ -9745,19 +9753,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // True if the `GT_IND` node represents an array access; false otherwise. bool TryGetArrayInfo(GenTreeIndir* indir, ArrayInfo* arrayInfo) { + assert(!indir->gtOp1->OperIs(GT_INDEX_ADDR)); + if ((indir->gtFlags & GTF_IND_ARR_INDEX) == 0) { return false; } - if (indir->gtOp1->OperIs(GT_INDEX_ADDR)) - { - GenTreeIndexAddr* const indexAddr = indir->gtOp1->AsIndexAddr(); - *arrayInfo = ArrayInfo(indexAddr->gtElemType, indexAddr->gtElemSize, indexAddr->gtElemOffset, - indexAddr->gtStructElemClass); - return true; - } - bool found = GetArrayInfoMap()->Lookup(indir, arrayInfo); assert(found); return true; diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index e22d9c453fd8..6fe17492c152 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -7071,7 +7071,7 @@ GenTree* Compiler::gtCloneExpr( copy = new (this, GT_INDEX_ADDR) GenTreeIndexAddr(asIndAddr->Arr(), asIndAddr->Index(), asIndAddr->gtElemType, - asIndAddr->gtStructElemClass, asIndAddr->gtElemSize, asIndAddr->gtLenOffset, + asIndAddr->gtElemLayout, asIndAddr->gtElemSize, asIndAddr->gtLenOffset, asIndAddr->gtElemOffset); copy->AsIndexAddr()->gtIndRngFailBB = asIndAddr->gtIndRngFailBB; } @@ -16477,8 +16477,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleIfPresent(GenTree* tree) structHnd = tree->AsIndex()->GetLayout()->GetClassHandle(); break; case GT_INDEX_ADDR: - structHnd = tree->AsIndexAddr()->gtStructElemClass; - break; + unreached(); case GT_FIELD: info.compCompHnd->getFieldType(tree->gtField.gtFldHnd, &structHnd); break; @@ -16517,29 +16516,31 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleIfPresent(GenTree* tree) // Attempt to find a handle for this expression. // We can do this for an array element indirection, or for a field indirection. ArrayInfo arrInfo; - if (TryGetArrayInfo(tree->AsIndir(), &arrInfo)) + GenTree* addr = tree->AsIndir()->Addr(); + if (addr->OperIs(GT_INDEX_ADDR)) + { + GenTreeIndexAddr* indexAddr = addr->AsIndexAddr(); + structHnd = EncodeElemType(indexAddr->gtElemType, indexAddr->gtElemLayout->GetClassHandle()); + } + else if (TryGetArrayInfo(tree->AsIndir(), &arrInfo)) { structHnd = EncodeElemType(arrInfo.m_elemType, arrInfo.m_elemStructType); } - else + else if (addr->OperIs(GT_ADD) && addr->AsOp()->gtGetOp2()->OperIs(GT_CNS_INT)) { - GenTree* addr = tree->AsIndir()->Addr(); - if ((addr->OperGet() == GT_ADD) && addr->gtGetOp2()->OperIs(GT_CNS_INT)) - { - FieldSeqNode* fieldSeq = addr->gtGetOp2()->AsIntCon()->gtFieldSeq; + FieldSeqNode* fieldSeq = addr->gtGetOp2()->AsIntCon()->gtFieldSeq; - if (fieldSeq != nullptr) + if (fieldSeq != nullptr) + { + while (fieldSeq->m_next != nullptr) { - while (fieldSeq->m_next != nullptr) - { - fieldSeq = fieldSeq->m_next; - } - if (fieldSeq != FieldSeqStore::NotAField() && !fieldSeq->IsPseudoField()) - { - CORINFO_FIELD_HANDLE fieldHnd = fieldSeq->m_fieldHnd; - CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &structHnd); - assert(fieldCorType == CORINFO_TYPE_VALUECLASS); - } + fieldSeq = fieldSeq->m_next; + } + if (fieldSeq != FieldSeqStore::NotAField() && !fieldSeq->IsPseudoField()) + { + CORINFO_FIELD_HANDLE fieldHnd = fieldSeq->m_fieldHnd; + CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &structHnd); + assert(fieldCorType == CORINFO_TYPE_VALUECLASS); } } } diff --git a/src/jit/gentree.h b/src/jit/gentree.h index c29ac3c0af2a..6dd8a3f9dc75 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -3860,13 +3860,13 @@ struct GenTreeCall final : public GenTree public: ClassLayout* GetLayout() const { - assert(varTypeIsStruct(TypeGet())); + // assert(varTypeIsStruct(TypeGet())); return m_layout; } void SetLayout(ClassLayout* layout) { - assert(varTypeIsStruct(TypeGet()) == (layout != nullptr)); + // assert(varTypeIsStruct(TypeGet()) == (layout != nullptr)); m_layout = layout; } @@ -4346,24 +4346,23 @@ struct GenTreeIndexAddr : public GenTreeOp return gtOp2; } - CORINFO_CLASS_HANDLE gtStructElemClass; // If the element type is a struct, this is the struct type. - BasicBlock* gtIndRngFailBB; // Basic block to jump to for array-index-out-of-range - var_types gtElemType; // The element type of the array. - unsigned gtElemSize; // size of elements in the array - unsigned gtLenOffset; // The offset from the array's base address to its length. - unsigned gtElemOffset; // The offset from the array's base address to its first element. - - GenTreeIndexAddr(GenTree* arr, - GenTree* ind, - var_types elemType, - CORINFO_CLASS_HANDLE structElemClass, - unsigned elemSize, - unsigned lenOffset, - unsigned elemOffset) + ClassLayout* gtElemLayout; // If the element type is a struct, this is the struct type. + var_types gtElemType; // The element type of the array. + unsigned gtElemSize; // size of elements in the array + unsigned gtLenOffset; // The offset from the array's base address to its length. + unsigned gtElemOffset; // The offset from the array's base address to its first element. + + GenTreeIndexAddr(GenTree* arr, + GenTree* ind, + var_types elemType, + ClassLayout* elemLayout, + unsigned elemSize, + unsigned lenOffset, + unsigned elemOffset) : GenTreeOp(GT_INDEX_ADDR, TYP_BYREF, arr, ind) - , gtStructElemClass(structElemClass) + , gtElemLayout(gtElemLayout) , gtIndRngFailBB(nullptr) , gtElemType(elemType) , gtElemSize(elemSize) diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 6d7897f7192d..632c0038679d 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -5588,18 +5588,21 @@ GenTree* Compiler::fgMorphArrayIndex(GenTree* tree) GenTreeIndex* asIndex = tree->AsIndex(); var_types elemTyp = tree->TypeGet(); + ClassLayout* elemLayout; unsigned elemSize; CORINFO_CLASS_HANDLE elemStructType; if (elemTyp != TYP_STRUCT) { + elemLayout = nullptr; elemSize = genTypeSize(elemTyp); elemStructType = NO_CLASS_HANDLE; } else { - elemSize = tree->AsIndex()->GetLayout()->GetSize(); - elemStructType = tree->AsIndex()->GetLayout()->GetClassHandle(); + elemLayout = tree->AsIndex()->GetLayout(); + elemSize = elemLayout->GetSize(); + elemStructType = elemLayout->GetClassHandle(); assert(elemStructType != NO_CLASS_HANDLE); } @@ -5667,7 +5670,7 @@ GenTree* Compiler::fgMorphArrayIndex(GenTree* tree) GenTree* const index = fgMorphTree(asIndex->Index()); GenTreeIndexAddr* const indexAddr = - new (this, GT_INDEX_ADDR) GenTreeIndexAddr(array, index, elemTyp, elemStructType, elemSize, + new (this, GT_INDEX_ADDR) GenTreeIndexAddr(array, index, elemTyp, elemLayout, elemSize, static_cast(lenOffs), static_cast(elemOffs)); indexAddr->gtFlags |= (array->gtFlags | index->gtFlags) & GTF_ALL_EFFECT;