internal static void BuildOptionDropFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef optionDropFunction)
        {
            NIType innerType;

            signature.GetGenericParameters().First().TryDestructureOptionType(out innerType);

            LLVMBasicBlockRef entryBlock  = optionDropFunction.AppendBasicBlock("entry"),
                              isSomeBlock = optionDropFunction.AppendBasicBlock("isSome"),
                              endBlock    = optionDropFunction.AppendBasicBlock("end");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef optionPtr = optionDropFunction.GetParam(0u),
                         isSomePtr = builder.CreateStructGEP(optionPtr, 0u, "isSomePtr"),
                         isSome    = builder.CreateLoad(isSomePtr, "isSome");

            builder.CreateCondBr(isSome, isSomeBlock, endBlock);

            builder.PositionBuilderAtEnd(isSomeBlock);
            moduleContext.CreateDropCallIfDropFunctionExists(builder, innerType, b => b.CreateStructGEP(optionPtr, 1u, "innerValuePtr"));
            builder.CreateBr(endBlock);

            builder.PositionBuilderAtEnd(endBlock);
            builder.CreateRetVoid();
        }
        internal static void BuildOptionToPanicResultFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef optionToPanicResultFunction)
        {
            LLVMTypeRef elementLLVMType = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First());

            LLVMBasicBlockRef entryBlock = optionToPanicResultFunction.AppendBasicBlock("entry"),
                              someBlock  = optionToPanicResultFunction.AppendBasicBlock("some"),
                              noneBlock  = optionToPanicResultFunction.AppendBasicBlock("none");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef option = optionToPanicResultFunction.GetParam(0u),
                         isSome = builder.CreateExtractValue(option, 0u, "isSome");
            LLVMValueRef branch = builder.CreateCondBr(isSome, someBlock, noneBlock);
            // TODO: if possible, set metadata that indicates the some branch is more likely to be taken

            LLVMTypeRef panicResultType = moduleContext.LLVMContext.CreateLLVMPanicResultType(elementLLVMType);

            builder.PositionBuilderAtEnd(someBlock);
            LLVMValueRef innerValue          = builder.CreateExtractValue(option, 1u, "innerValue");
            LLVMValueRef panicContinueResult = builder.BuildStructValue(panicResultType, new LLVMValueRef[] { moduleContext.LLVMContext.AsLLVMValue(true), innerValue }, "panicContinueResult");

            builder.CreateStore(panicContinueResult, optionToPanicResultFunction.GetParam(1u));
            builder.CreateRetVoid();

            builder.PositionBuilderAtEnd(noneBlock);
            LLVMValueRef panicResult = LLVMSharp.LLVM.ConstNull(panicResultType);

            builder.CreateStore(panicResult, optionToPanicResultFunction.GetParam(1u));
            builder.CreateRetVoid();
        }
