This repository has been archived by the owner on Nov 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 508
Get CoreRT Hello World selfcontained binary under 1 MB #7962
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
MichalStrehovsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
MichalStrehovsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
using System; | ||
using System.Xml.Linq; | ||
using System.Linq; | ||
using System.Diagnostics; | ||
using System.Collections.Generic; | ||
using System.Reflection; | ||
|
||
// This is a simple command line tool to inspect DGML files generated by | ||
// ILCompiler.DependencyAnalysisFramework's DgmlWriter class. | ||
// | ||
// It works best if FirstMarkLogStrategy is used. It might hit cycles if full | ||
// marking strategy is used, so better not try that. That's untested. | ||
// | ||
// Given the name of the DGML file and a name of the node in the DGML graph, | ||
// it prints the path from the node to the roots. | ||
|
||
class Program | ||
{ | ||
static void Main(string[] args) | ||
{ | ||
if (args.Length != 2) | ||
{ | ||
Console.WriteLine("Usage:"); | ||
Console.Write(Assembly.GetExecutingAssembly().ManifestModule.Name); | ||
Console.WriteLine(" dgmlfile.xml node_name"); | ||
return; | ||
} | ||
|
||
string file = args[0]; | ||
|
||
var directedGraph = XElement.Load(file); | ||
|
||
var idToNode = new Dictionary<int, Node>(); | ||
var nameToNode = new Dictionary<string, Node>(StringComparer.Ordinal); | ||
var nodes = directedGraph.Elements().Single(e => e.Name.LocalName == "Nodes"); | ||
foreach (var node in nodes.Elements()) | ||
{ | ||
Debug.Assert(node.Name.LocalName == "Node"); | ||
int id = int.Parse(node.Attribute("Id").Value); | ||
string name = node.Attribute("Label").Value; | ||
var n = new Node(name); | ||
idToNode[id] = n; | ||
nameToNode[name] = n; | ||
} | ||
|
||
var links = directedGraph.Elements().Single(e => e.Name.LocalName == "Links"); | ||
foreach (var link in links.Elements()) | ||
{ | ||
int source = int.Parse(link.Attribute("Source").Value); | ||
int target = int.Parse(link.Attribute("Target").Value); | ||
string reason = link.Attribute("Reason").Value; | ||
idToNode[target].Edges.Add((idToNode[source], reason)); | ||
} | ||
|
||
string goal = args[1]; | ||
if (!nameToNode.ContainsKey(goal)) | ||
Console.WriteLine($"No such node: '{goal}'."); | ||
else | ||
Dump(nameToNode[goal]); | ||
} | ||
|
||
static void Dump(Node current, int indent = 0, string reason = "") | ||
{ | ||
Console.WriteLine($"{new string(' ', indent)}({reason}) {current.Name}"); | ||
|
||
foreach (var edge in current.Edges) | ||
{ | ||
Dump(edge.Node, indent + 2, edge.Label); | ||
} | ||
} | ||
} | ||
|
||
class Node | ||
{ | ||
public readonly string Name; | ||
public readonly List<(Node Node, string Label)> Edges; | ||
|
||
public Node(string name) | ||
{ | ||
Name = name; | ||
Edges = new List<(Node, string)>(); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/ILCompiler.DependencyAnalysisFramework/WhyDgml/Why.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
</PropertyGroup> | ||
</Project> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to deleted these and convert the few places that use it to use
typeof
, e.g.if (type == typeof(Decimal))
.Caching these in statics is actually a deoptimization.
The JIT has optimization for
operator==
on System.Type that kicks in when one of the sides is typeof. It should compile this into a simple vtable compare.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to port the fix for this deoptimization to CoreCLR as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take it, the comment at the top of this class only applies for .NET Native?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually have a hard time finding the places where RyuJIT would be able to optimize the type comparison - most of these are used in deep reflection code where we have a
System.Type
from who knows where that we want to compare to a well known one, or we want to grab a specificSystem.Type
to return.I think typeof is still more expensive on CoreRT than on CoreCLR. It's at minimum a hashtable lookup. CoreCLR can do it faster for some reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CommonTypes.Decimal
is used in a single place incorert/src/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs
Line 90 in 09682e3
If you change this
if (type == typeof(Decimal))
, the RyuJIT should optimize it to a simplecmp
instruction (look forCORINFO_INTRINSIC_TypeEQ
).I am not suggestion to get rid of this class completely. I agree that it is not straightforward to get rid of this completely. I am just suggestion to get rid of the ones you are moving to
NotSoCommonTypes
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The equivalent in CoreCLR that can use the same fix is here: https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs#L192
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, the optimization is not as good as I though. It is not able to get rid of the materializing of the Type object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could probably come up with a scheme for RyuJIT to be able optimize this.
typeof(X)
expands to a set of calls "load nativeTypeHandle
→ getRuntimeTypeHandle
from nativeTypeHandle
->Type.GetTypeFromHandle
. RyuJIT optimizes this entire sequence into a singleCORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
helper call that takes the nativeTypeHandle
as an argument.RyuJIT can then optimize this to a simple compare if the other side of the comparison is a another
typeof
orsomeObject.GetType()
. But that's not the case here.If we could add a helper to compare native
TypeHandle
with an arbitrarySystem.Type
, we could have RyuJIT call that in that case. That would help avoid materializing theSystem.Type
from the nativeTypeHandle
.I could try to prototype that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dotnet/runtime#31686 is the JIT fix to optimize the pattern and make a lot of
CommonRuntimeTypes
obsolete.