From 9d7b1e0f494535d8c5e340447b1db104f09fb4d9 Mon Sep 17 00:00:00 2001 From: nub31 Date: Thu, 3 Jul 2025 18:57:37 +0200 Subject: [PATCH] ... --- example/src/main.nub | 38 +++++++++-------- src/compiler/Generation/QBE/QBEGenerator.cs | 47 ++++++++++++++++----- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/example/src/main.nub b/example/src/main.nub index a7a5d44..e05d7e5 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -1,29 +1,31 @@ namespace main -struct Name { - first: cstring - last: cstring -} +// struct Name { +// first: cstring +// last: cstring +// } -struct Human -{ - name: Name - age: i64 -} +// struct Human +// { +// name: Name +// age: i64 +// } export func main(args: []cstring): i64 { - let x: Human + // let x: Human - x = alloc Human { - name = alloc Name { - first = "john" - last = "doe" - } - age = 23 - } + // x = alloc Human { + // name = alloc Name { + // first = "john" + // last = "doe" + // } + // age = 23 + // } - c::puts(x.name.last) + // c::puts(x.name.last) + + c::puts("test") return 0 } diff --git a/src/compiler/Generation/QBE/QBEGenerator.cs b/src/compiler/Generation/QBE/QBEGenerator.cs index 1f22683..7f11d5e 100644 --- a/src/compiler/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/Generation/QBE/QBEGenerator.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; using Syntax; @@ -219,8 +220,9 @@ public static class QBEGenerator return false; } - private static void EmitCopyOrMoveInto(BoundExpressionNode source, string destinationPointer) + private static void EmitCopyIntoOrInitialize(BoundExpressionNode source, string destinationPointer) { + // If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying if (EmitTryMoveInto(source, destinationPointer)) { return; @@ -276,8 +278,33 @@ public static class QBEGenerator } } - private static string EmitCopy(NubType type, string source) + private static bool EmitTryCreateWithoutCopy(BoundExpressionNode source, [NotNullWhen(true)] out string? destination) { + switch (source) + { + case BoundArrayInitializerNode: + case BoundStructInitializerNode: + case BoundLiteralNode { Kind: LiteralKind.String }: + { + destination = EmitUnwrap(EmitExpression(source)); + return true; + } + } + + destination = null; + return false; + } + + private static string EmitCreateCopyOrInitialize(NubType type, BoundExpressionNode source) + { + // If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying + if (EmitTryCreateWithoutCopy(source, out var uncopiedValue)) + { + return uncopiedValue; + } + + var value = EmitUnwrap(EmitExpression(source)); + switch (type) { case NubComplexType complexType: @@ -286,20 +313,20 @@ public static class QBEGenerator var size = complexType switch { - NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, source), - NubCStringType => EmitCStringSizeInBytes(source), - NubStringType => EmitStringSizeInBytes(source), + NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, value), + NubCStringType => EmitCStringSizeInBytes(value), + NubStringType => EmitStringSizeInBytes(value), NubStructType nubStructType => SizeOf(nubStructType).ToString(), _ => throw new ArgumentOutOfRangeException(nameof(complexType)) }; _builder.AppendLine($" {destination} =l alloc8 {size}"); - EmitMemcpy(source, destination, size); + EmitMemcpy(value, destination, size); return destination; } case NubSimpleType: { - return source; + return value; } default: { @@ -601,7 +628,7 @@ public static class QBEGenerator { var destination = EmitExpression(assignment.Expression); Debug.Assert(destination.Kind == ValKind.Pointer); - EmitCopyOrMoveInto(assignment.Value, destination.Name); + EmitCopyIntoOrInitialize(assignment.Value, destination.Name); } private static void EmitBlock(BoundBlockNode block, List? variables = null) @@ -1039,7 +1066,7 @@ public static class QBEGenerator var offset = VarName(); _builder.AppendLine($" {offset} =l add {destination}, {OffsetOf(structDefinition, field.Name)}"); - EmitCopyOrMoveInto(valueExpression, offset); + EmitCopyIntoOrInitialize(valueExpression, offset); } return new Val(destination, structInitializer.StructType, ValKind.Direct); @@ -1169,7 +1196,7 @@ public static class QBEGenerator _ => throw new NotSupportedException($"'{parameter.Type}' type cannot be used in function calls") }; - var copy = EmitCopy(parameter.Type, EmitUnwrap(EmitExpression(parameter))); + var copy = EmitCreateCopyOrInitialize(parameter.Type, parameter); parameterStrings.Add($"{qbeType} {copy}"); }