Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,8 @@ class LclVarDsc
lvStkOffs = offset;
}

unsigned lvExactSize() const;
unsigned lvExactSize() const;
ValueSize lvValueSize() const;

unsigned lvSlotNum; // original slot # (if remapped)

Expand Down Expand Up @@ -3679,8 +3680,8 @@ class Compiler
bool gtSplitTree(
BasicBlock* block, Statement* stmt, GenTree* splitPoint, Statement** firstNewStmt, GenTree*** splitPointUse, bool early = false);

bool gtStoreDefinesField(
LclVarDsc* fieldVarDsc, ssize_t offset, unsigned size, ssize_t* pFieldStoreOffset, unsigned* pFieldStoreSize);
bool gtStoreMayDefineField(
LclVarDsc* fieldVarDsc, ssize_t offset, ValueSize size, ssize_t* pFieldRelativeOffset, ValueSize* pFieldAffectedBytes);

void gtPeelOffsets(GenTree** addr, target_ssize_t* offset, FieldSeq** fldSeq = nullptr) const;

Expand Down Expand Up @@ -4203,6 +4204,7 @@ class Compiler

unsigned lvaLclStackHomeSize(unsigned varNum);
unsigned lvaLclExactSize(unsigned varNum);
ValueSize lvaLclValueSize(unsigned varNum);

bool lvaHaveManyLocals(float percent = 1.0f) const;

Expand Down Expand Up @@ -5789,18 +5791,18 @@ class Compiler
void fgValueNumberLocalStore(GenTree* storeNode,
GenTreeLclVarCommon* lclDefNode,
ssize_t offset,
unsigned storeSize,
ValueSize storeSize,
ValueNumPair value,
bool normalize = true);

void fgValueNumberArrayElemLoad(GenTree* loadTree, VNFuncApp* addrFunc);

void fgValueNumberArrayElemStore(GenTree* storeNode, VNFuncApp* addrFunc, unsigned storeSize, ValueNum value);
void fgValueNumberArrayElemStore(GenTree* storeNode, VNFuncApp* addrFunc, ValueSize storeSize, ValueNum value);

void fgValueNumberFieldLoad(GenTree* loadTree, GenTree* baseAddr, FieldSeq* fieldSeq, ssize_t offset);

void fgValueNumberFieldStore(
GenTree* storeNode, GenTree* baseAddr, FieldSeq* fieldSeq, ssize_t offset, unsigned storeSize, ValueNum value);
GenTree* storeNode, GenTree* baseAddr, FieldSeq* fieldSeq, ssize_t offset, ValueSize storeSize, ValueNum value);

static bool fgGetStaticFieldSeqAndAddress(ValueNumStore* vnStore, GenTree* tree, ssize_t* byteOffset, FieldSeq** pFseq);

