Exemple #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();
        }
Exemple #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);
        }
Exemple #3
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 #4
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 #5
0
 internal static void AddIncoming(this LLVMValueRef phiValue, LLVMValueRef incomingValue, LLVMBasicBlockRef incomingBlock)
 {
     phiValue.AddIncoming(new LLVMValueRef[] { incomingValue }, new LLVMBasicBlockRef[] { incomingBlock }, 1u);
 }