Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ The .NET Foundation licenses this file to you under the MIT license.
<IlcArg Condition="'$(TrimmerDefaultAction)' == 'copyused' or '$(TrimmerDefaultAction)' == 'copy' or '$(TrimMode)' == 'partial'" Include="--defaultrooting" />
<IlcArg Condition="$(IlcResilient) != 'false'" Include="--resilient" />
<IlcArg Include="@(UnmanagedEntryPointsAssembly->'--generateunmanagedentrypoints:%(Identity)')" />
<IlcArg Condition="$(IlcOrderFile) != ''" Include="--order:$(IlcOrderFile)" />
<IlcArg Condition="$(IlcOrderFile) != ''" Include="--method-layout:explicit" />

<!-- The managed debugging support in libraries is unused - trim it -->
<IlcArg Condition="'$(DebuggerSupport)' != 'true'" Include="--feature:System.Diagnostics.Debugger.IsSupported=false" />
Expand All @@ -322,7 +324,7 @@ The .NET Foundation licenses this file to you under the MIT license.
</Target>

<Target Name="IlcCompile"
Inputs="@(IlcCompileInput);@(IlcReference);@(IlcSatelliteAssembly);@(RdXmlFile);%(ManagedBinary.IlcRspFile)"
Inputs="@(IlcCompileInput);@(IlcReference);@(IlcSatelliteAssembly);@(RdXmlFile);$(IlcOrderFile);%(ManagedBinary.IlcRspFile)"
Outputs="%(ManagedBinary.IlcOutputFile)"
DependsOnTargets="WriteIlcRspFileForCompilation;$(IlcCompileDependsOn)">
<Message Text="Generating native code" Importance="high" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

using Internal.TypeSystem;

Expand Down Expand Up @@ -36,6 +37,7 @@ public enum MethodLayoutAlgorithm
#endif
PettisHansen,
Random,
Explicit,
}

public enum FileLayoutAlgorithm
Expand All @@ -50,20 +52,23 @@ public FileLayoutOptimizer (Logger logger,
MethodLayoutAlgorithm methodAlgorithm,
FileLayoutAlgorithm fileAlgorithm,
ProfileDataManager profileData,
NodeFactory nodeFactory)
NodeFactory nodeFactory,
string orderFile = null)
{
_logger = logger;
_methodLayoutAlgorithm = methodAlgorithm;
_fileLayoutAlgorithm = fileAlgorithm;
_profileData = profileData;
_nodeFactory = nodeFactory;
_orderFile = orderFile;
}

private Logger _logger;
private MethodLayoutAlgorithm _methodLayoutAlgorithm = MethodLayoutAlgorithm.DefaultSort;
private FileLayoutAlgorithm _fileLayoutAlgorithm = FileLayoutAlgorithm.DefaultSort;
private ProfileDataManager _profileData;
private NodeFactory _nodeFactory;
private string _orderFile;

public ImmutableArray<DependencyNodeCore<NodeFactory>> ApplyProfilerGuidedMethodSort(ImmutableArray<DependencyNodeCore<NodeFactory>> nodes)
{
Expand Down Expand Up @@ -200,6 +205,33 @@ int ComputeHotWarmColdRegion(MethodWithGCInfo method)
}
break;

case MethodLayoutAlgorithm.Explicit:
var nameMap = new Dictionary<string, MethodWithGCInfo>(methods.Count);
var order = new Dictionary<MethodWithGCInfo, int>(methods.Count);

for (int i = 0; i < methods.Count; i++)
{
nameMap[methods[i].GetMangledName(_nodeFactory.NameMangler)] = methods[i];
order[methods[i]] = int.MaxValue;
}

using (StreamReader sr = new StreamReader(_orderFile))
{
int line = 0;
while (!sr.EndOfStream)
{
string symbolName = sr.ReadLine();
if (string.IsNullOrEmpty(symbolName)
|| !nameMap.TryGetValue(symbolName, out MethodWithGCInfo m))
continue;

order[m] = line++;
}
}

methods.MergeSortAllowDuplicates((MethodWithGCInfo left, MethodWithGCInfo right) => order[left].CompareTo(order[right]));
break;

