Skip to content

Commit 776a9ad

Browse files
committed
Implement pointer dimension reduction
1 parent b67724a commit 776a9ad

190 files changed

Lines changed: 330 additions & 252 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.silktouch/a8a82533527277ff.stout

0 Bytes
Binary file not shown.

sources/SilkTouch/SilkTouch/Mods/ExtractNestedTyping.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,16 @@ public override async Task ExecuteAsync(IModContext ctx, CancellationToken ct =
7272
{
7373
await base.ExecuteAsync(ctx, ct);
7474

75-
var proj = ctx.SourceProject;
76-
if (proj == null)
75+
var project = ctx.SourceProject;
76+
if (project == null)
7777
{
7878
return;
7979
}
8080

81-
var compilation = await proj.GetCompilationAsync(ct);
81+
var compilation = await project.GetCompilationAsync(ct);
8282
if (compilation == null)
8383
{
84-
return;
84+
throw new InvalidOperationException("Failed to get compilation");
8585
}
8686

8787
var cfg = config.Get(ctx.JobKey);
@@ -115,11 +115,11 @@ public override async Task ExecuteAsync(IModContext ctx, CancellationToken ct =
115115
foreach (var (fullyQualifiedName, node) in syntaxNodes)
116116
{
117117
var relativePath = $"Handles/{PathForFullyQualified(fullyQualifiedName)}";
118-
proj = proj
118+
project = project
119119
?.AddDocument(
120120
Path.GetFileName(relativePath),
121121
node.NormalizeWhitespace(),
122-
filePath: proj.FullPath(relativePath)
122+
filePath: project.FullPath(relativePath)
123123
)
124124
.Project;
125125
}
@@ -133,7 +133,7 @@ public override async Task ExecuteAsync(IModContext ctx, CancellationToken ct =
133133
foreach (var docId in ctx.SourceProject?.DocumentIds ?? [])
134134
{
135135
var doc =
136-
proj!.GetDocument(docId) ?? throw new InvalidOperationException("Document missing");
136+
project!.GetDocument(docId) ?? throw new InvalidOperationException("Document missing");
137137
var (fname, node) = (doc.RelativePath(), await doc.GetSyntaxRootAsync(ct));
138138
if (fname is null)
139139
{
@@ -147,15 +147,15 @@ public override async Task ExecuteAsync(IModContext ctx, CancellationToken ct =
147147
// This will handle removing nested structs.
148148
// This is also where extracted enums are processed.
149149
rewriter.File = fname;
150-
proj = doc.WithSyntaxRoot(
150+
project = doc.WithSyntaxRoot(
151151
rewriter.Visit(node)?.NormalizeWhitespace()
152152
?? throw new InvalidOperationException("Rewriter returned null")
153153
).Project;
154154

155155
foreach (var newStruct in rewriter.ExtractedNestedStructs)
156156
{
157157
// Add new documents for each nested struct
158-
proj = proj.AddDocument(
158+
project = project.AddDocument(
159159
$"{newStruct.Identifier}.gen.cs",
160160
CompilationUnit()
161161
.WithMembers(
@@ -171,7 +171,7 @@ rewriter.Namespace is not null
171171
: SingletonList<MemberDeclarationSyntax>(newStruct)
172172
)
173173
.NormalizeWhitespace(),
174-
filePath: proj.FullPath(
174+
filePath: project.FullPath(
175175
$"{fname.AsSpan()[..fname.LastIndexOf('/')]}/{newStruct.Identifier}.gen.cs"
176176
)
177177
).Project;
@@ -222,7 +222,7 @@ rewriter.Namespace is not null
222222
{
223223
var ns = NameUtils.FindCommonPrefix(namespaces, true, false, true);
224224
var dir = NameUtils.FindCommonPrefix(fileDirs, true, false, true).TrimEnd('/');
225-
proj = proj
225+
project = project
226226
?.AddDocument(
227227
$"{identifier}.gen.cs",
228228
CompilationUnit()
@@ -237,12 +237,12 @@ rewriter.Namespace is not null
237237
: SingletonList(typeDecl)
238238
)
239239
.NormalizeWhitespace(),
240-
filePath: proj.FullPath($"{dir}/{identifier}.gen.cs")
240+
filePath: project.FullPath($"{dir}/{identifier}.gen.cs")
241241
)
242242
.Project;
243243
}
244244

245-
ctx.SourceProject = proj;
245+
ctx.SourceProject = project;
246246
}
247247

248248
private static ReadOnlySpan<char> GetNativeTypeNameForPredefinedType(

sources/SilkTouch/SilkTouch/Mods/TransformHandles.cs

Lines changed: 119 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,23 @@ public override async Task ExecuteAsync(IModContext ctx, CancellationToken ct =
5656
{
5757
await base.ExecuteAsync(ctx, ct);
5858

59-
var proj = ctx.SourceProject;
60-
if (proj == null)
59+
var project = ctx.SourceProject;
60+
if (project == null)
6161
{
6262
return;
6363
}
6464

65-
var compilation = await proj.GetCompilationAsync(ct);
65+
var compilation = await project.GetCompilationAsync(ct);
6666
if (compilation == null)
6767
{
68-
return;
68+
throw new InvalidOperationException("Failed to get compilation");
6969
}
7070

7171
var cfg = config.Get(ctx.JobKey);
7272

7373
// Phase 1. Gather data before modifying
7474
// Find handle documents
75-
var handleTypeDiscoverer = new HandleTypeDiscoverer(proj, compilation, ct);
75+
var handleTypeDiscoverer = new HandleTypeDiscoverer(project, compilation, ct);
7676
var handleTypes = await handleTypeDiscoverer.GetHandleTypesAsync();
7777

7878
// Store handle document IDs for later
@@ -88,24 +88,37 @@ public override async Task ExecuteAsync(IModContext ctx, CancellationToken ct =
8888
}
8989

9090
var declaringSyntaxReference = handleTypeSymbol.DeclaringSyntaxReferences.Single();
91-
var documentId = proj.GetDocumentId(declaringSyntaxReference.SyntaxTree);
91+
var documentId = project.GetDocumentId(declaringSyntaxReference.SyntaxTree);
9292
if (documentId != null)
9393
{
9494
handleTypeDocumentIds.Add((handleTypeSymbol.Name, documentId));
9595
}
9696
}
9797

98+
// Get fully qualified metadata names for each handle type
99+
// This is because symbols are invalidated after modifying the project they come from
100+
// We use these names to restore the symbols
101+
// TODO: This actually requires rewriting the fully qualified metadata names since the names will be different after the rename below. AHHHH...
102+
// Rewriting RenameAllAsync to allow providing a list of CSharpSyntaxRewriters might work best
103+
var handleTypeMetadataNames = handleTypes
104+
.Select(t => {
105+
var ns = t.NamespaceFromSymbol();
106+
var name = string.IsNullOrEmpty(ns) ? t.Name : $"{ns}.{t.Name}";
107+
108+
return name.Replace(t.Name, $"{t.Name}Handle");
109+
});
110+
98111
// Phase 2. Modify project after gathering data
99112
// Add -Handle suffix
100-
ctx.SourceProject = proj;
113+
ctx.SourceProject = project;
101114
await NameUtils.RenameAllAsync(ctx, logger, handleTypes.Select(t => ((ISymbol)t, $"{t.Name}Handle")), ct);
102-
proj = ctx.SourceProject;
115+
project = ctx.SourceProject;
103116

104117
// Use document IDs from earlier
105118
var handleTypeRewriter = new HandleTypeRewriter(cfg.UseDSL);
106119
foreach (var (originalName, documentId) in handleTypeDocumentIds)
107120
{
108-
var document = proj.GetDocument(documentId) ?? throw new InvalidOperationException("Failed to find document");
121+
var document = project.GetDocument(documentId) ?? throw new InvalidOperationException("Failed to find document");
109122

110123
var syntaxTree = await document.GetSyntaxTreeAsync(ct);
111124
if (syntaxTree == null)
@@ -124,33 +137,29 @@ public override async Task ExecuteAsync(IModContext ctx, CancellationToken ct =
124137
)
125138
.WithName(document.Name.Replace(originalName, $"{originalName}Handle"));
126139

127-
proj = document.Project;
140+
project = document.Project;
141+
}
142+
143+
// Phase 3. Reduce pointer dimensions
144+
// Get the compilation again
145+
compilation = await project.GetCompilationAsync(ct);
146+
if (compilation == null)
147+
{
148+
throw new InvalidOperationException("Failed to get compilation");
128149
}
129150

130-
// TODO: Reduce handle pointer dimensions by 1
131-
132-
// TODO: Old code. Cleanup needed
133-
// // Before the execution of this foreach loop, the handle structs are empty
134-
// //
135-
// // During this foreach loop, we do two things:
136-
// // 1. Rewrite all type references to refer to the handle structs
137-
// // 2. Add members to handle structs (as identified the handles variable)
138-
// var rewriter = new PointerDimensionReducer(handles, cfg.UseDSL);
139-
// foreach (var docId in proj?.DocumentIds ?? [])
140-
// {
141-
// var doc =
142-
// proj?.GetDocument(docId) ?? throw new InvalidOperationException("Document missing");
143-
// if (await doc.GetSyntaxRootAsync(ct) is not { } root)
144-
// {
145-
// continue;
146-
// }
147-
//
148-
// doc = doc.WithSyntaxRoot(rewriter.Visit(root).NormalizeWhitespace());
149-
//
150-
// proj = doc.Project;
151-
// }
152-
153-
ctx.SourceProject = proj;
151+
// Restore symbols
152+
handleTypes = handleTypeMetadataNames.SelectMany(name => compilation.GetTypesByMetadataName(name)).ToList();
153+
154+
// Reduce pointer dimensions
155+
ctx.SourceProject = project;
156+
var pointerDimensionReducer = new PointerDimensionReducer(ctx, ct);
157+
await pointerDimensionReducer.ReducePointerDimensionAsync(handleTypes);
158+
project = ctx.SourceProject;
159+
160+
// At the time of writing this comment, this line effectively does nothing
161+
// However, if the code above is removed, then this line ensures that the context's project is updated properly
162+
ctx.SourceProject = project;
154163
}
155164

156165
private class HandleTypeDiscoverer(Project project, Compilation compilation, CancellationToken ct) : SymbolVisitor
@@ -578,11 +587,82 @@ private static IEnumerable<MemberDeclarationSyntax> GetDSLHandleMembers(string s
578587
}
579588
}
580589

581-
// TODO: Perksey said he wanted pointer reduction to be handled alongside NameUtils.RenameAllAsync
582-
// for performance reasons
583-
// TODO: Make this take in a list of references (eg: Type*, Type**) to rewrite. If a non-pointer reference
584-
// is encountered, throw an error
585-
private class PointerDimensionReducer(Dictionary<string, Dictionary<string, string>> handles) : CSharpSyntaxRewriter
590+
private class PointerDimensionReducer(IModContext ctx, CancellationToken ct) : CSharpSyntaxRewriter
591+
{
592+
/// <summary>
593+
/// Reduces the pointer dimension of all references to the specified symbols.
594+
/// </summary>
595+
public async Task ReducePointerDimensionAsync(List<INamedTypeSymbol> symbols)
596+
{
597+
var project = ctx.SourceProject;
598+
if (project == null)
599+
{
600+
return;
601+
}
602+
603+
var compilation = await project.GetCompilationAsync(ct);
604+
if (compilation == null)
605+
{
606+
return;
607+
}
608+
609+
// Find all locations where the symbols are referenced
610+
var locations = new List<Location>();
611+
var documents = project.Documents.ToImmutableHashSet();
612+
foreach (var symbol in symbols)
613+
{
614+
var references = await SymbolFinder.FindReferencesAsync(symbol, project.Solution, documents, ct);
615+
locations.AddRange(references.SelectMany(r => r.Locations).Select(rl => rl.Location));
616+
}
617+
618+
// Reduce the pointer dimension of all reference locations
619+
foreach (var location in locations)
620+
{
621+
var syntaxTree = location.SourceTree;
622+
if (syntaxTree == null)
623+
{
624+
continue;
625+
}
626+
627+
var document = project.GetDocument(syntaxTree);
628+
if (document == null)
629+
{
630+
continue;
631+
}
632+
633+
var syntaxRoot = await syntaxTree.GetRootAsync(ct);
634+
var syntaxNode = syntaxRoot.FindNode(location.SourceSpan);
635+
636+
var nodeToModify = GetNodeToModify(syntaxNode);
637+
if (nodeToModify == null)
638+
{
639+
continue;
640+
}
641+
642+
var newNode = Visit(nodeToModify);
643+
var newRoot = syntaxRoot.ReplaceNode(nodeToModify, newNode);
644+
var newDocument = document.WithSyntaxRoot(newRoot);
645+
646+
project = newDocument.Project;
647+
}
648+
649+
ctx.SourceProject = project;
650+
}
651+
652+
private SyntaxNode? GetNodeToModify(SyntaxNode current)
653+
{
654+
if (current.Parent is PointerTypeSyntax parent)
655+
{
656+
return parent;
657+
}
658+
659+
return null;
660+
}
661+
662+
public override SyntaxNode? VisitPointerType(PointerTypeSyntax node) => node.ElementType;
663+
}
664+
665+
private class OldPointerDimensionReducer(Dictionary<string, Dictionary<string, string>> handles) : CSharpSyntaxRewriter
586666
{
587667
/// <summary>
588668
/// The current scope i.e. fully qualified type name.

sources/Vulkan/Vulkan/IVulkan/IVulkan.gen.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12768,7 +12768,7 @@ static abstract void DestroyPipeline(
1276812768
[NativeFunction("vulkan", EntryPoint = "vkDestroyPipelineBinaryKHR")]
1276912769
static abstract void DestroyPipelineBinaryKHR(
1277012770
[NativeTypeName("VkDevice")] DeviceHandle* device,
12771-
[NativeTypeName("VkPipelineBinaryKHR")] PipelineBinaryKHRHandle* pipelineBinary,
12771+
[NativeTypeName("VkPipelineBinaryKHR")] PipelineBinaryKHRHandle pipelineBinary,
1277212772
[NativeTypeName("const VkAllocationCallbacks *")] AllocationCallbacks* pAllocator
1277312773
);
1277412774

@@ -12784,7 +12784,7 @@ static abstract void DestroyPipelineBinaryKHR(
1278412784
[NativeFunction("vulkan", EntryPoint = "vkDestroyPipelineBinaryKHR")]
1278512785
static abstract void DestroyPipelineBinaryKHR(
1278612786
[NativeTypeName("VkDevice")] Ref<DeviceHandle> device,
12787-
[NativeTypeName("VkPipelineBinaryKHR")] Ref<PipelineBinaryKHRHandle> pipelineBinary,
12787+
[NativeTypeName("VkPipelineBinaryKHR")] PipelineBinaryKHRHandle pipelineBinary,
1278812788
[NativeTypeName("const VkAllocationCallbacks *")] Ref<AllocationCallbacks> pAllocator
1278912789
);
1279012790

@@ -32561,7 +32561,7 @@ void DestroyPipeline(
3256132561
[NativeFunction("vulkan", EntryPoint = "vkDestroyPipelineBinaryKHR")]
3256232562
void DestroyPipelineBinaryKHR(
3256332563
[NativeTypeName("VkDevice")] DeviceHandle* device,
32564-
[NativeTypeName("VkPipelineBinaryKHR")] PipelineBinaryKHRHandle* pipelineBinary,
32564+
[NativeTypeName("VkPipelineBinaryKHR")] PipelineBinaryKHRHandle pipelineBinary,
3256532565
[NativeTypeName("const VkAllocationCallbacks *")] AllocationCallbacks* pAllocator
3256632566
);
3256732567

@@ -32577,7 +32577,7 @@ void DestroyPipelineBinaryKHR(
3257732577
[NativeFunction("vulkan", EntryPoint = "vkDestroyPipelineBinaryKHR")]
3257832578
void DestroyPipelineBinaryKHR(
3257932579
[NativeTypeName("VkDevice")] Ref<DeviceHandle> device,
32580-
[NativeTypeName("VkPipelineBinaryKHR")] Ref<PipelineBinaryKHRHandle> pipelineBinary,
32580+
[NativeTypeName("VkPipelineBinaryKHR")] PipelineBinaryKHRHandle pipelineBinary,
3258132581
[NativeTypeName("const VkAllocationCallbacks *")] Ref<AllocationCallbacks> pAllocator
3258232582
);
3258332583

sources/Vulkan/Vulkan/Vulkan/AccelerationStructureBuildGeometryInfoKHR.gen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public unsafe partial struct AccelerationStructureBuildGeometryInfoKHR
8181
"VK_KHR_deferred_host_operations+VK_VERSION_1_2",
8282
]
8383
)]
84-
public AccelerationStructureKHRHandle* SrcAccelerationStructure;
84+
public AccelerationStructureKHRHandle SrcAccelerationStructure;
8585

8686
[NativeTypeName("VkAccelerationStructureKHR")]
8787
[SupportedApiProfile(

sources/Vulkan/Vulkan/Vulkan/AccelerationStructureCaptureDescriptorDataInfoEXT.gen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public unsafe partial struct AccelerationStructureCaptureDescriptorDataInfoEXT
6161
"VK_KHR_deferred_host_operations+VK_VERSION_1_2",
6262
]
6363
)]
64-
public AccelerationStructureKHRHandle* AccelerationStructure;
64+
public AccelerationStructureKHRHandle AccelerationStructure;
6565

6666
[NativeTypeName("VkAccelerationStructureNV")]
6767
[SupportedApiProfile(

sources/Vulkan/Vulkan/Vulkan/AccelerationStructureCreateInfoKHR.gen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public unsafe partial struct AccelerationStructureCreateInfoKHR
6262
"VK_KHR_deferred_host_operations+VK_VERSION_1_2",
6363
]
6464
)]
65-
public BufferHandle* Buffer;
65+
public BufferHandle Buffer;
6666

6767
[NativeTypeName("VkDeviceSize")]
6868
[SupportedApiProfile(

sources/Vulkan/Vulkan/Vulkan/AccelerationStructureDeviceAddressInfoKHR.gen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ public unsafe partial struct AccelerationStructureDeviceAddressInfoKHR
5151
"VK_KHR_deferred_host_operations+VK_VERSION_1_2",
5252
]
5353
)]
54-
public AccelerationStructureKHRHandle* AccelerationStructure;
54+
public AccelerationStructureKHRHandle AccelerationStructure;
5555
}

sources/Vulkan/Vulkan/Vulkan/AccelerationStructureMemoryRequirementsInfoNV.gen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,5 @@ public unsafe partial struct AccelerationStructureMemoryRequirementsInfoNV
6161
"VK_KHR_deferred_host_operations+VK_VERSION_1_2",
6262
]
6363
)]
64-
public AccelerationStructureNVHandle* AccelerationStructure;
64+
public AccelerationStructureNVHandle AccelerationStructure;
6565
}

sources/Vulkan/Vulkan/Vulkan/AccelerationStructureTrianglesOpacityMicromapEXT.gen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,5 @@ public unsafe partial struct AccelerationStructureTrianglesOpacityMicromapEXT
125125
"VK_KHR_acceleration_structure+VK_VERSION_1_3",
126126
]
127127
)]
128-
public MicromapEXTHandle* Micromap;
128+
public MicromapEXTHandle Micromap;
129129
}

0 commit comments

Comments
 (0)