Exemple #3
0
        internal static void BuildVectorCloneFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorCloneFunction)
        {
            NIType elementType;

            signature.GetGenericParameters().First().TryDestructureVectorType(out elementType);
            LLVMTypeRef elementLLVMType = moduleContext.LLVMContext.AsLLVMType(elementType);

            LLVMBasicBlockRef entryBlock = vectorCloneFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef existingVectorPtr           = vectorCloneFunction.GetParam(0u),
                         existingVector              = builder.CreateLoad(existingVectorPtr, "existingVector"),
                         existingVectorAllocationPtr = builder.CreateExtractValue(existingVector, 0u, "existingVectorAllocationPtr"),
                         existingVectorSize          = builder.CreateExtractValue(existingVector, 1u, "existingVectorSize"),
                         existingVectorCapacity      = builder.CreateExtractValue(existingVector, 2u, "existingVectorCapacity"),
                         newVectorAllocationPtr      = moduleContext.CreateArrayMalloc(builder, elementLLVMType, existingVectorCapacity, "newVectorAllocationPtr");

            LLVMValueRef elementCloneFunction;

            if (moduleContext.TryGetCloneFunction(elementType, out elementCloneFunction))
            {
                LLVMBasicBlockRef loopStartBlock = vectorCloneFunction.AppendBasicBlock("loopStart"),
                                  loopBodyBlock  = vectorCloneFunction.AppendBasicBlock("loopBody"),
                                  loopEndBlock   = vectorCloneFunction.AppendBasicBlock("loopEnd");
                builder.CreateBr(loopStartBlock);

                builder.PositionBuilderAtEnd(loopStartBlock);
                LLVMValueRef index             = builder.CreatePhi(moduleContext.LLVMContext.Int32Type, "index");
                LLVMValueRef indexLessThanSize = builder.CreateICmp(LLVMIntPredicate.LLVMIntSLT, index, existingVectorSize, "indexLessThanSize");
                builder.CreateCondBr(indexLessThanSize, loopBodyBlock, loopEndBlock);

                builder.PositionBuilderAtEnd(loopBodyBlock);
                LLVMValueRef existingElementPtr = builder.CreateGEP(existingVectorAllocationPtr, new LLVMValueRef[] { index }, "existingElementPtr"),
                             newElementPtr      = builder.CreateGEP(newVectorAllocationPtr, new LLVMValueRef[] { index }, "newElementPtr");
                builder.CreateCall(elementCloneFunction, new LLVMValueRef[] { existingElementPtr, newElementPtr }, string.Empty);
                LLVMValueRef incrementIndex = builder.CreateAdd(index, moduleContext.LLVMContext.AsLLVMValue(1), "incrementIndex");
                builder.CreateBr(loopStartBlock);

                index.AddIncoming(moduleContext.LLVMContext.AsLLVMValue(0), entryBlock);
                index.AddIncoming(incrementIndex, loopBodyBlock);

                builder.PositionBuilderAtEnd(loopEndBlock);
            }
            else
            {
                LLVMValueRef existingVectorSizeExtend = builder.CreateSExt(existingVectorSize, moduleContext.LLVMContext.Int64Type, "existingVectorSizeExtend"),
                             bytesToCopy = builder.CreateMul(existingVectorSizeExtend, elementLLVMType.SizeOf(), "bytesToCopy");
                moduleContext.CreateCallToCopyMemory(builder, newVectorAllocationPtr, existingVectorAllocationPtr, bytesToCopy);
            }

            LLVMValueRef newVector    = builder.CreateInsertValue(existingVector, newVectorAllocationPtr, 0u, "newVector"),
                         newVectorPtr = vectorCloneFunction.GetParam(1u);

            builder.CreateStore(newVector, newVectorPtr);
            builder.CreateRetVoid();
        }
        internal static void BuildSetNotifierValueFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef setNotifierValueFunction)
        {
            NIType      valueType     = signature.GetGenericParameters().First();
            LLVMTypeRef valueLLVMType = moduleContext.LLVMContext.AsLLVMType(valueType);

            LLVMBasicBlockRef entryBlock            = setNotifierValueFunction.AppendBasicBlock("entry"),
                              readerWasWaitingBlock = setNotifierValueFunction.AppendBasicBlock("readerWasWaiting"),
                              readerWasDroppedBlock = setNotifierValueFunction.AppendBasicBlock("readerWasDropped"),
                              exitBlock             = setNotifierValueFunction.AppendBasicBlock("exit");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef notifierWriter = setNotifierValueFunction.GetParam(0u),
                         value          = setNotifierValueFunction.GetParam(1u),
                         refCountPtr    = builder.CreateExtractValue(notifierWriter, 0u, "refCountPtr"),
                         sharedDataPtr  = builder.CreateStructGEP(refCountPtr, 1u, "sharedDataPtr"),
                         valuePtr       = builder.CreateStructGEP(sharedDataPtr, SharedDataValueFieldIndex, "valuePtr"),
                         statePtr       = builder.CreateStructGEP(sharedDataPtr, SharedDataStateFieldIndex, "statePtr");

            builder.CreateStore(value, valuePtr);
            // This is Release because it needs the reader thread to observe the value store above,
            // and Acquire because it may need to observe the reader thread's waker store below.
            LLVMValueRef oldState = builder.CreateAtomicRMW(
                LLVMAtomicRMWBinOp.LLVMAtomicRMWBinOpOr,
                statePtr,
                moduleContext.LLVMContext.AsLLVMValue(WriterDroppedWithValue),
                LLVMAtomicOrdering.LLVMAtomicOrderingAcquireRelease,
                false);
            LLVMValueRef oldReaderState    = builder.CreateAnd(oldState, moduleContext.LLVMContext.AsLLVMValue(ReaderStateMask), "oldReaderState"),
                         readerStateSwitch = builder.CreateSwitch(oldReaderState, exitBlock, 2u);

            readerStateSwitch.AddCase(moduleContext.LLVMContext.AsLLVMValue(ReaderWaitingForValue), readerWasWaitingBlock);
            readerStateSwitch.AddCase(moduleContext.LLVMContext.AsLLVMValue(ReaderDropped), readerWasDroppedBlock);

            builder.PositionBuilderAtEnd(readerWasWaitingBlock);
            LLVMValueRef wakerPtr = builder.CreateStructGEP(sharedDataPtr, SharedDataWakerFieldIndex, "wakerPtr"),
                         waker    = builder.CreateLoad(wakerPtr, "waker");

            builder.CreateCall(moduleContext.FunctionImporter.GetImportedCommonFunction(CommonModules.InvokeName), new LLVMValueRef[] { waker }, string.Empty);
            builder.CreateBr(exitBlock);

            builder.PositionBuilderAtEnd(readerWasDroppedBlock);
            moduleContext.CreateDropCallIfDropFunctionExists(builder, valueType, _ => valuePtr);
            builder.CreateBr(exitBlock);

            builder.PositionBuilderAtEnd(exitBlock);
            LLVMValueRef decrementRefCountFunction = GetDecrementRefCountFunction(moduleContext, valueType.CreateNotifierSharedDataType());

            builder.CreateCall(decrementRefCountFunction, new LLVMValueRef[] { refCountPtr }, string.Empty);
            builder.CreateRetVoid();
        }
Exemple #5
0
        private static void BuildStringConcatFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      stringConcatFunction = stringModule.AddFunction(StringConcatName, CommonModuleSignatures[StringConcatName]);
            LLVMBasicBlockRef entryBlock           = stringConcatFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef slice0                    = stringConcatFunction.GetParam(0u),
                         slice1                    = stringConcatFunction.GetParam(1u),
                         sliceSize0                = builder.CreateExtractValue(slice0, 1u, "sliceSize0"),
                         sliceSize1                = builder.CreateExtractValue(slice1, 1u, "sliceSize1"),
                         concatSize                = builder.CreateAdd(sliceSize0, sliceSize1, "concatSize"),
                         concatAllocationPtr       = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), concatSize, "concatAllocationPtr"),
                         concatAllocationOffsetPtr = builder.CreateGEP(concatAllocationPtr, new LLVMValueRef[] { sliceSize0 }, "concatAllocationOffsetPtr"),
                         stringPtr                 = stringConcatFunction.GetParam(2u),
                         stringAllocationPtrPtr    = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr             = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr");

            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice0, concatAllocationPtr }, string.Empty);
            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice1, concatAllocationOffsetPtr }, string.Empty);
            builder.CreateStore(concatAllocationPtr, stringAllocationPtrPtr);
            builder.CreateStore(concatSize, stringSizePtr);
            builder.CreateRetVoid();
        }
Exemple #6
0
        private static void BuildStringFromSliceFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      stringFromSliceFunction = stringModule.AddFunction(StringFromSliceName, CommonModuleSignatures[StringFromSliceName]);
            LLVMBasicBlockRef entryBlock = stringFromSliceFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringSliceReference   = stringFromSliceFunction.GetParam(0u),
                         stringPtr              = stringFromSliceFunction.GetParam(1u),
                         stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr          = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr");

            LLVMValueRef sliceAllocationPtr = builder.CreateExtractValue(stringSliceReference, 0u, "sliceAllocationPtr");
            LLVMValueRef sliceSize          = builder.CreateExtractValue(stringSliceReference, 1u, "sliceSize");

            // Get a pointer to a heap allocation big enough for the string
            LLVMValueRef allocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), sliceSize, "allocationPtr");

            builder.CreateStore(allocationPtr, stringAllocationPtrPtr);

            // Copy the data from the string slice to the heap allocation
            LLVMValueRef sizeExtend = builder.CreateSExt(sliceSize, LLVMTypeRef.Int64Type(), "sizeExtend");

            builder.CreateCall(externalFunctions.CopyMemoryFunction, new LLVMValueRef[] { allocationPtr, sliceAllocationPtr, sizeExtend }, string.Empty);

            // Copy actual size into string handle
            builder.CreateStore(sliceSize, stringSizePtr);

            builder.CreateRetVoid();
        }