default:
throw new NotImplementedException(_methodLayoutAlgorithm.ToString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ internal RyuJitCompilation(
RyuJitCompilationOptions options,
MethodLayoutAlgorithm methodLayoutAlgorithm,
FileLayoutAlgorithm fileLayoutAlgorithm,
int parallelism)
int parallelism,
string orderFile)
: base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, inliningPolicy, logger)
{
_compilationOptions = options;
Expand All @@ -61,7 +62,7 @@ internal RyuJitCompilation(

_parallelism = parallelism;

_fileLayoutOptimizer = new FileLayoutOptimizer(logger, methodLayoutAlgorithm, fileLayoutAlgorithm, profileDataManager, nodeFactory);
_fileLayoutOptimizer = new FileLayoutOptimizer(logger, methodLayoutAlgorithm, fileLayoutAlgorithm, profileDataManager, nodeFactory, orderFile);
}

public ProfileDataManager ProfileData => _profileDataManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public sealed class RyuJitCompilationBuilder : CompilationBuilder
private FileLayoutAlgorithm _fileLayoutAlgorithm;
private ILProvider _ilProvider = new NativeAotILProvider();
private ProfileDataManager _profileDataManager;
private string _orderFile;
private string _jitPath;

public RyuJitCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group)
Expand All @@ -35,6 +36,12 @@ public RyuJitCompilationBuilder UseProfileData(IEnumerable<string> mibcFiles)
return this;
}

public RyuJitCompilationBuilder UseSymbolOrder(string filePath)
{
_orderFile = filePath;
return this;
}

public RyuJitCompilationBuilder UseJitPath(string jitPath)
{
_jitPath = jitPath;
Expand Down Expand Up @@ -149,7 +156,8 @@ public override ICompilation ToCompilation()
options,
_methodLayoutAlgorithm,
_fileLayoutAlgorithm,
_parallelism);
_parallelism,
_orderFile);
}
}
}
6 changes: 5 additions & 1 deletion src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ internal sealed class ILCompilerRootCommand : RootCommand
new("--method-layout") { CustomParser = MakeMethodLayoutAlgorithm, DefaultValueFactory = MakeMethodLayoutAlgorithm, Description = "Layout algorithm used by profile-driven optimization for arranging methods in a file.", HelpName = "arg" };
public Option<FileLayoutAlgorithm> FileLayout { get; } =
new("--file-layout") { CustomParser = MakeFileLayoutAlgorithm, DefaultValueFactory = MakeFileLayoutAlgorithm, Description = "Layout algorithm used by profile-driven optimization for arranging non-method contents in a file.", HelpName = "arg" };
public Option<string> OrderFile { get; } =
new("--order") { Description = "File that specifies order of symbols within the generated object file" };
public Option<string[]> SatelliteFilePaths { get; } =
new("--satellite") { DefaultValueFactory = _ => Array.Empty<string>(), Description = "Satellite assemblies associated with inputs/references" };
public Option<bool> EnableDebugInfo { get; } =
Expand Down Expand Up @@ -193,6 +195,7 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler")
Options.Add(MibcFilePaths);
Options.Add(MethodLayout);
Options.Add(FileLayout);
Options.Add(OrderFile);
Options.Add(SatelliteFilePaths);
Options.Add(EnableDebugInfo);
Options.Add(UseDwarf5);
Expand Down Expand Up @@ -300,7 +303,7 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler")

#pragma warning disable CA1861 // Avoid constant arrays as arguments. Only executed once during the execution of the program.
Helpers.MakeReproPackage(makeReproPath, result.GetValue(OutputFilePath), args, result,
inputOptions : new[] { "-r", "--reference", "-m", "--mibc", "--rdxml", "--directpinvokelist", "--descriptor", "--satellite" },
inputOptions : new[] { "-r", "--reference", "-m", "--mibc", "--rdxml", "--directpinvokelist", "--descriptor", "--satellite", "--order" },
outputOptions : new[] { "-o", "--out", "--exportsfile", "--dgmllog", "--scandgmllog", "--mstat", "--sourcelink" });
#pragma warning restore CA1861 // Avoid constant arrays as arguments
}
Expand Down Expand Up @@ -424,6 +427,7 @@ private static MethodLayoutAlgorithm MakeMethodLayoutAlgorithm(ArgumentResult re
"hotwarmcold" => MethodLayoutAlgorithm.HotWarmCold,
"pettishansen" => MethodLayoutAlgorithm.PettisHansen,
"random" => MethodLayoutAlgorithm.Random,
"explicit" => MethodLayoutAlgorithm.Explicit,
_ => throw new CommandLineException(result.Tokens[0].Value)
};
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/tools/aot/ILCompiler/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ public int Run()
string compilationUnitPrefix = multiFile ? Path.GetFileNameWithoutExtension(outputFilePath) : "";
var builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup)
.FileLayoutAlgorithms(Get(_command.MethodLayout), Get(_command.FileLayout))
.UseSymbolOrder(Get(_command.OrderFile))
.UseCompilationUnitPrefix(compilationUnitPrefix);

string[] mibcFilePaths = Get(_command.MibcFilePaths);
Expand Down
1 change: 1 addition & 0 deletions src/tests/nativeaot/SmokeTests/UnitTests/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
success &= RunTest(Threading.Run);
success &= RunTest(Devirtualization.Run);
success &= RunTest(StackTraces.Run);
success &= RunTest(Ordering.Run);

return success ? 100 : 1;

Expand Down
42 changes: 42 additions & 0 deletions src/tests/nativeaot/SmokeTests/UnitTests/Ordering.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

class Ordering
{
internal static unsafe int Run()
{
// Method addresses are not observable in WASM
if (OperatingSystem.IsWasi() || OperatingSystem.IsBrowser())
return 100;

var keys = new nint[]
{
(nint)(delegate*<Guid>)&Method4,
(nint)(delegate*<Guid>)&Method3,
(nint)(delegate*<Guid>)&Method2,
(nint)(delegate*<Guid>)&Method1,
(nint)(delegate*<Guid>)&Method0,
};

var items = new int[] { 4, 3, 2, 1, 0 };

Array.Sort(keys, items);

// the order specified in the order.txt file
var expectedOrder = new int[] { 2, 1, 3, 0, 4 };

for (int i = 0; i < items.Length; i++)
if (items[i] != expectedOrder[i])
throw new Exception(i.ToString());

return 100;
}

static Guid Method0() => new Guid(0xb20e3a5f, 0x4aad, 0x4225, 0x98, 0x26, 0xac, 0xe8, 0xe0, 0xf7, 0x64, 0x56);
static Guid Method1() => new Guid(0x13464316, 0xb19c, 0x4e1c, 0x95, 0x2e, 0x22, 0xb4, 0xa, 0x21, 0x7d, 0xd5);
static Guid Method2() => new Guid(0x510f2c1e, 0x7715, 0x4aee, 0x8d, 0xd5, 0x16, 0xf8, 0xd5, 0x70, 0x5, 0x90);
static Guid Method3() => new Guid(0x4cc6e597, 0x875e, 0x4cb0, 0x90, 0x88, 0xcb, 0x4e, 0xd8, 0x8, 0x91, 0xb8);
static Guid Method4() => new Guid(0x2d2e2b87, 0x75f5, 0x4c16, 0x93, 0xa9, 0xbe, 0xbd, 0x6b, 0x58, 0xbd, 0xd6);
}
3 changes: 3 additions & 0 deletions src/tests/nativeaot/SmokeTests/UnitTests/UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@

<RequiresProcessIsolation>true</RequiresProcessIsolation>
<ReferenceXUnitWrapperGenerator>false</ReferenceXUnitWrapperGenerator>

<IlcOrderFile>order.txt</IlcOrderFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="BasicThreading.cs" />
<Compile Include="Delegates.cs" />
<Compile Include="Devirtualization.cs" />
<Compile Include="Generics.cs" />
<Compile Include="Interfaces.cs" />
<Compile Include="Ordering.cs" />
<Compile Include="Threading.cs" />
<Compile Include="StackTraces.cs" />
<Compile Include="Main.cs" />
Expand Down
5 changes: 5 additions & 0 deletions src/tests/nativeaot/SmokeTests/UnitTests/order.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
UnitTests_Ordering__Method2
UnitTests_Ordering__Method1
UnitTests_Ordering__Method3
UnitTests_Ordering__Method0
UnitTests_Ordering__Method4
Loading