Skip to content

Conversation

@AndyAyersMS
Copy link
Member

If there is a tail recursive call site, the jit will mark all blocks
from method entry to the block with the call as "in a loop," anticipating
a tail recursive call to loop optimization.

Because of some confusing naming we were doing this even for recursive calls
that were not tail calls. Upshot is that blocks were marked as being in loops
when they weren't, and (among other things) this made the inliner more
aggressive for calls in those blocks.

If there is a tail recursive call site, the jit will mark all blocks
from method entry to the block with the call as "in a loop," anticipating
a tail recursive call to loop optimization.

Because of some confusing naming we were doing this even for recursive calls
that were not tail calls. Upshot is that blocks were marked as being in loops
when they weren't, and (among other things) this made the inliner more
aggressive for calls in those blocks.
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 12, 2020
@AndyAyersMS
Copy link
Member Author

AndyAyersMS commented Mar 12, 2020

@dotnet/jit-contrib PTAL.

This fixes an issue I ran into while working on on stack replacement, see these review comments.

I'll mark the one semantic change with a review comment; the remainder is renaming and compressing some dumps via JITDUMP.

Jit-diffs shows reduction in code size. At first glance most of this is because the jit is doing fewer inlines as fewer blocks in recursive methods are considered to be "in a loop."

PMI CodeSize Diffs for System.Private.CoreLib.dll, framework assemblies for x64 default jit
Summary of Code Size diffs:
(Lower is better)
Total bytes of diff: -33810 (-0.07% of base)
    diff is an improvement.
Top file regressions (bytes):
          57 : Newtonsoft.Json.Bson.dasm (0.06% of base)
           5 : xunit.assert.dasm (0.00% of base)
           5 : xunit.core.dasm (0.01% of base)
Top file improvements (bytes):
      -13569 : System.Private.Xml.dasm (-0.38% of base)
       -6637 : Microsoft.CodeAnalysis.VisualBasic.dasm (-0.12% of base)
       -3632 : Microsoft.CodeAnalysis.CSharp.dasm (-0.08% of base)
       -2019 : Microsoft.Diagnostics.Tracing.TraceEvent.dasm (-0.07% of base)
       -1218 : System.Reflection.Metadata.dasm (-0.28% of base)
       -1195 : System.Configuration.ConfigurationManager.dasm (-0.34% of base)
       -1017 : System.Private.CoreLib.dasm (-0.02% of base)
        -882 : Microsoft.CodeAnalysis.dasm (-0.05% of base)
        -861 : Newtonsoft.Json.dasm (-0.10% of base)
        -610 : System.Data.Common.dasm (-0.04% of base)
        -515 : System.Collections.Immutable.dasm (-0.05% of base)
        -361 : System.Reflection.MetadataLoadContext.dasm (-0.20% of base)
        -256 : System.Runtime.Numerics.dasm (-0.35% of base)
        -219 : System.Private.DataContractSerialization.dasm (-0.03% of base)
        -134 : Microsoft.VisualBasic.Core.dasm (-0.03% of base)
        -116 : System.Linq.Expressions.dasm (-0.02% of base)
        -109 : System.Diagnostics.PerformanceCounter.dasm (-0.13% of base)
         -87 : System.Diagnostics.Process.dasm (-0.10% of base)
         -80 : System.IO.FileSystem.dasm (-0.08% of base)
         -56 : System.Drawing.Common.dasm (-0.02% of base)
