public static void CreateDropCallIfDropFunctionExists( this FunctionModuleContext moduleContext, IRBuilder builder, NIType droppedValueType, Func <IRBuilder, LLVMValueRef> getDroppedValuePtr) { LLVMValueRef dropFunction; if (TraitHelpers.TryGetDropFunction(droppedValueType, moduleContext, out dropFunction)) { LLVMValueRef droppedValuePtr = getDroppedValuePtr(builder); builder.CreateCall(dropFunction, new LLVMValueRef[] { droppedValuePtr }, string.Empty); } }
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(); }