Skip to content

Commit

Permalink
JIT: allow slightly more general promotion of structs with struct fields
Browse files Browse the repository at this point in the history
For a while now the jit has been able to promote an outer struct A with an
inner struct field B that itself has a single non-struct field C, provided
that C occupies all of B and that C and B are pointer-sized.

For example, this comes up when supporting promotion of `Span<T>`, as a span
contains a `ByReference<T>` field that itself contains a pointer-sized field.

This change relaxes the constraints slightly, allowing B and C to be less than
pointer sized, provided C still occupies all of B, and B is suitably aligned
within A.

Doing so allows promotion of the new `Range` type, which contains two `Index`
fields that each wrap an `int`. This improves performance for uses of `Range`
for simple examples like those in #22079.
  • Loading branch information
AndyAyersMS committed Feb 26, 2019
1 parent fae2a56 commit 2e40dc9
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2020,13 +2020,26 @@ bool Compiler::StructPromotionHelper::TryPromoteStructField(lvaStructFieldInfo&
//
// TODO-CQ: Right now we only promote an actual SIMD typed field, which would cause
// a nested SIMD type to fail promotion.
if (fieldSize == 0 || fieldSize != TARGET_POINTER_SIZE || varTypeIsFloating(fieldVarType))
if (fieldSize == 0 || fieldSize > TARGET_POINTER_SIZE || varTypeIsFloating(fieldVarType))
{
JITDUMP("Promotion blocked: struct contains struct field with one field,"
" but that field has invalid size or type");
return false;
}

if (fieldSize != TARGET_POINTER_SIZE)
{
unsigned outerFieldOffset = compHandle->getFieldOffset(fieldInfo.fldHnd);

if ((outerFieldOffset % fieldSize) != 0)
{
JITDUMP("Promotion blocked: struct contains struct field with one field,"
" but the outer struct offset %u is not a multiple of the inner field size %u",
outerFieldOffset, fieldSize);
return false;
}
}

// Insist this wrapped field occupy all of its parent storage.
unsigned innerStructSize = compHandle->getClassSize(fieldInfo.fldTypeHnd);

Expand Down

0 comments on commit 2e40dc9

Please sign in to comment.