示例#1
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();
        }
示例#2
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);
        }
示例#3
0
        internal static void BuildVectorCreateFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorCreateFunction)
        {
            LLVMTypeRef elementLLVMType = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First());

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

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef vectorPtr      = vectorCreateFunction.GetParam(0u),
                         vectorCapacity = moduleContext.LLVMContext.AsLLVMValue(4),
                         allocationPtr  = moduleContext.CreateArrayMalloc(builder, elementLLVMType, vectorCapacity, "allocationPtr"),
                         vector         = builder.BuildStructValue(
                moduleContext.LLVMContext.CreateLLVMVectorType(elementLLVMType),
                new LLVMValueRef[] { allocationPtr, moduleContext.LLVMContext.AsLLVMValue(0), vectorCapacity },
                "vector");

            builder.CreateStore(vector, vectorPtr);
            builder.CreateRetVoid();
        }
示例#4
0
        private static LLVMValueRef CreateVectorGrowFunction(FunctionModuleContext moduleContext, string functionName, NIType elementType)
        {
            LLVMTypeRef elementLLVMType        = moduleContext.LLVMContext.AsLLVMType(elementType);
            LLVMTypeRef vectorGrowFunctionType = LLVMTypeRef.FunctionType(
                moduleContext.LLVMContext.VoidType,
                new LLVMTypeRef[]
            {
                LLVMTypeRef.PointerType(moduleContext.LLVMContext.CreateLLVMVectorType(elementLLVMType), 0u),
            },
                false);

            LLVMValueRef      vectorGrowFunction = moduleContext.Module.AddFunction(functionName, vectorGrowFunctionType);
            LLVMBasicBlockRef entryBlock         = vectorGrowFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef vectorPtr         = vectorGrowFunction.GetParam(0u),
                         vector            = builder.CreateLoad(vectorPtr, "vector"),
                         oldAllocationPtr  = builder.CreateExtractValue(vector, 0u, "oldAllocationPtr"),
                         oldVectorCapacity = builder.CreateExtractValue(vector, 2u, "oldVectorCapacity"),
            // TODO: ideally handle integer overflow; also there are ways this could be smarter
                         newVectorCapacity = builder.CreateMul(oldVectorCapacity, moduleContext.LLVMContext.AsLLVMValue(2), "newVectorCapacity"),
            // TODO: handle the case where the allocation fails
                         newAllocationPtr        = moduleContext.CreateArrayMalloc(builder, elementLLVMType, newVectorCapacity, "newAllocationPtr"),
                         oldVectorCapacityExtend = builder.CreateSExt(oldVectorCapacity, moduleContext.LLVMContext.Int64Type, "oldVectorCapacityExtend"),
                         bytesToCopy             = builder.CreateMul(oldVectorCapacityExtend, elementLLVMType.SizeOf(), "bytesToCopy");

            moduleContext.CreateCallToCopyMemory(builder, newAllocationPtr, oldAllocationPtr, bytesToCopy);
            LLVMValueRef newVector0 = builder.CreateInsertValue(vector, newAllocationPtr, 0u, "newVector0"),
                         newVector  = builder.CreateInsertValue(newVector0, newVectorCapacity, 2u, "newVector");

            builder.CreateStore(newVector, vectorPtr);
            builder.CreateFree(oldAllocationPtr);
            builder.CreateRetVoid();
            return(vectorGrowFunction);
        }