private FunctionVariableStorage RunAllocator(DfirRoot function) { var cancellationToken = new CompileCancellationToken(); RunCompilationUpToAsyncNodeDecomposition(function, cancellationToken); ExecutionOrderSortingVisitor.SortDiagrams(function); var asyncStateGrouper = new AsyncStateGrouper(); asyncStateGrouper.Execute(function, cancellationToken); IEnumerable <AsyncStateGroup> asyncStateGroups = asyncStateGrouper.GetAsyncStateGroups(); using (var contextWrapper = new ContextWrapper()) { var module = contextWrapper.CreateModule("module"); var functionImporter = new FunctionImporter(contextWrapper, module); var codeGenExpander = new CodeGenExpander( function, new FunctionModuleContext(contextWrapper, module, functionImporter), new Dictionary <CompilableDefinitionName, bool>()); asyncStateGroups.ForEach(codeGenExpander.ExpandAsyncStateGroup); var variableStorage = new FunctionVariableStorage(); var allocator = new Allocator(contextWrapper, variableStorage, asyncStateGroups); allocator.Execute(function, cancellationToken); return(variableStorage); } }
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)); } }