Exemple #7
0
        private static void BuildOpenFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      openFileHandleFunction = fileModule.AddFunction(OpenFileHandleName, CommonModuleSignatures[OpenFileHandleName]);
            LLVMBasicBlockRef entryBlock             = openFileHandleFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef pathSliceRef            = openFileHandleFunction.GetParam(0u),
                         nullTerminatedStringPtr = builder.CreateCall(_createNullTerminatedStringFromSliceFunction, new LLVMValueRef[] { pathSliceRef }, "nullTerminatedStringtPtr"),
                         readWriteAccess         = (0xC0000000u).AsLLVMValue(),
                         noShareMode             = 0u.AsLLVMValue(),
                         openAlways                        = (0x4u).AsLLVMValue(),
                         fileAttributeNormal               = (0x80u).AsLLVMValue(),
                         fileHandleOptionPtr               = openFileHandleFunction.GetParam(1u),
                         fileHandleIsSomePtr               = builder.CreateStructGEP(fileHandleOptionPtr, 0u, "fileHandleIsSomePtr"),
                         fileHandleInnerValuePtr           = builder.CreateStructGEP(fileHandleOptionPtr, 1u, "fileHandleInnerValuePtr"),
                         fileHandleInnerValueFileHandlePtr = builder.CreateStructGEP(fileHandleInnerValuePtr, 0u, "fileHandleInnerValueFileHandlePtr"),
                         fileHandle                        = builder.CreateCall(
                externalFunctions.CreateFileAFunction,
                new LLVMValueRef[] { nullTerminatedStringPtr, readWriteAccess, noShareMode, LLVMExtensions.NullVoidPointer, openAlways, fileAttributeNormal, LLVMExtensions.NullVoidPointer },
                "fileHandle");

            builder.CreateFree(nullTerminatedStringPtr);
            builder.CreateStore(true.AsLLVMValue(), fileHandleIsSomePtr);
            builder.CreateStore(fileHandle, fileHandleInnerValueFileHandlePtr);
            builder.CreateRetVoid();
        }
        internal static void BuildCreateNotifierPairFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef createNotifierPairFunction)
        {
            LLVMTypeRef valueType          = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First()),
                        notifierReaderType = moduleContext.LLVMContext.CreateLLVMNotifierReaderType(valueType),
                        notifierWriterType = moduleContext.LLVMContext.CreateLLVMNotifierWriterType(valueType);

            LLVMBasicBlockRef entryBlock = createNotifierPairFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMTypeRef  sharedDataType        = moduleContext.LLVMContext.CreateLLVMNotifierSharedDataType(valueType);
            LLVMTypeRef  refCountType          = moduleContext.LLVMContext.CreateLLVMRefCountType(sharedDataType);
            LLVMValueRef refCountAllocationPtr = moduleContext.CreateMalloc(builder, refCountType, "refCountAllocationPtr"),
                         refCount = builder.BuildStructValue(
                refCountType,
                new LLVMValueRef[] { moduleContext.LLVMContext.AsLLVMValue(2), LLVMSharp.LLVM.ConstNull(sharedDataType) },
                "refCount");

            builder.CreateStore(refCount, refCountAllocationPtr);

            LLVMValueRef notifierReader = builder.BuildStructValue(notifierReaderType, new[] { refCountAllocationPtr });

            builder.CreateStore(notifierReader, createNotifierPairFunction.GetParam(0u));
            LLVMValueRef notifierWriter = builder.BuildStructValue(notifierWriterType, new[] { refCountAllocationPtr });

            builder.CreateStore(notifierWriter, createNotifierPairFunction.GetParam(1u));
            builder.CreateRetVoid();
        }
        private LLVMValueRef BuildInitializeStateFunction(IEnumerable <LLVMTypeRef> parameterTypes)
        {
            LLVMTypeRef initializeStateFunctionType = LLVMTypeRef.FunctionType(
                SharedData.Context.VoidPointerType(),
                parameterTypes.ToArray(),
                false);
            LLVMValueRef      initializeStateFunction = Module.AddFunction(FunctionNames.GetInitializeStateFunctionName(_functionName), initializeStateFunctionType);
            var               builder    = SharedData.Context.CreateIRBuilder();
            LLVMBasicBlockRef entryBlock = initializeStateFunction.AppendBasicBlock("entry");

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef statePtr = SharedData.ModuleContext.CreateMalloc(builder, SharedData.AllocationSet.StateType, "statePtr");

            CurrentState = new OuterFunctionCompilerState(initializeStateFunction, builder)
            {
                StateMalloc = statePtr
            };
            GenerateStoreCompletionState(RuntimeConstants.FunctionNotDoneStatus);

            InitializeParameterAllocations(initializeStateFunction, builder);
            LLVMValueRef bitCastStatePtr = builder.CreateBitCast(statePtr, SharedData.Context.VoidPointerType(), "bitCastStatePtr");

            builder.CreateRet(bitCastStatePtr);

            return(initializeStateFunction);
        }
