Skip to content

Commit

Permalink
Merge pull request #330 from Draco-lang/rip-and-tear
Browse files Browse the repository at this point in the history
Cleanup before stackification
  • Loading branch information
LPeter1997 authored Oct 12, 2023
2 parents 94191bc + 6d27273 commit e9be01f
Show file tree
Hide file tree
Showing 36 changed files with 430 additions and 358 deletions.
8 changes: 4 additions & 4 deletions src/Draco.Compiler.Tests/Semantics/SymbolResolutionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1807,7 +1807,7 @@ public static class FooModule{

var diags = semanticModel.Diagnostics;
var xSym = GetInternalSymbol<VariableSymbol>(semanticModel.GetDeclaredSymbol(xDecl));
var fooSym = GetMemberSymbol<FieldSymbol>(GetInternalSymbol<ModuleSymbol>(semanticModel.GetReferencedSymbol(fooModuleRef)), "foo");
var fooSym = GetMemberSymbol<GlobalSymbol>(GetInternalSymbol<ModuleSymbol>(semanticModel.GetReferencedSymbol(fooModuleRef)), "foo");
var fooDecl = GetMetadataSymbol(compilation, null, "FooModule", "foo");

// Assert
Expand Down Expand Up @@ -1857,7 +1857,7 @@ public static class FooModule{

var diags = semanticModel.Diagnostics;
var xSym = GetInternalSymbol<VariableSymbol>(semanticModel.GetDeclaredSymbol(xDecl));
var fooSym = GetInternalSymbol<FieldSymbol>(semanticModel.GetReferencedSymbol(fooNameRef));
var fooSym = GetInternalSymbol<GlobalSymbol>(semanticModel.GetReferencedSymbol(fooNameRef));
var fooDecl = GetMetadataSymbol(compilation, null, "FooModule", "foo");

// Assert
Expand Down Expand Up @@ -1951,7 +1951,7 @@ public static class FooModule{
var semanticModel = compilation.GetSemanticModel(main);

var diags = semanticModel.Diagnostics;
var fooSym = GetMemberSymbol<FieldSymbol>(GetInternalSymbol<ModuleSymbol>(semanticModel.GetReferencedSymbol(fooModuleRef)), "foo");
var fooSym = GetMemberSymbol<GlobalSymbol>(GetInternalSymbol<ModuleSymbol>(semanticModel.GetReferencedSymbol(fooModuleRef)), "foo");
var fooDecl = GetMetadataSymbol(compilation, null, "FooModule", "foo");

// Assert
Expand Down Expand Up @@ -1996,7 +1996,7 @@ public static class FooModule{
var semanticModel = compilation.GetSemanticModel(main);

var diags = semanticModel.Diagnostics;
var fooSym = GetMemberSymbol<FieldSymbol>(GetInternalSymbol<ModuleSymbol>(semanticModel.GetReferencedSymbol(fooModuleRef)), "foo");
var fooSym = GetMemberSymbol<GlobalSymbol>(GetInternalSymbol<ModuleSymbol>(semanticModel.GetReferencedSymbol(fooModuleRef)), "foo");
var fooDecl = GetMetadataSymbol(compilation, null, "FooModule", "foo");

// Assert
Expand Down
2 changes: 1 addition & 1 deletion src/Draco.Compiler.Tests/Semantics/TypeCheckingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ public void AccessingField()
var semanticModel = compilation.GetSemanticModel(tree);

var xSym = GetInternalSymbol<LocalSymbol>(semanticModel.GetDeclaredSymbol(xDecl));
var stringEmptySym = GetMemberSymbol<FieldSymbol>(GetInternalSymbol<TypeSymbol>(semanticModel.GetReferencedSymbol(consoleRef)), "Empty");
var stringEmptySym = GetMemberSymbol<GlobalSymbol>(GetInternalSymbol<TypeSymbol>(semanticModel.GetReferencedSymbol(consoleRef)), "Empty");

// Assert
Assert.Empty(semanticModel.Diagnostics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private BoundExpression TypeGlobalExpression(UntypedGlobalExpression global, Con

private BoundExpression TypeFieldExpression(UntypedFieldExpression field, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var receiver = field.Reciever is null ? null : this.TypeExpression(field.Reciever, constraints, diagnostics);
var receiver = this.TypeExpression(field.Reciever, constraints, diagnostics);
return new BoundFieldExpression(field.Syntax, receiver, field.Field);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Draco.Compiler/Internal/Binding/Binder_BoundLvalue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private BoundLvalue TypeGlobalLvalue(UntypedGlobalLvalue global, ConstraintSolve

private BoundLvalue TypeFieldLvalue(UntypedFieldLvalue field, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var receiver = field.Reciever is null ? null : this.TypeExpression(field.Reciever, constraints, diagnostics);
var receiver = this.TypeExpression(field.Reciever, constraints, diagnostics);
return new BoundFieldLvalue(field.Syntax, receiver, field.Field);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -757,8 +757,6 @@ private UntypedExpression SymbolToExpression(SyntaxNode syntax, Symbol symbol, C
return new UntypedLocalExpression(syntax, local, constraints.GetLocalType(local));
case GlobalSymbol global:
return new UntypedGlobalExpression(syntax, global);
case FieldSymbol field:
return new UntypedFieldExpression(syntax, null, field);
case PropertySymbol prop:
var getter = GetGetterSymbol(syntax, prop, diagnostics);
return new UntypedPropertyGetExpression(syntax, null, getter);
Expand Down
4 changes: 2 additions & 2 deletions src/Draco.Compiler/Internal/Binding/Binder_UntypedLvalue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ private UntypedLvalue SymbolToLvalue(SyntaxNode syntax, Symbol symbol, Constrain
{
switch (symbol)
{
case FieldSymbol field:
return new UntypedFieldLvalue(syntax, null, field);
case GlobalSymbol global:
return new UntypedGlobalLvalue(syntax, global);
case PropertySymbol prop:
var setter = GetSetterSymbol(syntax, prop, diagnostics);
return new UntypedPropertySetLvalue(syntax, null, setter);
Expand Down
4 changes: 2 additions & 2 deletions src/Draco.Compiler/Internal/BoundTree/BoundNodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
</Node>

<Node Name="BoundFieldExpression" Base="BoundExpression">
<Field Name="Receiver" Type="BoundExpression?"/>
<Field Name="Receiver" Type="BoundExpression"/>
<Field Name="Field" Type="FieldSymbol" />
</Node>

Expand Down Expand Up @@ -280,7 +280,7 @@
</Node>

<Node Name="BoundFieldLvalue" Base="BoundLvalue">
<Field Name="Receiver" Type="BoundExpression?"/>
<Field Name="Receiver" Type="BoundExpression"/>
<Field Name="Field" Type="FieldSymbol" />
</Node>

Expand Down
12 changes: 2 additions & 10 deletions src/Draco.Compiler/Internal/Codegen/AllocatedLocal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ namespace Draco.Compiler.Internal.Codegen;
/// <summary>
/// Some method-local variable allocation.
/// </summary>
/// <param name="Operand">The corresponding IR operand.</param>
/// <param name="Symbol">The corresponding local symbol.</param>
/// <param name="Index">The index of the local within the method.</param>
internal readonly record struct AllocatedLocal(
IOperand Operand,
int Index)
{
/// <summary>
/// The symbol associated with this local, if any.
/// </summary>
public LocalSymbol? Symbol => this.Operand is Local local ? local.Symbol : null;
}
internal readonly record struct AllocatedLocal(LocalSymbol Symbol, int Index);
130 changes: 85 additions & 45 deletions src/Draco.Compiler/Internal/Codegen/CilCodegen.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
Expand All @@ -9,7 +10,6 @@
using Draco.Compiler.Internal.Symbols;
using Draco.Compiler.Internal.Symbols.Synthetized;
using Constant = Draco.Compiler.Internal.OptimizingIr.Model.Constant;
using Parameter = Draco.Compiler.Internal.OptimizingIr.Model.Parameter;
using Void = Draco.Compiler.Internal.OptimizingIr.Model.Void;

namespace Draco.Compiler.Internal.Codegen;
Expand All @@ -31,12 +31,20 @@ internal sealed class CilCodegen
.OrderBy(kv => kv.Value.Index)
.Select(kv => kv.Value);

/// <summary>
/// The allocated registers in order.
/// </summary>
public IEnumerable<Register> AllocatedRegisters => this.allocatedRegisters
.OrderBy(kv => kv.Value)
.Select(kv => kv.Key);

private PdbCodegen? PdbCodegen => this.metadataCodegen.PdbCodegen;

private readonly MetadataCodegen metadataCodegen;
private readonly IProcedure procedure;
private readonly ImmutableDictionary<LocalSymbol, AllocatedLocal> allocatedLocals;
private readonly ImmutableDictionary<Register, int> allocatedRegisters;
private readonly Dictionary<IBasicBlock, LabelHandle> labels = new();
private readonly Dictionary<IOperand, AllocatedLocal> allocatedLocals = new();

// NOTE: The current stackification attempt is FLAWED
// Imagine this situation:
Expand All @@ -62,30 +70,36 @@ public CilCodegen(MetadataCodegen metadataCodegen, IProcedure procedure)
var codeBuilder = new BlobBuilder();
var controlFlowBuilder = new ControlFlowBuilder();
this.InstructionEncoder = new InstructionEncoder(codeBuilder, controlFlowBuilder);

this.allocatedLocals = procedure.Locals
.Where(local => !SymbolEqualityComparer.Default.Equals(local.Type, IntrinsicSymbols.Unit))
.Select((local, index) => (Local: local, Index: index))
.ToImmutableDictionary(pair => pair.Local, pair => new AllocatedLocal(pair.Local, pair.Index));
this.allocatedRegisters = procedure.Registers
.Where(reg => !SymbolEqualityComparer.Default.Equals(reg.Type, IntrinsicSymbols.Unit))
.Select((reg, index) => (Register: reg, Index: index))
.ToImmutableDictionary(pair => pair.Register, pair => this.allocatedLocals.Count + pair.Index);
}

private MemberReferenceHandle GetGlobalReferenceHandle(Global global) => this.metadataCodegen.GetGlobalReferenceHandle(global);
private MemberReferenceHandle GetProcedureDefinitionHandle(IProcedure procedure) => this.metadataCodegen.GetProcedureReferenceHandle(procedure);
private UserStringHandle GetStringLiteralHandle(string text) => this.metadataCodegen.GetStringLiteralHandle(text);

private EntityHandle GetHandle(Symbol symbol) => this.metadataCodegen.GetEntityHandle(symbol);

// TODO: Parameters don't handle unit yet, it introduces some signature problems
private int GetParameterIndex(Parameter parameter) => parameter.Index;
private int GetParameterIndex(ParameterSymbol parameter) => this.procedure.GetParameterIndex(parameter);

private AllocatedLocal? GetAllocatedLocal(IOperand operand)
private AllocatedLocal? GetAllocatedLocal(LocalSymbol local)
{
if (SymbolEqualityComparer.Default.Equals(operand.Type, IntrinsicSymbols.Unit)) return null;
if (!this.allocatedLocals.TryGetValue(operand, out var local))
{
local = new(operand, this.allocatedLocals.Count);
this.allocatedLocals.Add(operand, local);
}
return local;
if (!this.allocatedLocals.TryGetValue(local, out var allocatedLocal)) return null;
return allocatedLocal;
}

private int? GetLocalIndex(Local local) => this.GetAllocatedLocal(local)?.Index;
private int? GetRegisterIndex(Register register) => this.GetAllocatedLocal(register)?.Index;
private int? GetLocalIndex(LocalSymbol local) => this.GetAllocatedLocal(local)?.Index;
private int? GetRegisterIndex(Register register)
{
if (!this.allocatedRegisters.TryGetValue(register, out var allocatedRegister)) return null;
return allocatedRegister;
}

private LabelHandle GetLabel(IBasicBlock block)
{
Expand Down Expand Up @@ -120,10 +134,9 @@ private void EncodeInstruction(IInstruction instruction)
case StartScope start:
{
var localIndices = start.Locals
.Select(sym => this.procedure.Locals[sym])
.Select(loc => this.GetAllocatedLocal(loc))
.Select(sym => this.GetAllocatedLocal(sym))
.OfType<AllocatedLocal>();
this.PdbCodegen?.StartScope(this.InstructionEncoder.Offset, localIndices);
this.PdbCodegen?.StartScope(this.InstructionEncoder.Offset, this.allocatedLocals.Values);
break;
}
case EndScope:
Expand Down Expand Up @@ -180,13 +193,23 @@ private void EncodeInstruction(IInstruction instruction)
// Depends on where we load from
switch (load.Source)
{
case Local local:
case ParameterSymbol param:
{
var index = this.GetParameterIndex(param);
this.InstructionEncoder.LoadArgument(index);
break;
}
case LocalSymbol local:
{
this.LoadLocal(local);
break;
case Global global:
}
case GlobalSymbol global:
{
this.InstructionEncoder.OpCode(ILOpCode.Ldsfld);
this.InstructionEncoder.Token(this.GetGlobalReferenceHandle(global));
this.EncodeToken(global);
break;
}
default:
throw new InvalidOperationException();
}
Expand Down Expand Up @@ -231,14 +254,16 @@ private void EncodeInstruction(IInstruction instruction)
{
switch (store.Target)
{
case Local local:
case ParameterSymbol:
throw new InvalidOperationException();
case LocalSymbol local:
this.EncodePush(store.Source);
this.StoreLocal(local);
break;
case Global global:
case GlobalSymbol global:
this.EncodePush(store.Source);
this.InstructionEncoder.OpCode(ILOpCode.Stsfld);
this.InstructionEncoder.Token(this.GetGlobalReferenceHandle(global));
this.EncodeToken(global);
break;
default:
throw new InvalidOperationException();
Expand Down Expand Up @@ -278,6 +303,38 @@ private void EncodeInstruction(IInstruction instruction)
this.InstructionEncoder.Token(this.GetHandle(storeField.Member));
break;
}
case AddressOfInstruction addressOf:
{
switch (addressOf.Source)
{
case ParameterSymbol param:
{
var paramIndex = this.GetParameterIndex(param);
this.InstructionEncoder.LoadArgumentAddress(paramIndex);
this.StoreLocal(addressOf.Target);
break;
}
case LocalSymbol local:
{
var localIndex = this.GetLocalIndex(local);
// NOTE: What if we ask the address of a unit?
Debug.Assert(localIndex is not null);
this.InstructionEncoder.LoadLocalAddress(localIndex.Value);
this.StoreLocal(addressOf.Target);
break;
}
case GlobalSymbol global:
{
this.InstructionEncoder.OpCode(ILOpCode.Ldsflda);
this.EncodeToken(global);
this.StoreLocal(addressOf.Target);
break;
}
default:
throw new InvalidOperationException();
}
break;
}
case CallInstruction call:
{
// Arguments
Expand Down Expand Up @@ -376,24 +433,7 @@ private void EncodePush(IOperand operand)
case Void:
return;
case Register r:
this.LoadLocal(r);
break;
case Parameter p:
this.InstructionEncoder.LoadArgument(this.GetParameterIndex(p));
break;
case Address a:
switch (a.Operand)
{
case Local local:
{
var index = this.GetLocalIndex(local);
if (index is null) break;
this.InstructionEncoder.LoadLocalAddress(index.Value);
break;
}
default:
throw new NotImplementedException();
}
this.LoadRegister(r);
break;
case Constant c:
switch (c.Value)
Expand All @@ -417,21 +457,21 @@ private void EncodePush(IOperand operand)
}
}

private void LoadLocal(Local local)
private void LoadLocal(LocalSymbol local)
{
var index = this.GetLocalIndex(local);
if (index is null) return;
this.InstructionEncoder.LoadLocal(index.Value);
}

private void LoadLocal(Register register)
private void LoadRegister(Register register)
{
var index = this.GetRegisterIndex(register);
if (index is null) return;
this.InstructionEncoder.LoadLocal(index.Value);
}

private void StoreLocal(Local local)
private void StoreLocal(LocalSymbol local)
{
var index = this.GetLocalIndex(local);
if (index is null) return;
Expand Down
Loading

0 comments on commit e9be01f

Please sign in to comment.