Skip to content

Commit

Permalink
Use a simple temp instead of InlineArray1 (#73086)
Browse files Browse the repository at this point in the history
  • Loading branch information
RikkiGibson authored May 8, 2024
1 parent 593ab79 commit 24fa558
Show file tree
Hide file tree
Showing 8 changed files with 1,072 additions and 850 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,7 @@ private BoundExpression VisitArrayOrSpanCollectionExpression(BoundCollectionExpr
syntax,
elementType,
elements,
asReadOnlySpan: collectionTypeKind == CollectionExpressionTypeKind.ReadOnlySpan,
_additionalLocals);
asReadOnlySpan: collectionTypeKind == CollectionExpressionTypeKind.ReadOnlySpan);
}

Debug.Assert(IsAllocatingRefStructCollectionExpression(node, collectionTypeKind, elementType.Type, _compilation));
Expand Down Expand Up @@ -243,7 +242,7 @@ private BoundExpression VisitCollectionInitializerCollectionExpression(BoundColl

// Create a temp for the collection.
BoundAssignmentOperator assignmentToTemp;
BoundLocal temp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp, isKnownToReferToTempIfReferenceType: true);
BoundLocal temp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp);
var sideEffects = ArrayBuilder<BoundExpression>.GetInstance(elements.Length + 1);
sideEffects.Add(assignmentToTemp);

Expand Down Expand Up @@ -429,16 +428,33 @@ private BoundExpression CreateAndPopulateSpanFromInlineArray(
SyntaxNode syntax,
TypeWithAnnotations elementType,
ImmutableArray<BoundNode> elements,
bool asReadOnlySpan,
ArrayBuilder<LocalSymbol> locals)
bool asReadOnlySpan)
{
Debug.Assert(elements.Length > 0);
Debug.Assert(elements.All(e => e is BoundExpression));
Debug.Assert(_factory.ModuleBuilderOpt is { });
Debug.Assert(_diagnostics.DiagnosticBag is { });
Debug.Assert(_compilation.Assembly.RuntimeSupportsInlineArrayTypes);
Debug.Assert(_additionalLocals is { });

int arrayLength = elements.Length;
if (arrayLength == 1
&& _factory.WellKnownMember(asReadOnlySpan
? WellKnownMember.System_ReadOnlySpan_T__ctor_ref_readonly_T
: WellKnownMember.System_Span_T__ctor_ref_T, isOptional: true) is MethodSymbol spanRefConstructor)
{
// Special case: no need to create an InlineArray1 type. Just use a temp of the element type.
var spanType = _factory
.WellKnownType(asReadOnlySpan ? WellKnownType.System_ReadOnlySpan_T : WellKnownType.System_Span_T)
.Construct([elementType]);
var constructor = spanRefConstructor.AsMember(spanType);
var element = VisitExpression((BoundExpression)elements[0]);
var temp = _factory.StoreToTemp(element, out var assignment);
_additionalLocals.Add(temp.LocalSymbol);
var call = _factory.New(constructor, arguments: [temp], argumentRefKinds: [asReadOnlySpan ? RefKindExtensions.StrictIn : RefKind.Ref]);
return _factory.Sequence([assignment], call);
}

var inlineArrayType = _factory.ModuleBuilderOpt.EnsureInlineArrayTypeExists(syntax, _factory, arrayLength, _diagnostics.DiagnosticBag).Construct(ImmutableArray.Create(elementType));
Debug.Assert(inlineArrayType.HasInlineArrayAttribute(out int inlineArrayLength) && inlineArrayLength == arrayLength);

Expand All @@ -449,10 +465,10 @@ private BoundExpression CreateAndPopulateSpanFromInlineArray(
// Create an inline array and assign to a local.
// var tmp = new <>y__InlineArrayN<ElementType>();
BoundAssignmentOperator assignmentToTemp;
BoundLocal inlineArrayLocal = _factory.StoreToTemp(new BoundDefaultExpression(syntax, inlineArrayType), out assignmentToTemp, isKnownToReferToTempIfReferenceType: true);
BoundLocal inlineArrayLocal = _factory.StoreToTemp(new BoundDefaultExpression(syntax, inlineArrayType), out assignmentToTemp);
var sideEffects = ArrayBuilder<BoundExpression>.GetInstance();
sideEffects.Add(assignmentToTemp);
locals.Add(inlineArrayLocal.LocalSymbol);
_additionalLocals.Add(inlineArrayLocal.LocalSymbol);

// Populate the inline array.
// InlineArrayElementRef<<>y__InlineArrayN<ElementType>, ElementType>(ref tmp, 0) = element0;
Expand Down Expand Up @@ -604,8 +620,7 @@ bool tryGetToArrayMethod(TypeSymbol spreadTypeOriginalDefinition, WellKnownType
// int index = 0;
BoundLocal indexTemp = _factory.StoreToTemp(
_factory.Literal(0),
out assignmentToTemp,
isKnownToReferToTempIfReferenceType: true);
out assignmentToTemp);
localsBuilder.Add(indexTemp);
sideEffects.Add(assignmentToTemp);

Expand All @@ -615,8 +630,7 @@ bool tryGetToArrayMethod(TypeSymbol spreadTypeOriginalDefinition, WellKnownType
ImmutableArray.Create(GetKnownLengthExpression(elements, numberIncludingLastSpread, localsBuilder)),
initializerOpt: null,
arrayType),
out assignmentToTemp,
isKnownToReferToTempIfReferenceType: true);
out assignmentToTemp);
localsBuilder.Add(arrayTemp);
sideEffects.Add(assignmentToTemp);