Exemple #10
0
        internal static void BuildVectorDropFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorDropFunction)
        {
            NIType elementType;

            signature.GetGenericParameters().First().TryDestructureVectorType(out elementType);

            LLVMBasicBlockRef entryBlock = vectorDropFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef vectorPtr = vectorDropFunction.GetParam(0u),
                         vectorAllocationPtrPtr = builder.CreateStructGEP(vectorPtr, 0u, "vectorAllocationPtrPtr"),
                         vectorAllocationPtr    = builder.CreateLoad(vectorAllocationPtrPtr, "vectorAllocationPtr");

            LLVMValueRef elementDropFunction;

            if (TraitHelpers.TryGetDropFunction(elementType, moduleContext, out elementDropFunction))
            {
                LLVMValueRef vectorSizePtr       = builder.CreateStructGEP(vectorPtr, 1u, "vectorSizePtr"),
                             vectorSize          = builder.CreateLoad(vectorSizePtr, "vectorSize");
                LLVMBasicBlockRef loopStartBlock = vectorDropFunction.AppendBasicBlock("loopStart"),
                                  loopBodyBlock  = vectorDropFunction.AppendBasicBlock("loopBody"),
                                  loopEndBlock   = vectorDropFunction.AppendBasicBlock("loopEnd");
                builder.CreateBr(loopStartBlock);

                builder.PositionBuilderAtEnd(loopStartBlock);
                LLVMValueRef index             = builder.CreatePhi(moduleContext.LLVMContext.Int32Type, "index");
                LLVMValueRef indexLessThanSize = builder.CreateICmp(LLVMIntPredicate.LLVMIntSLT, index, vectorSize, "indexLessThanSize");
                builder.CreateCondBr(indexLessThanSize, loopBodyBlock, loopEndBlock);

                builder.PositionBuilderAtEnd(loopBodyBlock);
                LLVMValueRef elementPtr = builder.CreateGEP(vectorAllocationPtr, new LLVMValueRef[] { index }, "elementPtr");
                builder.CreateCall(elementDropFunction, new LLVMValueRef[] { elementPtr }, string.Empty);
                LLVMValueRef incrementIndex = builder.CreateAdd(index, moduleContext.LLVMContext.AsLLVMValue(1), "incrementIndex");
                builder.CreateBr(loopStartBlock);

                index.AddIncoming(moduleContext.LLVMContext.AsLLVMValue(0), entryBlock);
                index.AddIncoming(incrementIndex, loopBodyBlock);

                builder.PositionBuilderAtEnd(loopEndBlock);
            }

            builder.CreateFree(vectorAllocationPtr);
            builder.CreateRetVoid();
        }
Exemple #11
0
        internal static void BuildVectorRemoveLastFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorRemoveLastFunction)
        {
            NIType      elementType           = signature.GetGenericParameters().First();
            LLVMTypeRef elementLLVMType       = moduleContext.LLVMContext.AsLLVMType(elementType),
                        elementOptionLLVMType = moduleContext.LLVMContext.CreateLLVMOptionType(elementLLVMType);

            LLVMBasicBlockRef entryBlock       = vectorRemoveLastFunction.AppendBasicBlock("entry"),
                              hasElementsBlock = vectorRemoveLastFunction.AppendBasicBlock("hasElements"),
                              noElementsBlock  = vectorRemoveLastFunction.AppendBasicBlock("noElements"),
                              endBlock         = vectorRemoveLastFunction.AppendBasicBlock("end");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef vectorPtr        = vectorRemoveLastFunction.GetParam(0u),
                         vectorSizePtr    = builder.CreateStructGEP(vectorPtr, 1u, "vectorSizePtr"),
                         vectorSize       = builder.CreateLoad(vectorSizePtr, "vectorSize"),
                         optionElementPtr = vectorRemoveLastFunction.GetParam(1u),
                         hasElements      = builder.CreateICmp(LLVMIntPredicate.LLVMIntSGT, vectorSize, moduleContext.LLVMContext.AsLLVMValue(0), "hasElements");

            builder.CreateCondBr(hasElements, hasElementsBlock, noElementsBlock);

            builder.PositionBuilderAtEnd(hasElementsBlock);
            LLVMValueRef vectorAllocationPtrPtr = builder.CreateStructGEP(vectorPtr, 0u, "vectorAllocationPtrPtr"),
                         vectorAllocationPtr    = builder.CreateLoad(vectorAllocationPtrPtr, "vectorAllocationPtr"),
                         lastIndex          = builder.CreateSub(vectorSize, moduleContext.LLVMContext.AsLLVMValue(1), "lastIndex"),
                         elementToRemovePtr = builder.CreateGEP(vectorAllocationPtr, new LLVMValueRef[] { lastIndex }, "elementToRemovePtr"),
                         elementToRemove    = builder.CreateLoad(elementToRemovePtr, "elementToRemove"),
                         someElement        = moduleContext.LLVMContext.BuildOptionValue(builder, elementOptionLLVMType, elementToRemove);

            builder.CreateStore(lastIndex, vectorSizePtr);
            builder.CreateBr(endBlock);

            builder.PositionBuilderAtEnd(noElementsBlock);
            LLVMValueRef noneElement = moduleContext.LLVMContext.BuildOptionValue(builder, elementOptionLLVMType, null);

            builder.CreateBr(endBlock);

            builder.PositionBuilderAtEnd(endBlock);
            LLVMValueRef optionElement = builder.CreatePhi(elementOptionLLVMType, "optionElement");

            optionElement.AddIncoming(someElement, hasElementsBlock);
            optionElement.AddIncoming(noneElement, noElementsBlock);
            builder.CreateStore(optionElement, optionElementPtr);
            builder.CreateRetVoid();
        }
Exemple #12
0
        internal static void BuildVectorInitializeFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorInitializeFunction)
        {
            LLVMTypeRef elementLLVMType = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First());
            LLVMTypeRef vectorLLVMType  = moduleContext.LLVMContext.CreateLLVMVectorType(elementLLVMType);

            LLVMBasicBlockRef entryBlock = vectorInitializeFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef element             = vectorInitializeFunction.GetParam(0u),
                         size                = vectorInitializeFunction.GetParam(1u),
                         vectorPtr           = vectorInitializeFunction.GetParam(2u),
                         allocationPtr       = moduleContext.CreateArrayMalloc(builder, elementLLVMType, size, "allocationPtr");
            LLVMBasicBlockRef loopStartBlock = vectorInitializeFunction.AppendBasicBlock("loopStart"),
                              loopBodyBlock  = vectorInitializeFunction.AppendBasicBlock("loopBody"),
                              loopEndBlock   = vectorInitializeFunction.AppendBasicBlock("loopEnd");

            builder.CreateBr(loopStartBlock);

            builder.PositionBuilderAtEnd(loopStartBlock);
            LLVMValueRef index             = builder.CreatePhi(moduleContext.LLVMContext.Int32Type, "index");
            LLVMValueRef indexLessThanSize = builder.CreateICmp(LLVMIntPredicate.LLVMIntSLT, index, size, "indexLessThanSize");

            builder.CreateCondBr(indexLessThanSize, loopBodyBlock, loopEndBlock);

            builder.PositionBuilderAtEnd(loopBodyBlock);
            LLVMValueRef vectorIndexPtr = builder.CreateGEP(allocationPtr, new LLVMValueRef[] { index }, "vectorIndexPtr");

            builder.CreateStore(element, vectorIndexPtr);
            LLVMValueRef incrementIndex = builder.CreateAdd(index, moduleContext.LLVMContext.AsLLVMValue(1), "incrementIndex");

            builder.CreateBr(loopStartBlock);

            builder.PositionBuilderAtEnd(loopEndBlock);
            LLVMValueRef vector = builder.BuildStructValue(
                vectorLLVMType,
                new LLVMValueRef[] { allocationPtr, size, size },
                "vector");

            builder.CreateStore(vector, vectorPtr);
            builder.CreateRetVoid();

            index.AddIncoming(moduleContext.LLVMContext.AsLLVMValue(0), entryBlock);
            index.AddIncoming(incrementIndex, loopBodyBlock);
        }
