コード例 #1
0
        private static void CompileAssign(FunctionCompiler compiler, FunctionalNode assignNode)
        {
            ValueSource assigneeSource = compiler.GetTerminalValueSource(assignNode.InputTerminals[0]),
                        newValueSource = compiler.GetTerminalValueSource(assignNode.InputTerminals[1]);

            assigneeSource.UpdateDereferencedValue(compiler._builder, newValueSource.GetValue(compiler._builder));
        }
コード例 #2
0
        private static void CompileCreateCopy(FunctionCompiler compiler, FunctionalNode createCopyNode)
        {
            // TODO: handle deep-copyable types
            ValueSource copyFromSource = compiler.GetTerminalValueSource(createCopyNode.InputTerminals[0]),
                        copySource     = compiler.GetTerminalValueSource(createCopyNode.OutputTerminals[1]);

            copySource.UpdateValue(compiler._builder, copyFromSource.GetDeferencedValue(compiler._builder));
        }
コード例 #3
0
        private static void CompileNoneConstructor(FunctionCompiler compiler, FunctionalNode noneConstructorNode)
        {
            ValueSource outputSource = compiler.GetTerminalValueSource(noneConstructorNode.OutputTerminals[0]);
            LLVMTypeRef outputType   = noneConstructorNode
                                       .OutputTerminals[0].GetTrueVariable()
                                       .Type.AsLLVMType();

            outputSource.UpdateValue(compiler._builder, LLVMSharp.LLVM.ConstNull(outputType));
        }
コード例 #4
0
        private static void CompileExchange(FunctionCompiler compiler, FunctionalNode exchangeNode)
        {
            ValueSource valueSource1 = compiler.GetTerminalValueSource(exchangeNode.InputTerminals[0]),
                        valueSource2 = compiler.GetTerminalValueSource(exchangeNode.InputTerminals[1]);
            LLVMValueRef valueRef1   = valueSource1.GetDeferencedValue(compiler._builder),
                         valueRef2   = valueSource2.GetDeferencedValue(compiler._builder);

            valueSource1.UpdateDereferencedValue(compiler._builder, valueRef2);
            valueSource2.UpdateDereferencedValue(compiler._builder, valueRef1);
        }
コード例 #5
0
        private static void CompileSelectReference(FunctionCompiler compiler, FunctionalNode selectReferenceNode)
        {
            ValueSource selectorSource   = compiler.GetTerminalValueSource(selectReferenceNode.InputTerminals[0]),
                        trueValueSource  = compiler.GetTerminalValueSource(selectReferenceNode.InputTerminals[1]),
                        falseValueSource = compiler.GetTerminalValueSource(selectReferenceNode.InputTerminals[2]);
            LLVMValueRef selectedValue   = compiler._builder.CreateSelect(
                selectorSource.GetDeferencedValue(compiler._builder),
                trueValueSource.GetValue(compiler._builder),
                falseValueSource.GetValue(compiler._builder),
                "select");
            ValueSource selectedValueSource = compiler.GetTerminalValueSource(selectReferenceNode.OutputTerminals[1]);

            selectedValueSource.UpdateValue(compiler._builder, selectedValue);
        }
コード例 #6
0
        private static void CompileInspect(FunctionCompiler compiler, FunctionalNode inspectNode)
        {
            VariableReference input = inspectNode.InputTerminals[0].GetTrueVariable();

            // define global data in module for inspected value
            LLVMTypeRef  globalType    = input.Type.GetReferentType().AsLLVMType();
            string       globalName    = $"inspect_{inspectNode.UniqueId}";
            LLVMValueRef globalAddress = compiler.Module.AddGlobal(globalType, globalName);

            // Setting an initializer is necessary to distinguish this from an externally-defined global
            globalAddress.SetInitializer(LLVMSharp.LLVM.ConstNull(globalType));

            // load the input dereference value and store it in the global
            compiler._builder.CreateStore(compiler._variableValues[input].GetDeferencedValue(compiler._builder), globalAddress);
        }
コード例 #7
0
        private static void CompileSomeConstructor(FunctionCompiler compiler, FunctionalNode someConstructorNode)
        {
            ValueSource inputSource  = compiler.GetTerminalValueSource(someConstructorNode.InputTerminals[0]),
                        outputSource = compiler.GetTerminalValueSource(someConstructorNode.OutputTerminals[0]);

            // CreateSomeValueStruct creates a const struct, which isn't allowed since
            // inputSource.GetValue isn't always a constant.

            LLVMValueRef[] someFieldValues = new[]
            {
                true.AsLLVMValue(),
                           inputSource.GetValue(compiler._builder)
            };
            ((LocalAllocationValueSource)outputSource).UpdateStructValue(compiler._builder, someFieldValues);
        }
コード例 #8
0
        internal static Module CompileFunctionForLLVM(DfirRoot dfirRoot, CompileCancellationToken cancellationToken, string compiledFunctionName = "")
        {
            ExecutionOrderSortingVisitor.SortDiagrams(dfirRoot);

            Dictionary <VariableReference, LLVM.ValueSource> valueSources = VariableReference.CreateDictionaryWithUniqueVariableKeys <LLVM.ValueSource>();

            LLVM.Allocator allocator = new LLVM.Allocator(valueSources);
            allocator.Execute(dfirRoot, cancellationToken);

            Module module = new Module("module");

            compiledFunctionName = string.IsNullOrEmpty(compiledFunctionName) ? dfirRoot.SpecAndQName.RuntimeName : compiledFunctionName;
            LLVM.FunctionCompiler functionCompiler = new LLVM.FunctionCompiler(module, compiledFunctionName, valueSources);
            functionCompiler.Execute(dfirRoot, cancellationToken);
            return(module);
        }
コード例 #9
0
        private static void CompileUnaryOperation(
            FunctionCompiler compiler,
            FunctionalNode operationNode,
            Func <FunctionCompiler, LLVMValueRef, LLVMValueRef> generateOperation,
            bool mutating)
        {
            ValueSource  inputValueSource = compiler.GetTerminalValueSource(operationNode.InputTerminals[0]);
            LLVMValueRef inputValue       = inputValueSource.GetDeferencedValue(compiler._builder);
            LLVMValueRef resultValue      = generateOperation(compiler, inputValue);

            if (!mutating)
            {
                ValueSource outputValueSource = compiler.GetTerminalValueSource(operationNode.OutputTerminals[1]);
                outputValueSource.UpdateValue(compiler._builder, resultValue);
            }
            else
            {
                inputValueSource.UpdateDereferencedValue(compiler._builder, resultValue);
            }
        }
コード例 #10
0
 private static void CompileNothing(FunctionCompiler compiler, FunctionalNode noopNode)
 {
 }
コード例 #11
0
        private static void CompileOutput(FunctionCompiler compiler, FunctionalNode outputNode)
        {
            ValueSource       inputValueSource = compiler.GetTerminalValueSource(outputNode.InputTerminals[0]);
            VariableReference input            = outputNode.InputTerminals[0].GetTrueVariable();
            NIType            referentType     = input.Type.GetReferentType();

            if (referentType.IsBoolean())
            {
                LLVMValueRef value = inputValueSource.GetDeferencedValue(compiler._builder);
                compiler._builder.CreateCall(compiler._commonExternalFunctions.OutputBoolFunction, new LLVMValueRef[] { value }, string.Empty);
                return;
            }
            if (referentType.IsInteger())
            {
                LLVMValueRef outputFunction;
                switch (referentType.GetKind())
                {
                case NITypeKind.Int8:
                    outputFunction = compiler._commonExternalFunctions.OutputInt8Function;
                    break;

                case NITypeKind.UInt8:
                    outputFunction = compiler._commonExternalFunctions.OutputUInt8Function;
                    break;

                case NITypeKind.Int16:
                    outputFunction = compiler._commonExternalFunctions.OutputInt16Function;
                    break;

                case NITypeKind.UInt16:
                    outputFunction = compiler._commonExternalFunctions.OutputUInt16Function;
                    break;

                case NITypeKind.Int32:
                    outputFunction = compiler._commonExternalFunctions.OutputInt32Function;
                    break;

                case NITypeKind.UInt32:
                    outputFunction = compiler._commonExternalFunctions.OutputUInt32Function;
                    break;

                case NITypeKind.Int64:
                    outputFunction = compiler._commonExternalFunctions.OutputInt64Function;
                    break;

                case NITypeKind.UInt64:
                    outputFunction = compiler._commonExternalFunctions.OutputUInt64Function;
                    break;

                default:
                    throw new NotImplementedException($"Don't know how to display type {referentType} yet.");
                }
                LLVMValueRef value = inputValueSource.GetDeferencedValue(compiler._builder);
                compiler._builder.CreateCall(outputFunction, new LLVMValueRef[] { value }, string.Empty);
                return;
            }
            if (referentType.IsString())
            {
                // TODO: this should go away once auto-borrowing into string slices works
                // call output_string with string pointer and size
                LLVMValueRef stringPtr   = inputValueSource.GetValue(compiler._builder),
                             stringSlice = compiler._builder.CreateCall(
                    compiler.GetImportedCommonFunction(CommonModules.StringToSliceRetName),
                    new LLVMValueRef[] { stringPtr },
                    "stringSlice");
                compiler._builder.CreateCall(
                    compiler.GetImportedCommonFunction(CommonModules.OutputStringSliceName),
                    new LLVMValueRef[] { stringSlice },
                    string.Empty);
                return;
            }
            if (referentType == DataTypes.StringSliceType)
            {
                compiler.CreateCallForFunctionalNode(compiler.GetImportedCommonFunction(CommonModules.OutputStringSliceName), outputNode);
                return;
            }
            else
            {
                throw new NotImplementedException($"Don't know how to display type {referentType} yet.");
            }
        }