Expand Down Expand Up @@ -903,7 +917,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty
// If we use optimizations, we know the length of the resulting list, and we store it in a temp so we can pass it to List.ctor(int32) and to CollectionsMarshal.SetCount

// int knownLengthTemp = N + s1.Length + ...;
knownLengthTemp = _factory.StoreToTemp(knownLengthExpression, out assignmentToTemp, isKnownToReferToTempIfReferenceType: true);
knownLengthTemp = _factory.StoreToTemp(knownLengthExpression, out assignmentToTemp);
localsBuilder.Add(knownLengthTemp);
sideEffects.Add(assignmentToTemp);

Expand All @@ -924,7 +938,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty
}

// Create a temp for the list.
BoundLocal listTemp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp, isKnownToReferToTempIfReferenceType: true);
BoundLocal listTemp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp);
localsBuilder.Add(listTemp);
sideEffects.Add(assignmentToTemp);

Expand All @@ -940,7 +954,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty
sideEffects.Add(_factory.Call(receiver: null, setCount, listTemp, knownLengthTemp));

// var span = CollectionsMarshal.AsSpan<ElementType(list);
BoundLocal spanTemp = _factory.StoreToTemp(_factory.Call(receiver: null, asSpan, listTemp), out assignmentToTemp, isKnownToReferToTempIfReferenceType: true);
BoundLocal spanTemp = _factory.StoreToTemp(_factory.Call(receiver: null, asSpan, listTemp), out assignmentToTemp);
localsBuilder.Add(spanTemp);
sideEffects.Add(assignmentToTemp);

Expand All @@ -950,8 +964,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty
// int index = 0;
BoundLocal indexTemp = _factory.StoreToTemp(
_factory.Literal(0),
out assignmentToTemp,
isKnownToReferToTempIfReferenceType: true);
out assignmentToTemp);
localsBuilder.Add(indexTemp);
sideEffects.Add(assignmentToTemp);

Expand Down Expand Up @@ -1061,7 +1074,7 @@ private void RewriteCollectionExpressionElementsIntoTemporaries(
{
var rewrittenExpression = RewriteCollectionExpressionElementExpression(elements[i]);
BoundAssignmentOperator assignmentToTemp;
BoundLocal temp = _factory.StoreToTemp(rewrittenExpression, out assignmentToTemp, isKnownToReferToTempIfReferenceType: true);
BoundLocal temp = _factory.StoreToTemp(rewrittenExpression, out assignmentToTemp);
locals.Add(temp);
sideEffects.Add(assignmentToTemp);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,21 @@ public BoundObjectCreationExpression New(NamedTypeSymbol type, ImmutableArray<Bo
public BoundObjectCreationExpression New(MethodSymbol ctor, ImmutableArray<BoundExpression> args)
=> new BoundObjectCreationExpression(Syntax, ctor, args) { WasCompilerGenerated = true };

public BoundObjectCreationExpression New(MethodSymbol constructor, ImmutableArray<BoundExpression> arguments, ImmutableArray<RefKind> argumentRefKinds)
=> new BoundObjectCreationExpression(
Syntax,
constructor,
arguments,
argumentNamesOpt: default,
argumentRefKinds,
expanded: false,
argsToParamsOpt: default,
defaultArguments: default,
constantValueOpt: null,
initializerExpressionOpt: null,
constructor.ContainingType)
{ WasCompilerGenerated = true };

public BoundObjectCreationExpression New(WellKnownMember wm, ImmutableArray<BoundExpression> args)
{
var ctor = WellKnownMethod(wm);
Expand Down
Loading

0 comments on commit 24fa558

Please sign in to comment.