Exemple #13
0
        private SNode Visit(SNode node)
        {
            LLVMTypeRef[] paramType = { };
            var           funcType  = LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, paramType);

            func  = mod.AddFunction("main", funcType);
            entry = func.AppendBasicBlock("entry");
            var body = func.AppendBasicBlock("body");

            blockStack.Add(entry);
            blockStack.Add(body);
            symbolTables.Add(new LLVMSymbolTable(symbolTables.Last()));
            builder.PositionAtEnd(body);
            Visit(node.CompoundStatement);
            builder.BuildRetVoid();
            builder.PositionAtEnd(entry);
            builder.BuildBr(body);
            return(node);
        }
        internal static void BuildNotifierWriterDropFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef notifierValueDropFunction)
        {
            NIType notifierWriterType = signature.GetGenericParameters().First(),
                   valueType          = notifierWriterType.GetGenericParameters().First();

            LLVMBasicBlockRef entryBlock            = notifierValueDropFunction.AppendBasicBlock("entry"),
                              readerWasWaitingBlock = notifierValueDropFunction.AppendBasicBlock("readerWasWaiting"),
                              exitBlock             = notifierValueDropFunction.AppendBasicBlock("exit");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef notifierWriterPtr = notifierValueDropFunction.GetParam(0u),
                         notifierWriter    = builder.CreateLoad(notifierWriterPtr, "notifierWriter"),
                         refCountPtr       = builder.CreateExtractValue(notifierWriter, 0u, "refCountPtr"),
                         sharedDataPtr     = builder.CreateStructGEP(refCountPtr, 1u, "sharedDataPtr"),
                         valuePtr          = builder.CreateStructGEP(sharedDataPtr, SharedDataValueFieldIndex, "valuePtr"),
                         statePtr          = builder.CreateStructGEP(sharedDataPtr, SharedDataStateFieldIndex, "statePtr");
            // This is Acquire because it may need to observe the reader thread's waker store below.
            LLVMValueRef oldState = builder.CreateAtomicRMW(
                LLVMAtomicRMWBinOp.LLVMAtomicRMWBinOpOr,
                statePtr,
                moduleContext.LLVMContext.AsLLVMValue(WriterDroppedWithoutValue),
                LLVMAtomicOrdering.LLVMAtomicOrderingAcquire,
                false);
            LLVMValueRef oldReaderState   = builder.CreateAnd(oldState, moduleContext.LLVMContext.AsLLVMValue(ReaderStateMask), "oldReaderState"),
                         readerWasWaiting = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, oldReaderState, moduleContext.LLVMContext.AsLLVMValue(ReaderWaitingForValue), "readerWasWaiting");

            builder.CreateCondBr(readerWasWaiting, readerWasWaitingBlock, exitBlock);

            builder.PositionBuilderAtEnd(readerWasWaitingBlock);
            LLVMValueRef wakerPtr = builder.CreateStructGEP(sharedDataPtr, SharedDataWakerFieldIndex, "wakerPtr"),
                         waker    = builder.CreateLoad(wakerPtr, "waker");

            builder.CreateCall(moduleContext.FunctionImporter.GetImportedCommonFunction(CommonModules.InvokeName), new LLVMValueRef[] { waker }, string.Empty);
            builder.CreateBr(exitBlock);

            builder.PositionBuilderAtEnd(exitBlock);
            LLVMValueRef decrementRefCountFunction = GetDecrementRefCountFunction(moduleContext, valueType.CreateNotifierSharedDataType());

            builder.CreateCall(decrementRefCountFunction, new LLVMValueRef[] { refCountPtr }, string.Empty);
            builder.CreateRetVoid();
        }
Exemple #15
0
        private static LLVMValueRef BuildDecrementRefCountFunction(FunctionModuleContext moduleContext, string functionName, NIType valueType)
        {
            LLVMTypeRef functionType = LLVMTypeRef.FunctionType(
                moduleContext.LLVMContext.VoidType,
                new LLVMTypeRef[]
            {
                LLVMTypeRef.PointerType(moduleContext.LLVMContext.CreateLLVMRefCountType(moduleContext.LLVMContext.AsLLVMType(valueType)), 0u)
            },
                false);
            LLVMValueRef      decrementRefCountFunction = moduleContext.Module.AddFunction(functionName, functionType);
            LLVMBasicBlockRef entryBlock           = decrementRefCountFunction.AppendBasicBlock("entry"),
                              noRefsRemainingBlock = decrementRefCountFunction.AppendBasicBlock("noRefsRemaining"),
                              endBlock             = decrementRefCountFunction.AppendBasicBlock("end");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef refCountObjectPtr = decrementRefCountFunction.GetParam(0u),
                         referenceCountPtr = builder.CreateStructGEP(refCountObjectPtr, 0u, "referenceCountPtr"),
                         one = moduleContext.LLVMContext.AsLLVMValue(1),
                         previousReferenceCount = builder.CreateAtomicRMW(
                LLVMAtomicRMWBinOp.LLVMAtomicRMWBinOpSub,
                referenceCountPtr,
                one,
                // Since the decrement to the reference count does not have any effect until after we branch,
                // we only need monotonic ordering here.
                // See the documentation about atomic orderings here: https://llvm.org/docs/LangRef.html#atomic-memory-ordering-constraints
                LLVMAtomicOrdering.LLVMAtomicOrderingMonotonic,
                false),
                         noRefsRemaining = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, previousReferenceCount, one, "noRefsRemaining");

            builder.CreateCondBr(noRefsRemaining, noRefsRemainingBlock, endBlock);

            builder.PositionBuilderAtEnd(noRefsRemainingBlock);
            moduleContext.CreateDropCallIfDropFunctionExists(builder, valueType, b => b.CreateStructGEP(refCountObjectPtr, 1u, "valuePtr"));
            builder.CreateFree(refCountObjectPtr);
            builder.CreateBr(endBlock);

            builder.PositionBuilderAtEnd(endBlock);
            builder.CreateRetVoid();
            return(decrementRefCountFunction);
        }
        /// <summary>
        /// Tries to implement a method defined in the <see cref="System.String"/> class.
        /// </summary>
        /// <param name="method">An internal call method to implement.</param>
        /// <param name="function"><paramref name="method"/>'s corresponding LLVM function.</param>
        /// <returns><c>true</c> if <paramref name="method"/> was implemented; otherwise, <c>false</c>.</returns>
        private bool TryImplementString(IMethod method, LLVMValueRef function, ModuleBuilder module)
        {
            if (!IsStaticMethodOf(method, "System.String"))
            {
                return(false);
            }

            var name       = method.Name.ToString();
            var paramCount = method.Parameters.Count;

            if (name == "FastAllocateString" && paramCount == 1)
            {
                var dataType = method.ParentType;
                var llvmType = module.ImportType(dataType);
                var fields   = MethodBodyEmitter.DecomposeStringFields(dataType, module);

                var ep = function.AppendBasicBlock("entry");
                using (var builder = new IRBuilder(module.Context))
                {
                    builder.PositionBuilderAtEnd(ep);

                    var size = LLVM.SizeOf(llvmType.GetStructElementTypes()[fields.DataFieldIndex]);

                    var value = module.GC.EmitAllocObject(
                        dataType,
                        builder.CreateMul(
                            builder.CreateZExt(
                                function.GetParam(0),
                                size.TypeOf(),
                                ""),
                            size,
                            "bytecount"),
                        module,
                        builder,
                        "str");

                    var lengthPtr = fields.GetLengthPtr(value, builder);
                    builder.CreateStore(
                        builder.CreateTrunc(
                            function.GetParam(0),
                            lengthPtr.TypeOf().GetElementType(),
                            ""),
                        fields.GetLengthPtr(value, builder));
                    builder.CreateRet(value);
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
        static void BuildFilterFunclet(LLVMModuleRef module, LLVMTypeRef[] funcletArgTypes)
        {
            LlvmFilterFunclet = module.AddFunction("LlvmFilterFunclet", LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32, funcletArgTypes, false));
            var            block          = LlvmFilterFunclet.AppendBasicBlock("Filter");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            LLVMValueRef filterResult = funcletBuilder.BuildCall(LlvmFilterFunclet.GetParam(0), new LLVMValueRef[] { LlvmFilterFunclet.GetParam(1) }, "callFilter");

            funcletBuilder.BuildRet(filterResult);
            funcletBuilder.Dispose();
        }
Exemple #18
0
        internal static void BuildSharedGetValueFunction(FunctionModuleContext functionCompiler, NIType signature, LLVMValueRef sharedGetValueFunction)
        {
            LLVMBasicBlockRef entryBlock = sharedGetValueFunction.AppendBasicBlock("entry");
            var builder = functionCompiler.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef shared      = builder.CreateLoad(sharedGetValueFunction.GetParam(0u), "shared"),
                         valuePtr    = builder.CreateStructGEP(shared, 1u, "valuePtr"),
                         valuePtrPtr = sharedGetValueFunction.GetParam(1u);

            builder.CreateStore(valuePtr, valuePtrPtr);
            builder.CreateRetVoid();
        }
Exemple #19
0
        internal static void BuildVariantDropFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef variantDropFunction)
        {
            NIType variantType = signature.GetGenericParameters().First();

            Tuple <NIType, int>[] droppableFields = variantType.GetFields()
                                                    .Select((field, i) => new Tuple <NIType, int>(field, i))
                                                    .Where(field => field.Item1.GetDataType().TypeHasDropTrait()).ToArray();
            LLVMBasicBlockRef entryBlock = variantDropFunction.AppendBasicBlock("entry");

            Tuple <LLVMBasicBlockRef, int>[] dropBlocks = droppableFields.Select(field => new Tuple <LLVMBasicBlockRef, int>(variantDropFunction.AppendBasicBlock($"drop{field.Item1.GetName()}"), field.Item2)).ToArray();
            LLVMBasicBlockRef exitBlock = variantDropFunction.AppendBasicBlock("exit");

            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef variantPtr     = variantDropFunction.GetParam(0u),
                         variantTagPtr  = builder.CreateStructGEP(variantPtr, 0u, "variantTagPtr"),
                         variantDataPtr = builder.CreateStructGEP(variantPtr, 1u, "variantDataPtr"),
                         variantTag     = builder.CreateLoad(variantTagPtr, "variantTag"),
                         tagSwitch      = builder.CreateSwitch(variantTag, exitBlock, (uint)dropBlocks.Length);

            foreach (var pair in dropBlocks)
            {
                tagSwitch.AddCase(moduleContext.LLVMContext.AsLLVMValue((byte)pair.Item2), pair.Item1);
            }

            for (int i = 0; i < droppableFields.Length; ++i)
            {
                builder.PositionBuilderAtEnd(dropBlocks[i].Item1);
                NIType       fieldType       = droppableFields[i].Item1.GetDataType();
                LLVMTypeRef  fieldLLVMType   = moduleContext.LLVMContext.AsLLVMType(fieldType);
                LLVMValueRef bitCastFieldPtr = builder.CreateBitCast(variantDataPtr, LLVMTypeRef.PointerType(fieldLLVMType, 0u), "bitCastFieldPtr");
                moduleContext.CreateDropCallIfDropFunctionExists(builder, fieldType, _ => bitCastFieldPtr);
                builder.CreateBr(exitBlock);
            }

            builder.PositionBuilderAtEnd(exitBlock);
            builder.CreateRetVoid();
        }
Exemple #20
0
        internal static void BuildVectorAppendFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorAppendFunction)
        {
            NIType elementType = signature.GetGenericParameters().First();

            LLVMBasicBlockRef entryBlock  = vectorAppendFunction.AppendBasicBlock("entry"),
                              growBlock   = vectorAppendFunction.AppendBasicBlock("grow"),
                              appendBlock = vectorAppendFunction.AppendBasicBlock("append");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef vectorPtr         = vectorAppendFunction.GetParam(0u),
                         vectorSizePtr     = builder.CreateStructGEP(vectorPtr, 1u, "vectorSizePtr"),
                         vectorSize        = builder.CreateLoad(vectorSizePtr, "vectorSize"),
                         vectorCapacityPtr = builder.CreateStructGEP(vectorPtr, 2u, "vectorCapacityPtr"),
                         vectorCapacity    = builder.CreateLoad(vectorCapacityPtr, "vectorCapacity"),
                         vectorIsFull      = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, vectorSize, vectorCapacity, "vectorIsFull");

            builder.CreateCondBr(vectorIsFull, growBlock, appendBlock);

            builder.PositionBuilderAtEnd(growBlock);
            string       specializedName    = FunctionNames.MonomorphizeFunctionName("vector_grow", elementType.ToEnumerable());
            LLVMValueRef vectorGrowFunction = moduleContext.FunctionImporter.GetCachedFunction(
                specializedName,
                () => CreateVectorGrowFunction(moduleContext, specializedName, elementType));

            builder.CreateCall(vectorGrowFunction, new LLVMValueRef[] { vectorPtr }, string.Empty);
            builder.CreateBr(appendBlock);

            builder.PositionBuilderAtEnd(appendBlock);
            LLVMValueRef vectorAllocationPtrPtr = builder.CreateStructGEP(vectorPtr, 0u, "vectorAllocationPtrPtr"),
                         vectorAllocationPtr    = builder.CreateLoad(vectorAllocationPtrPtr, "vectorAllocationPtr"),
                         elementPtr             = builder.CreateGEP(vectorAllocationPtr, new LLVMValueRef[] { vectorSize }, "elementPtr"),
                         incrementedSize        = builder.CreateAdd(vectorSize, moduleContext.LLVMContext.AsLLVMValue(1), "incrementedSize");

            builder.CreateStore(vectorAppendFunction.GetParam(1u), elementPtr);
            builder.CreateStore(incrementedSize, vectorSizePtr);
            builder.CreateRetVoid();
        }
        internal static void BuildNotifierReaderDropFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef notifierReaderDropFunction)
        {
            NIType notifierReaderType = signature.GetGenericParameters().ElementAt(0),
                   valueType          = notifierReaderType.GetGenericParameters().ElementAt(0);

            LLVMBasicBlockRef entryBlock = notifierReaderDropFunction.AppendBasicBlock("entry"),
                              writerWasDroppedWithValueBlock = notifierReaderDropFunction.AppendBasicBlock("writerWasDroppedWithValue"),
                              endBlock = notifierReaderDropFunction.AppendBasicBlock("end");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef notifierReaderPtr = notifierReaderDropFunction.GetParam(0u),
                         notifierReader    = builder.CreateLoad(notifierReaderPtr, "notifierReaderPromise"),
                         refCountPtr       = builder.CreateExtractValue(notifierReader, 0u, "refCountPtr"),
                         sharedDataPtr     = builder.CreateStructGEP(refCountPtr, 1u, "sharedDataPtr"),
                         statePtr          = builder.CreateStructGEP(sharedDataPtr, SharedDataStateFieldIndex, "statePtr");
            // This is Acquire because it may need to observe the writer's value store.
            LLVMValueRef oldState = builder.CreateAtomicRMW(
                LLVMAtomicRMWBinOp.LLVMAtomicRMWBinOpOr,
                statePtr,
                moduleContext.LLVMContext.AsLLVMValue(ReaderDropped),
                LLVMAtomicOrdering.LLVMAtomicOrderingAcquire,
                false),
                         oldWriterState            = builder.CreateAnd(oldState, moduleContext.LLVMContext.AsLLVMValue(WriterStateMask), "oldWriterState"),
                         writerWasDroppedWithValue = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, oldWriterState, moduleContext.LLVMContext.AsLLVMValue(WriterDroppedWithValue), "writerWasDroppedWithValue");

            builder.CreateCondBr(writerWasDroppedWithValue, writerWasDroppedWithValueBlock, endBlock);

            builder.PositionBuilderAtEnd(writerWasDroppedWithValueBlock);
            moduleContext.CreateDropCallIfDropFunctionExists(builder, valueType, b => b.CreateStructGEP(sharedDataPtr, SharedDataValueFieldIndex, "valuePtr"));
            builder.CreateBr(endBlock);

            builder.PositionBuilderAtEnd(endBlock);
            LLVMValueRef decrementRefCountFunction = GetDecrementRefCountFunction(moduleContext, valueType.CreateNotifierSharedDataType());

            builder.CreateCall(decrementRefCountFunction, new LLVMValueRef[] { refCountPtr }, string.Empty);
            builder.CreateRetVoid();
        }
