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(); }
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(); }
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(); }
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(); }
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); }
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(); }
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(); }
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); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }