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)); }
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)); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); } }
private static void CompileNothing(FunctionCompiler compiler, FunctionalNode noopNode) { }
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."); } }