Exemple #22
0
        private static void BuildStringToSliceFunction(Module stringModule)
        {
            LLVMValueRef      stringToSliceFunction = stringModule.AddFunction(StringToSliceName, CommonModuleSignatures[StringToSliceName]);
            LLVMBasicBlockRef entryBlock            = stringToSliceFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringPtr = stringToSliceFunction.GetParam(0u),
                         stringSliceReferencePtr = stringToSliceFunction.GetParam(1u);
            LLVMValueRef sliceReference          = builder.CreateCall(_stringFromSliceRetFunction, new LLVMValueRef[] { stringPtr }, "sliceReference");

            builder.CreateStore(sliceReference, stringSliceReferencePtr);
            builder.CreateRetVoid();
        }
        internal static void CreateSliceIndexFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef sliceIndexFunction)
        {
            NIType      elementType          = signature.GetGenericParameters().First();
            LLVMTypeRef elementPtrOptionType = moduleContext.LLVMContext.CreateLLVMOptionType(LLVMTypeRef.PointerType(moduleContext.LLVMContext.AsLLVMType(elementType), 0u));

            LLVMBasicBlockRef entryBlock        = sliceIndexFunction.AppendBasicBlock("entry"),
                              validIndexBlock   = sliceIndexFunction.AppendBasicBlock("validIndex"),
                              invalidIndexBlock = sliceIndexFunction.AppendBasicBlock("invalidIndex");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef indexPtr    = sliceIndexFunction.GetParam(0u),
                         index       = builder.CreateLoad(indexPtr, "index"),
                         sliceRef    = sliceIndexFunction.GetParam(1u),
                         sliceLength = builder.CreateExtractValue(sliceRef, 1u, "sliceLength"),
                         indexLessThanSliceLength = builder.CreateICmp(LLVMIntPredicate.LLVMIntSLT, index, sliceLength, "indexLTSliceLength"),
                         indexNonNegative         = builder.CreateICmp(LLVMIntPredicate.LLVMIntSGE, index, moduleContext.LLVMContext.AsLLVMValue(0), "indexNonNegative"),
                         indexInBounds            = builder.CreateAnd(indexLessThanSliceLength, indexNonNegative, "indexInBounds"),
                         elementPtrOptionPtr      = sliceIndexFunction.GetParam(2u);

            builder.CreateCondBr(indexInBounds, validIndexBlock, invalidIndexBlock);

            builder.PositionBuilderAtEnd(validIndexBlock);
            LLVMValueRef sliceBufferPtr = builder.CreateExtractValue(sliceRef, 0u, "sliceBufferPtr"),
                         elementPtr     = builder.CreateGEP(sliceBufferPtr, new LLVMValueRef[] { index }, "elementPtr"),
                         someElementPtr = moduleContext.LLVMContext.BuildOptionValue(builder, elementPtrOptionType, elementPtr);

            builder.CreateStore(someElementPtr, elementPtrOptionPtr);
            builder.CreateRetVoid();

            builder.PositionBuilderAtEnd(invalidIndexBlock);
            LLVMValueRef noneElementPtr = moduleContext.LLVMContext.BuildOptionValue(builder, elementPtrOptionType, null);

            builder.CreateStore(noneElementPtr, elementPtrOptionPtr);
            builder.CreateRetVoid();
        }
Exemple #24
0
        private static void BuildDropStringFunction(Module stringModule)
        {
            _dropStringFunction = stringModule.AddFunction(DropStringName, CommonModuleSignatures[DropStringName]);
            LLVMBasicBlockRef entryBlock = _dropStringFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringPtr = _dropStringFunction.GetParam(0u),
                         stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringAllocationPtr    = builder.CreateLoad(stringAllocationPtrPtr, "stringAllocationPtr");

            builder.CreateFree(stringAllocationPtr);
            builder.CreateRetVoid();
        }
Exemple #25
0
        internal static void BuildCreateYieldPromiseFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef createYieldPromiseFunction)
        {
            LLVMTypeRef valueType = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First()),
             valueReferenceType   = LLVMTypeRef.PointerType(valueType, 0u),
             yieldPromiseType     = moduleContext.LLVMContext.CreateLLVMYieldPromiseType(valueReferenceType);

            LLVMBasicBlockRef entryBlock = createYieldPromiseFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef value        = createYieldPromiseFunction.GetParam(0u),
                         yieldPromise = builder.BuildStructValue(yieldPromiseType, new[] { value });

            builder.CreateStore(yieldPromise, createYieldPromiseFunction.GetParam(1u));
            builder.CreateRetVoid();
        }
        internal static void CreateSliceToIteratorFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef sliceToIteratorFunction)
        {
            LLVMBasicBlockRef entryBlock = sliceToIteratorFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef sliceRef         = sliceToIteratorFunction.GetParam(0u),
                         sliceIteratorPtr = sliceToIteratorFunction.GetParam(1u),
                         sliceIterator    = builder.BuildStructValue(
                sliceIteratorPtr.TypeOf().GetElementType(),
                new LLVMValueRef[] { sliceRef, moduleContext.LLVMContext.AsLLVMValue(0) },
                "sliceIterator");

            builder.CreateStore(sliceIterator, sliceIteratorPtr);
            builder.CreateRetVoid();
        }
        public FunctionCompiler(Module module, string functionName, Dictionary <VariableReference, ValueSource> variableValues)
        {
            Module          = module;
            _variableValues = variableValues;

            LLVMTypeRef functionType = LLVMSharp.LLVM.FunctionType(LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { }, false);

            _topLevelFunction = Module.AddFunction(functionName, functionType);
            LLVMBasicBlockRef entryBlock = _topLevelFunction.AppendBasicBlock("entry");

            _builder = new IRBuilder();
            _builder.PositionBuilderAtEnd(entryBlock);

            _commonExternalFunctions = new CommonExternalFunctions(module);
            InitializeLocalAllocations();
        }
Exemple #28
0
        internal static void BuildSharedDropFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef sharedDropFunction)
        {
            NIType valueType;

            signature.GetGenericParameters().First().TryDestructureSharedType(out valueType);

            LLVMBasicBlockRef entryBlock = sharedDropFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef decrementRefCountFunction = GetDecrementRefCountFunction(moduleContext, valueType),
                         shared = builder.CreateLoad(sharedDropFunction.GetParam(0u), "shared");

            builder.CreateCall(decrementRefCountFunction, new LLVMValueRef[] { shared }, string.Empty);
            builder.CreateRetVoid();
        }
Exemple #29
0
        internal static void BuildYieldPromisePollFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef yieldPromisePollFunction)
        {
            LLVMTypeRef valueType       = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().ElementAt(1)),
                        valueOptionType = moduleContext.LLVMContext.CreateLLVMOptionType(valueType);

            LLVMBasicBlockRef entryBlock = yieldPromisePollFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef yieldPromisePtr = yieldPromisePollFunction.GetParam(0u),
                         valuePtr        = builder.CreateStructGEP(yieldPromisePtr, 0u, "valuePtr"),
                         value           = builder.CreateLoad(valuePtr, "value"),
                         someValue       = moduleContext.LLVMContext.BuildOptionValue(builder, valueOptionType, value);

            builder.CreateStore(someValue, yieldPromisePollFunction.GetParam(2u));
            builder.CreateRetVoid();
        }
Exemple #30
0
        private static void BuildCreateEmptyStringFunction(Module stringModule)
        {
            _createEmptyStringFunction = stringModule.AddFunction(CreateEmptyStringName, CommonModuleSignatures[CreateEmptyStringName]);
            LLVMBasicBlockRef entryBlock = _createEmptyStringFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringPtr = _createEmptyStringFunction.GetParam(0u),
                         stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringLengthPtr        = builder.CreateStructGEP(stringPtr, 1u, "stringLengthPtr"),
                         allocationPtr          = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), 4.AsLLVMValue(), "allocationPtr");

            builder.CreateStore(allocationPtr, stringAllocationPtrPtr);
            builder.CreateStore(0.AsLLVMValue(), stringLengthPtr);
            builder.CreateRetVoid();
        }