Example #1
0
        internal static LLVM.FunctionCompileResult CompileFunctionForLLVM(
            DfirRoot dfirRoot,
            CompileCancellationToken cancellationToken,
            Dictionary <CompilableDefinitionName, bool> calleesIsYielding,
            Dictionary <CompilableDefinitionName, bool> calleesMayPanic,
            string compiledFunctionName = "")
        {
            // TODO: running this here because it needs to know which callee Functions are yielding/panicking.
            new AsyncNodeDecompositionTransform(calleesIsYielding, calleesMayPanic, new NodeInsertionTypeUnificationResultFactory())
            .Execute(dfirRoot, cancellationToken);

            ExecutionOrderSortingVisitor.SortDiagrams(dfirRoot);

            var asyncStateGrouper = new AsyncStateGrouper();

            asyncStateGrouper.Execute(dfirRoot, cancellationToken);
            IEnumerable <AsyncStateGroup> asyncStateGroups = asyncStateGrouper.GetAsyncStateGroups();

            using (var contextWrapper = new LLVM.ContextWrapper())
            {
                var module           = contextWrapper.CreateModule("module");
                var functionImporter = new LLVM.FunctionImporter(contextWrapper, module);

                var codeGenExpander = new CodeGenExpander(
                    dfirRoot,
                    new LLVM.FunctionModuleContext(contextWrapper, module, functionImporter),
                    calleesMayPanic);
                asyncStateGroups.ForEach(codeGenExpander.ExpandAsyncStateGroup);

    #if DEBUG
                string prettyPrintAsyncStateGroups = asyncStateGroups.PrettyPrintAsyncStateGroups();
    #endif
                bool isYielding = asyncStateGroups.Select(g => g.FunctionId).Distinct().HasMoreThan(1);
                bool mayPanic   = asyncStateGroups.Any(group => group.StartsWithPanicOrContinue);

                var variableStorage = new LLVM.FunctionVariableStorage();
                var allocator       = new Allocator(contextWrapper, variableStorage, asyncStateGroups);
                allocator.Execute(dfirRoot, cancellationToken);

                compiledFunctionName = string.IsNullOrEmpty(compiledFunctionName) ? FunctionLLVMName(dfirRoot.CompileSpecification.Name) : compiledFunctionName;

                var parameterInfos = dfirRoot.DataItems.OrderBy(d => d.ConnectorPaneIndex).Select(ToParameterInfo).ToArray();
                var sharedData     = new LLVM.FunctionCompilerSharedData(
                    contextWrapper,
                    module,
                    parameterInfos,
                    allocator.AllocationSet,
                    variableStorage,
                    functionImporter);
                var moduleBuilder = isYielding
                    ? new LLVM.AsynchronousFunctionModuleBuilder(sharedData, compiledFunctionName, asyncStateGroups)
                    : (LLVM.FunctionModuleBuilder) new LLVM.SynchronousFunctionModuleBuilder(sharedData, compiledFunctionName, asyncStateGroups);
                sharedData.VisitationHandler = new LLVM.FunctionCompiler(moduleBuilder, sharedData, codeGenExpander.ReservedIndexCount);

                moduleBuilder.CompileFunction();
                module.VerifyAndThrowIfInvalid();
                return(new LLVM.FunctionCompileResult(new LLVM.ContextFreeModule(module), isYielding, mayPanic));
            }
        }
 public FunctionCompilerSharedData(
     ContextWrapper context,
     Module module,
     IReadOnlyList <ParameterInfo> orderedParameters,
     FunctionAllocationSet allocationSet,
     FunctionVariableStorage variableStorage,
     FunctionImporter functionImporter)
 {
     Context           = context;
     Module            = module;
     OrderedParameters = orderedParameters;
     AllocationSet     = allocationSet;
     VariableStorage   = variableStorage;
     FunctionImporter  = functionImporter;
     ModuleContext     = new FunctionModuleContext(context, module, functionImporter);
 }