Skip to content

Commit

Permalink
Added threading option
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Sep 28, 2023
1 parent 4cc2367 commit c0dfb53
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
18 changes: 16 additions & 2 deletions src/Draco.Compiler.Benchmarks/E2eBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,28 @@ public void Setup()
}

[Benchmark]
public EmitResult Compile()
public EmitResult CompileSingleThreaded()
{
var syntaxTree = SyntaxTree.Parse(this.Input.Code, Path.GetFullPath(this.Input.Path));
var compilation = Compilation.Create(
syntaxTrees: ImmutableArray.Create(syntaxTree),
metadataReferences: Basic.Reference.Assemblies.Net70.ReferenceInfos.All
.Select(r => MetadataReference.FromPeStream(new MemoryStream(r.ImageBytes)))
.ToImmutableArray());
.ToImmutableArray(),
useMultithreading: false);
return compilation.Emit(peStream: this.peStream);
}

[Benchmark]
public EmitResult CompileMultiThreaded()
{
var syntaxTree = SyntaxTree.Parse(this.Input.Code, Path.GetFullPath(this.Input.Path));
var compilation = Compilation.Create(
syntaxTrees: ImmutableArray.Create(syntaxTree),
metadataReferences: Basic.Reference.Assemblies.Net70.ReferenceInfos.All
.Select(r => MetadataReference.FromPeStream(new MemoryStream(r.ImageBytes)))
.ToImmutableArray(),
useMultithreading: true);
return compilation.Emit(peStream: this.peStream);
}
}
39 changes: 38 additions & 1 deletion src/Draco.Compiler/Api/Compilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Draco.Compiler.Api.Diagnostics;
using Draco.Compiler.Api.Semantics;
using Draco.Compiler.Api.Syntax;
Expand Down Expand Up @@ -45,13 +46,16 @@ public sealed class Compilation : IBinderProvider
/// <param name="rootModulePath">The path of the root module.</param>
/// <param name="outputPath">The output path.</param>
/// <param name="assemblyName">The output assembly name.</param>
/// <param name="useMultithreading">True, if multithreading should be used.</param>
/// <returns>The constructed <see cref="Compilation"/>.</returns>
public static Compilation Create(
ImmutableArray<SyntaxTree> syntaxTrees,
ImmutableArray<MetadataReference>? metadataReferences = null,
string? rootModulePath = null,
string? outputPath = null,
string? assemblyName = null) => new(
string? assemblyName = null,
bool useMultithreading = true) => new(
useMultithreading: useMultithreading,
syntaxTrees: syntaxTrees,
metadataReferences: metadataReferences,
rootModulePath: rootModulePath,
Expand All @@ -67,6 +71,11 @@ public static Compilation Create(
.Concat(this.GlobalDiagnosticBag)
.ToImmutableArray();

/// <summary>
/// True, if threading is utilized by the compilation.
/// </summary>
public bool UseMultithreading { get; }

/// <summary>
/// The trees that are being compiled.
/// </summary>
Expand Down Expand Up @@ -148,6 +157,7 @@ public static Compilation Create(

// Main ctor with all state
private Compilation(
bool useMultithreading,
ImmutableArray<SyntaxTree> syntaxTrees,
ImmutableArray<MetadataReference>? metadataReferences,
string? rootModulePath = null,
Expand All @@ -162,6 +172,7 @@ private Compilation(
IntrinsicSymbols? intrinsicSymbols = null,
BinderCache? binderCache = null)
{
this.UseMultithreading = useMultithreading;
this.SyntaxTrees = syntaxTrees;
this.MetadataReferences = metadataReferences ?? ImmutableArray<MetadataReference>.Empty;
this.RootModulePath = Path.TrimEndingDirectorySeparator(rootModulePath ?? string.Empty);
Expand Down Expand Up @@ -205,6 +216,7 @@ public Compilation UpdateSyntaxTree(SyntaxTree? oldTree, SyntaxTree? newTree)
}

return new Compilation(
useMultithreading: this.UseMultithreading,
syntaxTrees: newSyntaxTrees.ToImmutable(),
metadataReferences: this.MetadataReferences,
rootModulePath: this.RootModulePath,
Expand Down Expand Up @@ -306,6 +318,31 @@ public EmitResult Emit(
Diagnostics: ImmutableArray<Diagnostic>.Empty);
}

internal Task RunOnThread(Action action)
{
if (this.UseMultithreading)
{
return Task.Run(action);
}
else
{
action();
return Task.CompletedTask;
}
}

internal Task<T> RunOnThread<T>(Func<T> func)
{
if (this.UseMultithreading)
{
return Task.Run(func);
}
else
{
return Task.FromResult(func());
}
}

internal ModuleSymbol GetModuleForSyntaxTree(SyntaxTree tree)
{
var filePath = SplitPath.FromFilePath(tree.SourceText.Path?.LocalPath ?? string.Empty);
Expand Down
4 changes: 2 additions & 2 deletions src/Draco.Compiler/Api/Semantics/SemanticModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ private ImmutableArray<Diagnostic> GetDiagnostics(SourceSpan? span = null)
case CompilationUnitSyntax:
case FunctionDeclarationSyntax:
{
tasks.Add(Task.Run(() => containingSymbol?.Bind(this)));
tasks.Add(this.compilation.RunOnThread(() => containingSymbol?.Bind(this)));
break;
}
// NOTE: Only globals need binding
case VariableDeclarationSyntax when containingSymbol is SourceModuleSymbol containingModule:
{
tasks.Add(Task.Run(() =>
tasks.Add(this.compilation.RunOnThread(() =>
{
// We need to search for this global
var globalSymbol = containingModule.Members
Expand Down

0 comments on commit c0dfb53

Please sign in to comment.