Skip to content

Commit 1f8253c

Browse files
author
Julien Couvreur
committed
Tweaks
1 parent eb6497d commit 1f8253c

File tree

2 files changed

+65
-12
lines changed

2 files changed

+65
-12
lines changed

src/Compilers/CSharp/Portable/CodeGen/EmitArrayInitializer.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ private bool TryEmitReadonlySpanAsBlobWrapper(NamedTypeSymbol spanType, BoundExp
483483
specialElementType = elementType.EnumUnderlyingTypeOrSelf().SpecialType;
484484
if (!IsTypeAllowedInBlobWrapper(specialElementType))
485485
{
486-
return start is null && length is null && tryEmitAsCachedArrayOfConstants(ac, arrayType, elementType, spanType, used, inPlaceTarget);
486+
return start is null && length is null && tryEmitAsCachedArrayOfConstants(ac, arrayType, elementType, spanType, used, inPlaceTarget, out avoidInPlace);
487487
}
488488

489489
// Get the data and number of elements that compose the initialization.
@@ -678,8 +678,9 @@ bool emitAsCachedArrayFromBlob(NamedTypeSymbol spanType, BoundExpression wrapped
678678
}
679679

680680
// Emit: new ReadOnlySpan<ElementType>(PrivateImplementationDetails.cachingField ??= new ElementType[] { ... constants ... })
681-
bool tryEmitAsCachedArrayOfConstants(BoundArrayCreation arrayCreation, ArrayTypeSymbol arrayType, TypeSymbol elementType, NamedTypeSymbol spanType, bool used, BoundExpression? inPlaceTarget)
681+
bool tryEmitAsCachedArrayOfConstants(BoundArrayCreation arrayCreation, ArrayTypeSymbol arrayType, TypeSymbol elementType, NamedTypeSymbol spanType, bool used, BoundExpression? inPlaceTarget, out bool avoidInPlace)
682682
{
683+
avoidInPlace = false;
683684
var initializer = arrayCreation.InitializerOpt;
684685
if (initializer == null)
685686
{
@@ -707,6 +708,15 @@ bool tryEmitAsCachedArrayOfConstants(BoundArrayCreation arrayCreation, ArrayType
707708
return true;
708709
}
709710

711+
if (inPlaceTarget is not null)
712+
{
713+
// We can use the optimization, but not for in-place initialization. Fail to optimize,
714+
// but tell the caller they can call this again with a null inPlaceTarget, at which point this
715+
// should be able to optimize the call.
716+
avoidInPlace = true;
717+
return false;
718+
}
719+
710720
Cci.IFieldReference cachingField = _builder.module.GetArrayCachingFieldForConstants(constants, _module.Translate(arrayType),
711721
arrayCreation.Syntax, _diagnostics.DiagnosticBag);
712722

src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadOnlySpanConstructionTest.cs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,7 +2657,7 @@ public static int M()
26572657
[InlineData("string", "11")]
26582658
[InlineData("object", "18")]
26592659
[InlineData("C", "18")]
2660-
public void ReadOnlySpanFromArryOfConstants_Null(string type, string typeCode)
2660+
public void ReadOnlySpanFromArrayOfConstants_Null(string type, string typeCode)
26612661
{
26622662
var src = $$"""
26632663
var values = C.M();
@@ -2698,8 +2698,51 @@ .maxstack 2
26982698
verifier.VerifyIL("C.M", expectedIL);
26992699
}
27002700

2701+
[Theory, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2702+
[InlineData("string", "11")]
2703+
[InlineData("object", "18")]
2704+
[InlineData("C", "18")]
2705+
public void ReadOnlySpanFromArrayOfConstants_Null_CollectionExpression(string type, string typeCode)
2706+
{
2707+
var src = $$"""
2708+
System.Console.Write(C.M());
2709+
2710+
public class C
2711+
{
2712+
public static int M()
2713+
{
2714+
System.ReadOnlySpan<{{type}}> values = [ null, null ];
2715+
return values.Length;
2716+
}
2717+
}
2718+
""";
2719+
var compilation = CreateCompilationWithMscorlibAndSpan(src);
2720+
var verifier = CompileAndVerify(compilation, expectedOutput: "2", verify: Verification.Skipped);
2721+
2722+
verifier.VerifyIL("C.M", $$"""
2723+
{
2724+
// Code size 35 (0x23)
2725+
.maxstack 2
2726+
.locals init (System.ReadOnlySpan<{{type}}> V_0) //values
2727+
IL_0000: ldsfld "{{type}}[] <PrivateImplementationDetails>.96A296D224F285C67BEE93C30F8A309157F0DAA35DC5B87E410B78630A09CFC7_B{{typeCode}}"
2728+
IL_0005: dup
2729+
IL_0006: brtrue.s IL_0015
2730+
IL_0008: pop
2731+
IL_0009: ldc.i4.2
2732+
IL_000a: newarr "{{type}}"
2733+
IL_000f: dup
2734+
IL_0010: stsfld "{{type}}[] <PrivateImplementationDetails>.96A296D224F285C67BEE93C30F8A309157F0DAA35DC5B87E410B78630A09CFC7_B{{typeCode}}"
2735+
IL_0015: newobj "System.ReadOnlySpan<{{type}}>..ctor({{type}}[])"
2736+
IL_001a: stloc.0
2737+
IL_001b: ldloca.s V_0
2738+
IL_001d: call "int System.ReadOnlySpan<{{type}}>.Length.get"
2739+
IL_0022: ret
2740+
}
2741+
""");
2742+
}
2743+
27012744
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2702-
public void ReadOnlySpanFromArryOfConstants_OtherStrings()
2745+
public void ReadOnlySpanFromArrayOfConstants_OtherStrings()
27032746
{
27042747
var src = """
27052748
var values = C.M();
@@ -2769,7 +2812,7 @@ .maxstack 4
27692812
}
27702813

27712814
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2772-
public void ReadOnlySpanFromArryOfConstants_VariableStrings()
2815+
public void ReadOnlySpanFromArrayOfConstants_VariableStrings()
27732816
{
27742817
var src = """
27752818
public class C
@@ -2811,7 +2854,7 @@ .locals init (string V_0, //hello
28112854
}
28122855

28132856
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2814-
public void ReadOnlySpanFromArryOfConstants_NoInitializer()
2857+
public void ReadOnlySpanFromArrayOfConstants_NoInitializer()
28152858
{
28162859
var src = """
28172860
public class C
@@ -2828,7 +2871,7 @@ public class C
28282871
}
28292872

28302873
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2831-
public void ReadOnlySpanFromArryOfConstants_NativeInts()
2874+
public void ReadOnlySpanFromArrayOfConstants_NativeInts()
28322875
{
28332876
var src = """
28342877
var values = C.M();
@@ -2871,7 +2914,7 @@ .maxstack 4
28712914
}
28722915

28732916
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2874-
public void ReadOnlySpanFromArryOfConstants_NativeUnsignedInts()
2917+
public void ReadOnlySpanFromArrayOfConstants_NativeUnsignedInts()
28752918
{
28762919
var src = """
28772920
var values = C.M();
@@ -2914,7 +2957,7 @@ .maxstack 4
29142957
}
29152958

29162959
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2917-
public void ReadOnlySpanFromArryOfConstants_Decimals()
2960+
public void ReadOnlySpanFromArrayOfConstants_Decimals()
29182961
{
29192962
var src = """
29202963
var values = C.M();
@@ -2956,7 +2999,7 @@ .maxstack 4
29562999
}
29573000

29583001
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2959-
public void ReadOnlySpanFromArryOfConstants_DateTime_NotConstant()
3002+
public void ReadOnlySpanFromArrayOfConstants_DateTime_NotConstant()
29603003
{
29613004
var src = """
29623005
using System;
@@ -2990,7 +3033,7 @@ .maxstack 4
29903033
}
29913034

29923035
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
2993-
public void ReadOnlySpanFromArryOfConstants_DateTime_WithConst()
3036+
public void ReadOnlySpanFromArrayOfConstants_DateTime_WithConst()
29943037
{
29953038
var src = """
29963039
using System;
@@ -3013,7 +3056,7 @@ public class C
30133056
}
30143057

30153058
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")]
3016-
public void ReadOnlySpanFromArryOfConstants_WithoutConst()
3059+
public void ReadOnlySpanFromArrayOfConstants_WithoutConst()
30173060
{
30183061
var src = """
30193062
public struct S { public int i; }

0 commit comments

Comments
 (0)