32 total files with Code Size differences (29 improved, 3 regressed), 199 unchanged.
Top method regressions (bytes):
          62 (27.56% of base) : Microsoft.CodeAnalysis.dasm - SyntaxWalker:Visit(SyntaxNode):this
          46 ( 2.70% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - VisualBasicSyntaxNode:FindTriviaByOffset(SyntaxNode,int,Func`2):SyntaxTrivia
          43 ( 2.40% of base) : Newtonsoft.Json.Bson.dasm - BsonBinaryWriter:WriteTokenInternal(BsonToken):this
          43 ( 1.93% of base) : Newtonsoft.Json.dasm - BsonBinaryWriter:WriteTokenInternal(BsonToken):this
          40 ( 5.52% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - AsyncMethodToClassRewriter:TypeNeedsClearing(TypeSymbol):bool:this
          39 ( 5.24% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - VisualBasicSyntaxNode:GetFirstDirective(Func`2):DirectiveTriviaSyntax:this
          37 ( 3.52% of base) : Newtonsoft.Json.dasm - JsonSchemaModelBuilder:BuildNodeModel(JsonSchemaNode):JsonSchemaModel:this
          23 ( 4.45% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - LambdaRewriter:FramePointer(VisualBasicSyntaxNode,NamedTypeSymbol):BoundExpression:this
          21 ( 6.84% of base) : System.Private.Xml.dasm - XmlILVisitor:CachesResult(QilNode):bool:this
          14 ( 1.19% of base) : Newtonsoft.Json.Bson.dasm - BsonBinaryWriter:CalculateSize(BsonToken):int:this
          14 ( 1.19% of base) : Newtonsoft.Json.dasm - BsonBinaryWriter:CalculateSize(BsonToken):int:this
          13 ( 4.26% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - DataFlowPass:IsEmptyStructType(TypeSymbol):bool:this
          12 ( 6.52% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - TypeCompilationState:CallsInitializeComponent(MethodSymbol,HashSet`1):bool:this
           7 ( 1.81% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - LocalRewriter:LocalOrFieldNeedsToBeCleanedUp(TypeSymbol):bool:this
           5 ( 1.86% of base) : Microsoft.CodeAnalysis.dasm - MetadataWriter:GetImportScopeIndex(IImportScope,Dictionary`2):int:this
           5 ( 3.45% of base) : System.IO.Packaging.dasm - CompatibilityScope:ShouldProcessContent(String,String):bool:this
           5 ( 0.67% of base) : xunit.assert.dasm - ArgumentFormatter:FormatTypeName(Type):String
           5 ( 0.67% of base) : xunit.core.dasm - ArgumentFormatter:FormatTypeName(Type):String
           5 ( 0.67% of base) : xunit.execution.dotnet.dasm - ArgumentFormatter:FormatTypeName(Type):String
           3 ( 0.28% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - CodeGenerator:EmitAllElementInitializersRecursive(ArrayTypeSymbol,ArrayBuilder`1,bool):this
Top method improvements (bytes):
       -1251 (-50.10% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - DataFlowPass:MakeSlotsForExpression(BoundExpression):SlotCollection:this
       -1226 (-53.80% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Binder:ReclassifyInvocationExpressionAsStatement(BoundExpression,DiagnosticBag):BoundExpression:this
        -844 (-29.57% of base) : System.Private.Xml.dasm - SchemaCollectionPreprocessor:PreprocessSimpleType(XmlSchemaSimpleType,bool):this
        -838 (-29.65% of base) : System.Private.Xml.dasm - Preprocessor:PreprocessSimpleType(XmlSchemaSimpleType,bool):this
        -835 (-21.90% of base) : System.Private.Xml.dasm - Compiler:CompileElement(XmlSchemaElement):this
        -833 (-13.60% of base) : System.Private.CoreLib.dasm - DateTimeParse:ParseByFormat(byref,byref,byref,DateTimeFormatInfo,byref):bool
        -826 (-22.77% of base) : System.Private.Xml.dasm - SchemaCollectionCompiler:CompileElement(XmlSchemaElement):this
        -710 (-40.85% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - CodeGenerator:EmitStore(BoundExpression):this
        -659 (-45.73% of base) : Microsoft.CodeAnalysis.CSharp.dasm - CodeGenerator:EmitStore(BoundAssignmentOperator):this
        -639 (-6.31% of base) : System.Configuration.ConfigurationManager.dasm - ConfigurationElement:DeserializeElement(XmlReader,bool):this
        -605 (-34.97% of base) : Microsoft.CodeAnalysis.CSharp.dasm - LocalRewriter:MakeConversion(CSharpSyntaxNode,BoundExpression,Conversion,TypeSymbol,bool,bool,ConstantValue):BoundExpression:this
        -573 (-60.38% of base) : Microsoft.CodeAnalysis.dasm - AnalyzerFileReference:GetFullyQualifiedTypeName(TypeDefinition,PEModule):String
        -465 (-43.26% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - SymbolDisplayVisitor:VisitNamespace(INamespaceSymbol,String):this
        -448 (-19.67% of base) : System.Private.Xml.dasm - SchemaCollectionCompiler:CompileSimpleType(XmlSchemaSimpleType):this
        -439 (-16.28% of base) : Newtonsoft.Json.dasm - JsonSchemaGenerator:GenerateInternal(Type,int,bool):JsonSchema:this
        -436 (-18.96% of base) : System.Private.Xml.dasm - Compiler:CompileSimpleType(XmlSchemaSimpleType):this
        -432 (-20.11% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Binder:ReclassifyExpression(BoundExpression,DiagnosticBag):BoundExpression:this
        -374 (-11.77% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - VBSemanticModel:GetSemanticSymbols(BoundNodeSummary,Binder,int,byref,byref):ImmutableArray`1:this
        -366 (-25.33% of base) : Microsoft.CodeAnalysis.CSharp.dasm - SyntaxEquivalence:AreEquivalentRecursive(GreenNode,GreenNode,Func`2,bool):bool
        -361 (-45.12% of base) : System.Reflection.MetadataLoadContext.dasm - EcmaToStringHelpers:ToTypeString(TypeDefinitionHandle,MetadataReader):String
Top method regressions (percentages):
          62 (27.56% of base) : Microsoft.CodeAnalysis.dasm - SyntaxWalker:Visit(SyntaxNode):this
          21 ( 6.84% of base) : System.Private.Xml.dasm - XmlILVisitor:CachesResult(QilNode):bool:this
          12 ( 6.52% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - TypeCompilationState:CallsInitializeComponent(MethodSymbol,HashSet`1):bool:this
          40 ( 5.52% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - AsyncMethodToClassRewriter:TypeNeedsClearing(TypeSymbol):bool:this
          39 ( 5.24% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - VisualBasicSyntaxNode:GetFirstDirective(Func`2):DirectiveTriviaSyntax:this
          23 ( 4.45% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - LambdaRewriter:FramePointer(VisualBasicSyntaxNode,NamedTypeSymbol):BoundExpression:this
          13 ( 4.26% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - DataFlowPass:IsEmptyStructType(TypeSymbol):bool:this
          37 ( 3.52% of base) : Newtonsoft.Json.dasm - JsonSchemaModelBuilder:BuildNodeModel(JsonSchemaNode):JsonSchemaModel:this
           5 ( 3.45% of base) : System.IO.Packaging.dasm - CompatibilityScope:ShouldProcessContent(String,String):bool:this
          46 ( 2.70% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - VisualBasicSyntaxNode:FindTriviaByOffset(SyntaxNode,int,Func`2):SyntaxTrivia
          43 ( 2.40% of base) : Newtonsoft.Json.Bson.dasm - BsonBinaryWriter:WriteTokenInternal(BsonToken):this
          43 ( 1.93% of base) : Newtonsoft.Json.dasm - BsonBinaryWriter:WriteTokenInternal(BsonToken):this
           5 ( 1.86% of base) : Microsoft.CodeAnalysis.dasm - MetadataWriter:GetImportScopeIndex(IImportScope,Dictionary`2):int:this
           7 ( 1.81% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - LocalRewriter:LocalOrFieldNeedsToBeCleanedUp(TypeSymbol):bool:this
          14 ( 1.19% of base) : Newtonsoft.Json.Bson.dasm - BsonBinaryWriter:CalculateSize(BsonToken):int:this
          14 ( 1.19% of base) : Newtonsoft.Json.dasm - BsonBinaryWriter:CalculateSize(BsonToken):int:this
           5 ( 0.67% of base) : xunit.assert.dasm - ArgumentFormatter:FormatTypeName(Type):String
           5 ( 0.67% of base) : xunit.core.dasm - ArgumentFormatter:FormatTypeName(Type):String
           5 ( 0.67% of base) : xunit.execution.dotnet.dasm - ArgumentFormatter:FormatTypeName(Type):String
           3 ( 0.28% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - CodeGenerator:EmitAllElementInitializersRecursive(ArrayTypeSymbol,ArrayBuilder`1,bool):this
Top method improvements (percentages):
        -573 (-60.38% of base) : Microsoft.CodeAnalysis.dasm - AnalyzerFileReference:GetFullyQualifiedTypeName(TypeDefinition,PEModule):String
       -1226 (-53.80% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Binder:ReclassifyInvocationExpressionAsStatement(BoundExpression,DiagnosticBag):BoundExpression:this
       -1251 (-50.10% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - DataFlowPass:MakeSlotsForExpression(BoundExpression):SlotCollection:this
        -659 (-45.73% of base) : Microsoft.CodeAnalysis.CSharp.dasm - CodeGenerator:EmitStore(BoundAssignmentOperator):this
        -361 (-45.12% of base) : System.Reflection.MetadataLoadContext.dasm - EcmaToStringHelpers:ToTypeString(TypeDefinitionHandle,MetadataReader):String
        -465 (-43.26% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - SymbolDisplayVisitor:VisitNamespace(INamespaceSymbol,String):this
        -710 (-40.85% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - CodeGenerator:EmitStore(BoundExpression):this
         -56 (-37.84% of base) : System.Drawing.Common.dasm - GraphicsContext:Dispose(bool):this
        -239 (-35.78% of base) : System.Private.Xml.dasm - XPathParser`1:ParseRelativeLocationPath():ubyte:this
        -239 (-35.78% of base) : System.Private.Xml.dasm - XPathParser`1:ParseRelativeLocationPath():short:this
        -239 (-35.78% of base) : System.Private.Xml.dasm - XPathParser`1:ParseRelativeLocationPath():int:this
        -239 (-35.46% of base) : System.Private.Xml.dasm - XPathPatternParser:ParseRelativePathPattern():QilNode:this
        -239 (-35.46% of base) : System.Private.Xml.dasm - XPathParser`1:ParseRelativeLocationPath():long:this
         -48 (-35.29% of base) : Microsoft.CodeAnalysis.CSharp.dasm - DirectiveParser:ParseLogicalNot():ExpressionSyntax:this
        -116 (-35.05% of base) : System.Linq.Expressions.dasm - Expression:GetUserDefinedBinaryOperator(int,Type,Type,String):MethodInfo
        -605 (-34.97% of base) : Microsoft.CodeAnalysis.CSharp.dasm - LocalRewriter:MakeConversion(CSharpSyntaxNode,BoundExpression,Conversion,TypeSymbol,bool,bool,ConstantValue):BoundExpression:this
        -245 (-34.70% of base) : System.Private.Xml.dasm - XPathParser`1:ParseRelativeLocationPath():double:this
        -235 (-31.84% of base) : System.Private.Xml.dasm - XPathParser`1:ParseSubExpr(int):ubyte:this
        -235 (-31.84% of base) : System.Private.Xml.dasm - XPathParser`1:ParseSubExpr(int):short:this
        -235 (-31.84% of base) : System.Private.Xml.dasm - XPathParser`1:ParseSubExpr(int):int:this
238 total methods with Code Size differences (218 improved, 20 regressed), 240241 unchanged.


// A tail recursive call is a potential loop from the current block to the start of the method.
if (canTailCall && gtIsRecursiveCall(methHnd))
if ((tailCallFlags != 0) && canTailCall && gtIsRecursiveCall(methHnd))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual fix -- canTailCall is set to true at the top of a method, and so might still be true when we reach this point for calls that are not tail calls. So we need to also check if this call is a tail call.

Copy link
Contributor

@CarolEidt CarolEidt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I gather you've sampled to diffs to ensure that they are as expected?

@AndyAyersMS
Copy link
Member Author

I gather you've sampled to diffs to ensure that they are as expected?

Wasn't sure what to expect. Checked what I hope is a representative sample; all of the diffs I saw were from less inlining, and quite often, from less inlining on exception paths. Here's an example from System.Private.Xml:

        mov      rcx, 0xD1FFAB1E
        call     CORINFO_HELP_NEWSFAST
        mov      rdi, rax
-       mov      rcx, rsi
-       xor      rdx, rdx
-       call     XPathException:CreateMessage(String,ref):String
-       mov      dword ptr [rdi+112], 0xD1FFAB1E
-       mov      dword ptr [rdi+116], 0xD1FFAB1E
-       lea      rcx, bword ptr [rdi+16]
-       mov      rdx, rax
-       call     CORINFO_HELP_ASSIGN_REF
-       xor      rdx, rdx
-       mov      gword ptr [rdi+32], rdx
-       mov      dword ptr [rdi+116], 0xD1FFAB1E
-       mov      dword ptr [rdi+116], 0xD1FFAB1E
-       lea      rcx, bword ptr [rdi+120]
+       mov      rcx, rdi
        mov      rdx, rsi
-       call     CORINFO_HELP_ASSIGN_REF
-       xor      rcx, rcx
-       mov      gword ptr [rdi+128], rcx
+       xor      r8, r8
+       xor      r9, r9
+       call     XPathException:.ctor(String,ref,Exception):this
        mov      rcx, rdi
        call     CORINFO_HELP_THROW
        int3

-; Total bytes of code 779, prolog size 10, PerfScore 155.04, (MethodHash=14ab57cd) for method QueryBuilder:ProcessNode(AstNode,int,byref):Query:this
+; Total bytes of code 632, prolog size 10, PerfScore 133.46, (MethodHash=14ab57cd) for method QueryBuilder:ProcessNode(AstNode,int,byref):Query:this

In some of the "regression" cases, eg SyntaxWalker:Visit(SyntaxNode):this XmlILVisitor:CachesResult(QilNode):bool:this, the extra inlines lead to less code overall because the inlines enabled struct promotion. So there's perhaps a missing bit of inline heuristic that should look for enhanced promotion opportunities, but these are tricky to get right (success often requires a coordinated set of inlines).

@erozenfeld
Copy link
Member

I would expect some diffs to show eliminated zero-inits since we rely on BBF_BACKWARD_JUMP when deciding whether we can eliminate explicit zero initializations.

@erozenfeld
Copy link
Member

We can make this check even less aggressive if we take into account other conditions that currently block tail recursion --> loop optimization:

if (opts.compTailCallLoopOpt && canFastTailCall && gtIsRecursiveCall(call) && !lvaReportParamTypeArg() &&
!lvaKeepAliveAndReportThis() && !call->IsVirtual() && !hasStructParam && !varTypeIsStruct(call->TypeGet()))
{
fastTailCallToLoop = true;
}

printf("\n");
}
#endif
JITDUMP("\nGTF_CALL_M_EXPLICIT_TAILCALL set for call [%06u]\n", dspTreeID(call));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dspTreeID() really should be named getTreeID()

Copy link
Contributor

@briansull briansull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Thanks for finding and fixing this

@AndyAyersMS
Copy link
Member Author

AndyAyersMS commented Mar 12, 2020

I would expect some diffs to show eliminated zero-init

Was looking for diffs like this, but haven't spotted any. Will sample a few more. I've also been thinking we need a jit-diff metric for prolog zeroing, which might make it easier to see this sort of thing. We have one for prolog size but it's not quite the same, and I think is broken.

We can make this check even less aggressive if we take into account other conditions

Sure, perhaps in a follow-on PR?

I'm also a bit worried that we are setting BBF_BACKARD_JUMP in the middle of importation -- if we change this flag for an already imported block then we potentially have a latent bug in the imported code for that block. I suspect all the semantically important cases are handled by the pre-importation values, and the while-importing changes that add BBF_BACKARD_JUMP only impact heuristics, but it would be good to be sure (perhaps, use two separate bits?).

@erozenfeld
Copy link
Member

I've also been thinking we need a jit-diff metric for prolog zeroing, which might make it easier to see this sort of thing.

In this case the zero-init diffs will be in the main body, not in the prolog. This change should only affect elimination of explicit zero-inits.

I'm also a bit worried that we are setting BBF_BACKARD_JUMP in the middle of importation -- if we change this flag for an already imported block then we potentially have a latent bug in the imported code for that block. I suspect all the semantically important cases are handled by the pre-importation values, and the while-importing changes that add BBF_BACKARD_JUMP` only impact heuristics, but it would be good to be sure (perhaps, use two separate bits?).

Yes, I think we might have this problem at the place where we call fgVarNeedsExplicitZeroInit in importer.cpp (github doesn't let me create a link since the file is too long). If we add BBF_BACKWARD_JUMP to that block after we've made the decision to skip explicit zero-init and later turn the call into a loop, we may get a problem. This is somewhat mitigated by the code in fgMorphRecursiveFastTailCallIntoLoop (below) but it looks like we still have a hole. It certainly is not a problem for C# code but we can probably get a test case with il.

// If compInitMem is set, we may need to zero-initialize some locals. Normally it's done in the prolog
// but this loop can't include the prolog. Since we don't have liveness information, we insert zero-initialization
// for all non-parameter IL locals as well as temp structs with GC fields.
// Liveness phase will remove unnecessary initializations.
if (info.compInitMem)
{
unsigned varNum;
LclVarDsc* varDsc;
for (varNum = 0, varDsc = lvaTable; varNum < lvaCount; varNum++, varDsc++)
{
#if FEATURE_FIXED_OUT_ARGS
if (varNum == lvaOutgoingArgSpaceVar)
{
continue;
}
#endif // FEATURE_FIXED_OUT_ARGS
if (!varDsc->lvIsParam)
{
var_types lclType = varDsc->TypeGet();
bool isUserLocal = (varNum < info.compLocalsCount);
bool structWithGCFields = ((lclType == TYP_STRUCT) && varDsc->GetLayout()->HasGCPtr());
if (isUserLocal || structWithGCFields)
{
GenTree* lcl = gtNewLclvNode(varNum, lclType);
GenTree* init = nullptr;
if (varTypeIsStruct(lclType))
{
const bool isVolatile = false;
const bool isCopyBlock = false;
init = gtNewBlkOpNode(lcl, gtNewIconNode(0), isVolatile, isCopyBlock);
init = fgMorphInitBlock(init);
}
else
{
GenTree* zero = gtNewZeroConNode(genActualType(lclType));
init = gtNewAssignNode(lcl, zero);
}
Statement* initStmt = gtNewStmt(init, callILOffset);
fgInsertStmtBefore(block, lastStmt, initStmt);
}
}
}
}

Sure, perhaps in a follow-on PR?

Sounds good.

@AndyAyersMS AndyAyersMS merged commit 84cf6a1 into dotnet:master Mar 12, 2020
@AndyAyersMS AndyAyersMS deleted the FixRecursiveTailCallLoopMarking branch March 12, 2020 22:55
AndyAyersMS added a commit to AndyAyersMS/runtime that referenced this pull request Mar 12, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants