Skip to content

Commit 5a0865c

Browse files
authored
JIT: fix issues in field-wise escape analysis (#114974)
Two fixes: * we can't retype implicit byref gc struct params, as their GC info is reported by the caller. Instead we must mark them as escaping. * when retyping GT_STOREIND we should always use the stored data's new type Fixes #111922.
1 parent 5d42918 commit 5a0865c

File tree

3 files changed

+134
-3
lines changed

3 files changed

+134
-3
lines changed

src/coreclr/jit/objectalloc.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -698,12 +698,27 @@ void ObjectAllocator::MarkEscapingVarsAndBuildConnGraph()
698698
{
699699
JITDUMP(" V%02u is address exposed\n", lclNum);
700700
MarkLclVarAsEscaping(lclNum);
701+
continue;
701702
}
702-
else if (lclNum == comp->info.compRetBuffArg)
703+
704+
if (lclNum == comp->info.compRetBuffArg)
703705
{
704706
JITDUMP(" V%02u is retbuff\n", lclNum);
705707
MarkLclVarAsEscaping(lclNum);
708+
continue;
709+
}
710+
711+
#if FEATURE_IMPLICIT_BYREFS
712+
// We have to mark all implicit byref params as escaping, because
713+
// their GC reporting is controlled by the caller
714+
//
715+
if (lclDsc->lvIsParam && lclDsc->lvIsImplicitByRef)
716+
{
717+
JITDUMP(" V%02u is an implicit byref param\n", lclNum);
718+
MarkLclVarAsEscaping(lclNum);
719+
continue;
706720
}
721+
#endif
707722

708723
// Parameters have unknown initial values.
709724
// OSR locals have unknown initial values.
@@ -2047,8 +2062,7 @@ void ObjectAllocator::UpdateAncestorTypes(GenTree* tree,
20472062

20482063
// If we are storing to a GC struct field, we may need to retype the store
20492064
//
2050-
if (retypeFields && parent->OperIs(GT_STOREIND) && (addr->OperIs(GT_FIELD_ADDR)) &&
2051-
(varTypeIsGC(parent->TypeGet())))
2065+
if (parent->OperIs(GT_STOREIND) && addr->OperIs(GT_FIELD_ADDR) && varTypeIsGC(parent->TypeGet()))
20522066
{
20532067
parent->ChangeType(newType);
20542068
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Reflection;
6+
using System.Diagnostics;
7+
using System.Runtime.CompilerServices;
8+
using Xunit;
9+
10+
class C1
11+
{
12+
public C1(int x) { a = x; b = x; }
13+
public int a;
14+
public int b;
15+
}
16+
17+
struct S1
18+
{
19+
public S1(C1 z) { c = z; }
20+
public int a;
21+
public int b;
22+
public C1 c;
23+
}
24+
25+
public class Runtime_111922
26+
{
27+
[Fact]
28+
public static int Problem()
29+
{
30+
S1 s = new S1(new C1(4));
31+
return 95 + SubProblem(1, s);
32+
}
33+
34+
[MethodImpl(MethodImplOptions.NoInlining)]
35+
static int SubProblem(int x, S1 s)
36+
{
37+
s = new S1(new C1(5));
38+
39+
SideEffect();
40+
41+
C1 v = s.c;
42+
return v.a;
43+
}
44+
45+
[Fact]
46+
public static int Problem1()
47+
{
48+
S1 s = new S1(new C1(4));
49+
return 95 + SubProblem1(1, ref s);
50+
}
51+
52+
[MethodImpl(MethodImplOptions.NoInlining)]
53+
static int SubProblem1(int x, ref S1 s)
54+
{
55+
s = new S1(new C1(5));
56+
57+
SideEffect();
58+
59+
C1 v = s.c;
60+
return v.a;
61+
}
62+
63+
[Fact]
64+
public static int Problem2()
65+
{
66+
S1 s = new S1(new C1(4));
67+
return 91 + SubProblem2(0, s) + SubProblem2(1, s);
68+
}
69+
70+
[MethodImpl(MethodImplOptions.NoInlining)]
71+
static int SubProblem2(int x, S1 s)
72+
{
73+
if (x == 0)
74+
{
75+
s = new S1(new C1(5));
76+
}
77+
78+
SideEffect();
79+
80+
C1 v = s.c;
81+
return v.a;
82+
}
83+
84+
[Fact]
85+
public static int Problem3()
86+
{
87+
C1 c = new C1(6);
88+
return 1 + SubProblem3(0, c, c, c, c, c, c, c, c) + SubProblem3(1, c, c, c, c, c, c, c, c);
89+
}
90+
91+
[MethodImpl(MethodImplOptions.NoInlining)]
92+
static int SubProblem3(int x, C1 c1, C1 c2, C1 c3, C1 c4, C1 c5, C1 c6, C1 c7, C1 c8)
93+
{
94+
if (x == 0)
95+
{
96+
c1 = new C1(7);
97+
c8 = new C1(8);
98+
}
99+
100+
SideEffect();
101+
102+
return c1.a + c2.a + c3.a + c4.a + c5.a + c6.a + c7.a + c8.a;
103+
}
104+
105+
106+
[MethodImpl(MethodImplOptions.NoInlining)]
107+
static void SideEffect() { }
108+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<DebugType>None</DebugType>
4+
<Optimize>True</Optimize>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="$(MSBuildProjectName).cs" />
8+
</ItemGroup>
9+
</Project>

0 commit comments

Comments
 (0)