From 6b89ba41d47e40116240a9b83940b5da1932fd23 Mon Sep 17 00:00:00 2001 From: Scott Carda <55811729+ScottCarda-MS@users.noreply.github.com> Date: Fri, 2 Jul 2021 10:00:30 -0700 Subject: [PATCH 1/2] Doc Comments for Transformations (#1060) Added doc to TrimSyntaxTree and ValidateMonomorphization transformations --- .../Compiler/RewriteSteps/SyntaxTreeTrimming.cs | 2 +- .../Transformations/MonomorphizationValidation.cs | 9 +++++++++ .../Transformations/SyntaxTreeTrimming.cs | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/QsCompiler/Compiler/RewriteSteps/SyntaxTreeTrimming.cs b/src/QsCompiler/Compiler/RewriteSteps/SyntaxTreeTrimming.cs index 34100e4e47..bd9529099b 100644 --- a/src/QsCompiler/Compiler/RewriteSteps/SyntaxTreeTrimming.cs +++ b/src/QsCompiler/Compiler/RewriteSteps/SyntaxTreeTrimming.cs @@ -31,7 +31,7 @@ internal class SyntaxTreeTrimming : IRewriteStep public bool ImplementsPostconditionVerification => false; /// - /// Constructor for the SyntaxTreeTrimming Rewrite Step. + /// Initializes a new instance of the class. /// /// When true, intrinsics will not be removed as part of the rewrite step. public SyntaxTreeTrimming(bool keepAllIntrinsics = true, IEnumerable? dependencies = null) diff --git a/src/QsCompiler/Transformations/MonomorphizationValidation.cs b/src/QsCompiler/Transformations/MonomorphizationValidation.cs index deb45147ac..07f1e5fb40 100644 --- a/src/QsCompiler/Transformations/MonomorphizationValidation.cs +++ b/src/QsCompiler/Transformations/MonomorphizationValidation.cs @@ -10,8 +10,17 @@ namespace Microsoft.Quantum.QsCompiler.Transformations.Monomorphization.Validation { + /// + /// Validates that the monomorphization transformation has removed all references to + /// generic objects. + /// public class ValidateMonomorphization : SyntaxTreeTransformation { + /// + /// Applies the transformation that walks through the syntax tree, checking to ensure + /// that all generic data has been removed. If allowTypeParametersForIntrinsics is true, + /// then generic data is allowed for type parameters of callables that have an intrinsic body. + /// public static void Apply(QsCompilation compilation, bool allowTypeParametersForIntrinsics = true) { var intrinsicCallableSet = allowTypeParametersForIntrinsics diff --git a/src/QsCompiler/Transformations/SyntaxTreeTrimming.cs b/src/QsCompiler/Transformations/SyntaxTreeTrimming.cs index d2eff5d6c0..09fb31fce9 100644 --- a/src/QsCompiler/Transformations/SyntaxTreeTrimming.cs +++ b/src/QsCompiler/Transformations/SyntaxTreeTrimming.cs @@ -11,8 +11,20 @@ namespace Microsoft.Quantum.QsCompiler.Transformations.SyntaxTreeTrimming { + /// + /// Removes unused callables from the syntax tree. + /// public static class TrimSyntaxTree { + /// + /// Applies the transformation that removes from the syntax tree all callables that + /// are unused, meaning they are not a descendant of at least one entry point in + /// the call graph. If keepAllIntrinsics is true, callables with an intrinsic body + /// will not be trimmed, regardless of usage. Any callables that later + /// transformations will depend on should be passed in and will not be trimmed, + /// regardless of usage. Note that unused type constructors will be subject to + /// trimming as any other callable. + /// public static QsCompilation Apply(QsCompilation compilation, bool keepAllIntrinsics, IEnumerable? dependencies = null) { return TrimTree.Apply(compilation, keepAllIntrinsics, dependencies); @@ -68,6 +80,9 @@ private static bool Filter(QsNamespaceElement elem, ImmutableHashSet + /// Class representing the state of the transformation. + /// public class TransformationState { public Func NamespaceElementFilter { get; } From bb5836a75d228eda3eabf87618778d27496c938d Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Fri, 2 Jul 2021 16:09:52 -0700 Subject: [PATCH 2/2] addressing most review comments --- .../CompilationManager/AssemblyLoader.cs | 12 +-- src/QsCompiler/LlvmBindings/BitcodeModule.cs | 12 --- src/QsCompiler/QirGeneration/Context.cs | 20 ++++ .../EntryPointOperationLoader.cs | 92 ------------------- .../QirGeneration/NameGeneration.cs | 11 --- 5 files changed, 26 insertions(+), 121 deletions(-) delete mode 100644 src/QsCompiler/QirGeneration/EntryPointOperationLoader.cs diff --git a/src/QsCompiler/CompilationManager/AssemblyLoader.cs b/src/QsCompiler/CompilationManager/AssemblyLoader.cs index 339a4ef393..7f3fe1f3cc 100644 --- a/src/QsCompiler/CompilationManager/AssemblyLoader.cs +++ b/src/QsCompiler/CompilationManager/AssemblyLoader.cs @@ -161,18 +161,18 @@ public static bool LoadSyntaxTree( } /// - /// Loads any QIR byte code included as a resource from . + /// Loads any QIR bitcode included as a resource from . /// - /// The file info of a .NET DLL from which to load the QIR byte code. - /// A stream to store the QIR byte code embedded to as a resource. + /// The file info of a .NET DLL from which to load the QIR bitcode. + /// A stream to store the QIR bitcode embedded to as a resource. /// - /// True if includes the QIR byte code resource, false otherwise. + /// True if includes the QIR bitcode resource, false otherwise. /// /// does not exist. - public static bool LoadQirByteCode(FileInfo assemblyFileInfo, Stream qirByteStream) + public static bool LoadQirBitcode(FileInfo assemblyFileInfo, Stream qirStream) { using var assemblyFile = GetAssemblyReader(assemblyFileInfo.FullName); - return LoadResource(DotnetCoreDll.ResourceNameQsDataQirV1, assemblyFile, qirByteStream); + return LoadResource(DotnetCoreDll.ResourceNameQsDataQirV1, assemblyFile, qirStream); } /// diff --git a/src/QsCompiler/LlvmBindings/BitcodeModule.cs b/src/QsCompiler/LlvmBindings/BitcodeModule.cs index 47bdedcdca..14633814e0 100644 --- a/src/QsCompiler/LlvmBindings/BitcodeModule.cs +++ b/src/QsCompiler/LlvmBindings/BitcodeModule.cs @@ -326,18 +326,6 @@ public bool Verify(out string errorMessage) return this.moduleHandle.TryVerify(LLVMVerifierFailureAction.LLVMReturnStatusAction, out errorMessage); } - /// Gets a function by name from this module. - /// Name of the function to get. - /// The function or default if not found. - [Obsolete("Use TryGetFunction instead")] - public IrFunction? GetFunction(string name) - { - this.ThrowIfDisposed(); - - var funcRef = this.moduleHandle.GetNamedFunction(name); - return funcRef == default ? default : Value.FromHandle(funcRef); - } - /// Looks up a function in the module by name. /// Name of the function. /// The function or if not found. diff --git a/src/QsCompiler/QirGeneration/Context.cs b/src/QsCompiler/QirGeneration/Context.cs index 79f9d73f6f..3a3a881c27 100644 --- a/src/QsCompiler/QirGeneration/Context.cs +++ b/src/QsCompiler/QirGeneration/Context.cs @@ -227,6 +227,26 @@ private static string UniqueName(string name, Dictionary names) return $"{name}__{index}"; } + /// + [Obsolete("Please use NameGeneration.InteropFriendlyWrapperName instead.", true)] + public static string InteropFriendlyWrapperName(QsQualifiedName fullName) => + NameGeneration.InteropFriendlyWrapperName(fullName); + + /// + [Obsolete("Please use NameGeneration.EntryPointName instead.", true)] + public static string EntryPointName(QsQualifiedName fullName) => + NameGeneration.EntryPointName(fullName); + + /// + [Obsolete("Please use NameGeneration.FunctionName instead.", true)] + public static string FunctionName(QsQualifiedName fullName, QsSpecializationKind kind) => + NameGeneration.FunctionName(fullName, kind); + + /// + [Obsolete("Please use NameGeneration.FunctionWrapperName instead.", true)] + public static string FunctionWrapperName(QsQualifiedName fullName, QsSpecializationKind kind) => + NameGeneration.FunctionWrapperName(fullName, kind); + /// /// Order of specializations in the constant array that contains the fours IrFunctions /// associated with a callable. diff --git a/src/QsCompiler/QirGeneration/EntryPointOperationLoader.cs b/src/QsCompiler/QirGeneration/EntryPointOperationLoader.cs deleted file mode 100644 index 082946d996..0000000000 --- a/src/QsCompiler/QirGeneration/EntryPointOperationLoader.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Quantum.Qir.Serialization; -using Microsoft.Quantum.QsCompiler.SyntaxTokens; -using Microsoft.Quantum.QsCompiler.SyntaxTree; - -namespace Microsoft.Quantum.QsCompiler.QIR -{ - using QsTypeKind = QsTypeKind; - - public static class EntryPointOperationLoader - { - /// - /// Loads the entry point operations found in the syntax tree included as a resource from . - /// - /// The file info of a .NET DLL from which to load entry point operations from. - /// - /// A list of entry point operation objects representing the QIR entry point operations. - /// - /// does not exist. - /// does not contain a Q# syntax tree. - /// Encounters invalid parameters for an entry point. - public static IList LoadEntryPointOperations(FileInfo assemblyFileInfo) - { - if (!AssemblyLoader.LoadReferencedAssembly(assemblyFileInfo.FullName, out var compilation)) - { - throw new ArgumentException("Unable to read the Q# syntax tree from the given DLL."); - } - - return GenerateEntryPointOperations(compilation); - } - - private static IList GenerateEntryPointOperations(QsCompilation compilation) - { - var globals = compilation.Namespaces.GlobalCallableResolutions(); - - return compilation.EntryPoints.Select(ep => new EntryPointOperation() - { - Name = NameGeneration.InteropFriendlyWrapperName(ep), - Parameters = GetParams(globals[ep]), - }).ToList(); - } - - private static List GetParams(QsCallable callable) - { - return SyntaxGenerator.ExtractItems(callable.ArgumentTuple) - .Where(sym => !sym.Type.Resolution.IsUnitType) - .Select(sym => MakeParameter(sym)) - .ToList(); - } - - private static Parameter MakeParameter(LocalVariableDeclaration parameter) - { - var type = MapResolvedTypeToDataType(parameter.Type); - var arrayType = parameter.Type.Resolution is QsTypeKind.ArrayType innerType - ? (DataType?)MapResolvedTypeToDataType(innerType.Item) - : null; - - if (arrayType == DataType.ArrayType) - { - throw new ArgumentException("Multi-dimensional arrays are not supported types of entry point parameters."); - } - - return new Parameter() - { - Name = parameter.VariableName is QsLocalSymbol.ValidName name - ? name.Item - : throw new ArgumentException("Encountered invalid name for parameter."), - Type = type, - ArrayType = arrayType, - }; - } - - private static DataType MapResolvedTypeToDataType(ResolvedType rt) => rt.Resolution.Tag switch - { - QsTypeKind.Tags.Bool => DataType.BoolType, - QsTypeKind.Tags.Int => DataType.IntegerType, - QsTypeKind.Tags.Double => DataType.DoubleType, - QsTypeKind.Tags.Pauli => DataType.PauliType, - QsTypeKind.Tags.Range => DataType.RangeType, - QsTypeKind.Tags.Result => DataType.ResultType, - QsTypeKind.Tags.String => DataType.StringType, - QsTypeKind.Tags.ArrayType => DataType.ArrayType, - _ => throw new ArgumentException($"Invalid type ({rt.Resolution.Tag}) for entry point parameter"), - }; - } -} diff --git a/src/QsCompiler/QirGeneration/NameGeneration.cs b/src/QsCompiler/QirGeneration/NameGeneration.cs index d854adbf2f..bcc2288225 100644 --- a/src/QsCompiler/QirGeneration/NameGeneration.cs +++ b/src/QsCompiler/QirGeneration/NameGeneration.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using Microsoft.Quantum.QsCompiler.SyntaxTree; using Microsoft.Quantum.QsCompiler.Transformations.Targeting; @@ -73,15 +72,5 @@ internal static bool TryGetTargetInstructionName(QsCallable callable, [MaybeNull return false; } } - - /// - /// Order of specializations in the constant array that contains the fours IrFunctions - /// associated with a callable. - /// - public static readonly ImmutableArray FunctionArray = ImmutableArray.Create( - QsSpecializationKind.QsBody, - QsSpecializationKind.QsAdjoint, - QsSpecializationKind.QsControlled, - QsSpecializationKind.QsControlledAdjoint); } }