Expand Down
17 changes: 14 additions & 3 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,11 @@ extern const BYTE genTypeStSzs[TYP_COUNT];
template <class T>
inline unsigned genTypeStSz(T value)
{
#ifdef TARGET_ARM64
// The size of these types cannot be evaluated in static contexts.
assert(TypeGet(value) != TYP_SIMD);
assert(TypeGet(value) != TYP_MASK);
#endif
assert((unsigned)TypeGet(value) < ArrLen(genTypeStSzs));

return genTypeStSzs[TypeGet(value)];
Expand Down Expand Up @@ -3415,6 +3420,12 @@ inline bool Compiler::fgIsBigOffset(size_t offset)
//
inline bool Compiler::IsValidLclAddr(unsigned lclNum, unsigned offset)
{
#ifdef TARGET_ARM64
if (varTypeHasUnknownSize(lvaGetDesc(lclNum)))
{
return false;
}
#endif
return (offset < UINT16_MAX) && (offset < lvaLclExactSize(lclNum));
}

Expand Down Expand Up @@ -4675,13 +4686,13 @@ GenTree::VisitResult GenTree::VisitLocalDefs(Compiler* comp, TVisitor visitor)
{
if (OperIs(GT_STORE_LCL_VAR))
{
unsigned size = comp->lvaLclExactSize(AsLclVarCommon()->GetLclNum());
ValueSize size = comp->lvaLclValueSize(AsLclVarCommon()->GetLclNum());
return visitor(LocalDef(AsLclVarCommon(), /* isEntire */ true, 0, size));
}
if (OperIs(GT_STORE_LCL_FLD))
{
GenTreeLclFld* fld = AsLclFld();
return visitor(LocalDef(fld, !fld->IsPartialLclFld(comp), fld->GetLclOffs(), fld->GetSize()));
return visitor(LocalDef(fld, !fld->IsPartialLclFld(comp), fld->GetLclOffs(), fld->GetValueSize()));
}
if (OperIs(GT_CALL))
{
Expand All @@ -4693,7 +4704,7 @@ GenTree::VisitResult GenTree::VisitLocalDefs(Compiler* comp, TVisitor visitor)

bool isEntire = storeSize == comp->lvaLclExactSize(lclAddr->GetLclNum());

return visitor(LocalDef(lclAddr, isEntire, lclAddr->GetLclOffs(), storeSize));
return visitor(LocalDef(lclAddr, isEntire, lclAddr->GetLclOffs(), ValueSize(storeSize)));
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4291,14 +4291,14 @@ class SsaCheckVisitor : public GenTreeVisitor<SsaCheckVisitor>
LclVarDsc* const fieldVarDsc = m_compiler->lvaGetDesc(fieldLclNum);
unsigned const fieldSsaNum = def.Def->GetSsaNum(m_compiler, index);

ssize_t fieldStoreOffset;
unsigned fieldStoreSize;
if (m_compiler->gtStoreDefinesField(fieldVarDsc, def.Offset, def.Size, &fieldStoreOffset,
&fieldStoreSize))
ssize_t fieldStoreOffset;
ValueSize fieldStoreSize;
if (m_compiler->gtStoreMayDefineField(fieldVarDsc, def.Offset, def.Size, &fieldStoreOffset,
&fieldStoreSize))
{
ProcessDef(def.Def, fieldLclNum, fieldSsaNum);

if (!ValueNumStore::LoadStoreIsEntire(genTypeSize(fieldVarDsc), fieldStoreOffset,
if (!ValueNumStore::LoadStoreIsEntire(fieldVarDsc->lvValueSize(), fieldStoreOffset,
fieldStoreSize))
{
assert(isUse);
Expand Down
104 changes: 81 additions & 23 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18047,7 +18047,7 @@ bool GenTree::IsLclVarAddr() const
bool GenTree::IsPartialLclFld(Compiler* comp)
{
return OperIs(GT_LCL_FLD, GT_STORE_LCL_FLD) &&
(comp->lvaGetDesc(AsLclFld())->lvExactSize() != AsLclFld()->GetSize());
(comp->lvaGetDesc(AsLclFld())->lvValueSize() != AsLclFld()->GetValueSize());
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -18360,9 +18360,14 @@ ssize_t GenTreeIndir::Offset()
}

unsigned GenTreeIndir::Size() const
{
return ValueSize().GetExact();
}

ValueSize GenTreeIndir::ValueSize() const
{
assert(isIndir() || OperIsBlk());
return OperIsBlk() ? AsBlk()->Size() : genTypeSize(TypeGet());
return OperIsBlk() ? ::ValueSize(AsBlk()->Size()) : ValueSize::FromJitType(TypeGet());
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -19015,38 +19020,68 @@ bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeq** pFldSe
}

//------------------------------------------------------------------------
// gtStoreDefinesField: Does the given parent store modify the given field?
// gtStoreMayDefineField: Does the given parent store modify the given field?
//
// Arguments:
// fieldVarDsc - The field local
// offset - Offset of the store, relative to the parent
// size - Size of the store in bytes
// pFieldStoreOffset - [out] parameter for the store's offset relative
// to the field local itself
// pFieldStoreSize - [out] parameter for the amount of the field's
// local's bytes affected by the store
// fieldVarDsc - The field local
// offset - Offset of the store, relative to the parent
// storeSize - Size of the store in bytes
// pFieldRelativeOffset - [out] parameter for the store's offset relative
// to the field local itself
// pFieldAffectedBytes - [out] parameter for the amount of the field's
// local's bytes affected by the store
//
// Return Value:
// If the given store affects the given field local, "true, "false"
// If the given store may affect the given field local, "true", "false"
// otherwise.
// If it is uncertain whether the store affects the field, the return value is
// "true" and "pFieldAffectedBytes" contains a ValueSize of type "Unknown".
//
bool Compiler::gtStoreDefinesField(
LclVarDsc* fieldVarDsc, ssize_t offset, unsigned size, ssize_t* pFieldStoreOffset, unsigned* pFieldStoreSize)
bool Compiler::gtStoreMayDefineField(LclVarDsc* fieldVarDsc,
ssize_t offset,
ValueSize storeSize,
ssize_t* pFieldRelativeOffset,
ValueSize* pFieldAffectedBytes)
{
ssize_t fieldOffset = fieldVarDsc->lvFldOffset;
unsigned fieldSize = genTypeSize(fieldVarDsc); // No TYP_STRUCT field locals.
ssize_t fieldOffset = fieldVarDsc->lvFldOffset;
ValueSize fieldSize = fieldVarDsc->lvValueSize();

ssize_t storeEndOffset = offset + static_cast<ssize_t>(size);
ssize_t fieldEndOffset = fieldOffset + static_cast<ssize_t>(fieldSize);
if ((fieldOffset < storeEndOffset) && (offset < fieldEndOffset))
if ((offset == fieldOffset) && (fieldSize == storeSize))
{
*pFieldStoreOffset = (offset < fieldOffset) ? 0 : (offset - fieldOffset);
*pFieldStoreSize = static_cast<unsigned>(min(storeEndOffset, fieldEndOffset) - max(offset, fieldOffset));

*pFieldRelativeOffset = 0;
*pFieldAffectedBytes = fieldSize;
return true;
}
else if (fieldSize.IsExact() && storeSize.IsExact())
{
ssize_t storeEndOffset = offset + static_cast<ssize_t>(storeSize.GetExact());
ssize_t fieldEndOffset = fieldOffset + static_cast<ssize_t>(fieldSize.GetExact());
if ((fieldOffset < storeEndOffset) && (offset < fieldEndOffset))
{
*pFieldRelativeOffset = (offset < fieldOffset) ? 0 : (offset - fieldOffset);
*pFieldAffectedBytes =
ValueSize(static_cast<unsigned>(min(storeEndOffset, fieldEndOffset) - max(offset, fieldOffset)));

return false;
return true;
}

return false;
}
else
{
// One of either the field size or store size is inexact, and the store is not entire, which means we
// can't determine precise overlap of the field and store bounds. We assume that this will define the
// field in this situation and allow the caller to decide on what to do with this, based on
// pFieldAffectedBytes having some inexact ValueSize.
//
// TODO-SVE:
// * Can we check against inequalities with vector min/max sizes?
// * Can we check for exact store ranges terminating before the start of the unknown size field?
// * Can we check for exact field ranges terminating before the offset of the store?
*pFieldRelativeOffset = (offset < fieldOffset) ? 0 : (offset - fieldOffset);
*pFieldAffectedBytes = ValueSize::Unknown();
return true;
}
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -31603,7 +31638,12 @@ unsigned GenTreeHWIntrinsic::GetResultOpNumForRmwIntrinsic(GenTree* use, GenTree

unsigned GenTreeLclFld::GetSize() const
{
return TypeIs(TYP_STRUCT) ? GetLayout()->GetSize() : genTypeSize(TypeGet());
return GetValueSize().GetExact();
}

ValueSize GenTreeLclFld::GetValueSize() const
{
return (TypeGet() == TYP_STRUCT) ? ValueSize(GetLayout()->GetSize()) : ValueSize::FromJitType(TypeGet());
}

#ifdef TARGET_ARM
Expand Down Expand Up @@ -34087,3 +34127,21 @@ Statement* Compiler::gtLatestStatement(Statement* stmt1, Statement* stmt2)

assert(!"could not determine latest stmt");
}

ValueSize ValueSize::FromJitType(var_types type)
{
assert(genTypeSize(type) != 0);
switch (type)
{
#ifdef TARGET_ARM64
case TYP_SIMD:
return ValueSize::Vector();
// TODO-SVE: Implement scalable mask
// case TYP_MASK:
// return ValueSize::Mask();
#endif
default:
assert(genTypeSize(type) != SIZE_UNKNOWN);
return ValueSize(genTypeSize(type));
}
}
Loading
Loading