コード例 #1
0
 private static LLVMValueRef CreateMallocFunction(this FunctionModuleContext moduleContext)
 {
     return(moduleContext.Module.AddFunction(
                "malloc",
                // TODO: should ideally use the native integer size of the context
                LLVMTypeRef.FunctionType(moduleContext.LLVMContext.VoidPointerType(), new LLVMTypeRef[] { moduleContext.LLVMContext.Int64Type }, IsVarArg: false)));
 }
コード例 #2
0
        public static LLVMValueRef CreateMalloc(this FunctionModuleContext moduleContext, IRBuilder builder, LLVMTypeRef type, string name)
        {
            LLVMValueRef mallocFunction = moduleContext.FunctionImporter.GetCachedFunction("malloc", moduleContext.CreateMallocFunction),
                         mallocCall     = builder.CreateCall(mallocFunction, new LLVMValueRef[] { type.SizeOf() }, "malloCcall");

            return(builder.CreateBitCast(mallocCall, LLVMTypeRef.PointerType(type, 0u), name));
        }
コード例 #3
0
        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();
        }
コード例 #4
0
ファイル: TraitHelpers.cs プロジェクト: rebarlang/rebar
        public static bool TryGetCloneFunction(this FunctionModuleContext moduleContext, NIType valueType, out LLVMValueRef cloneFunction)
        {
            cloneFunction = default(LLVMValueRef);
            var functionBuilder = Signatures.CreateCopyType.DefineFunctionFromExisting();

            functionBuilder.Name = "Clone";
            functionBuilder.ReplaceGenericParameters(valueType, NIType.Unset);
            NIType signature = functionBuilder.CreateType();
            NIType innerType;

            if (valueType == NITypes.String)
            {
                cloneFunction = moduleContext.FunctionImporter.GetImportedCommonFunction(CommonModules.StringCloneName);
                return(true);
            }
            if (valueType.TryDestructureSharedType(out innerType))
            {
                cloneFunction = moduleContext.GetSpecializedFunctionWithSignature(signature, FunctionCompiler.BuildSharedCloneFunction);
                return(true);
            }
            if (valueType.TryDestructureVectorType(out innerType))
            {
                cloneFunction = moduleContext.GetSpecializedFunctionWithSignature(signature, FunctionCompiler.BuildVectorCloneFunction);
                return(true);
            }

            if (valueType.TypeHasCloneTrait())
            {
                throw new NotSupportedException("Clone function not found for type: " + valueType);
            }
            return(false);
        }
コード例 #5
0
        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();
        }
コード例 #6
0
        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();
        }
コード例 #7
0
        private static LLVMValueRef GetDecrementRefCountFunction(FunctionModuleContext moduleContext, NIType valueType)
        {
            string specializedName = FunctionNames.MonomorphizeFunctionName("decrementRefCount", valueType.ToEnumerable());

            return(moduleContext.FunctionImporter.GetCachedFunction(
                       specializedName,
                       () => BuildDecrementRefCountFunction(moduleContext, specializedName, valueType)));
        }
コード例 #8
0
        public static LLVMValueRef GetImportedSynchronousFunction(this FunctionModuleContext moduleContext, MethodCallNode methodCallNode)
        {
            string targetFunctionName = FunctionCompileHandler.FunctionLLVMName(methodCallNode.TargetName);

            return(moduleContext.GetImportedFunction(
                       FunctionNames.GetSynchronousFunctionName(targetFunctionName),
                       () => moduleContext.LLVMContext.TranslateFunctionType(methodCallNode.Signature)));
        }
コード例 #9
0
        public static LLVMValueRef GetImportedInitializeStateFunction(this FunctionModuleContext moduleContext, CreateMethodCallPromise createMethodCallPromise)
        {
            string targetFunctionName = FunctionCompileHandler.FunctionLLVMName(createMethodCallPromise.TargetName);

            return(moduleContext.GetImportedFunction(
                       FunctionNames.GetInitializeStateFunctionName(targetFunctionName),
                       () => moduleContext.TranslateInitializeFunctionType(createMethodCallPromise.Signature)));
        }
コード例 #10
0
        public static LLVMValueRef CreateArrayMalloc(this FunctionModuleContext moduleContext, IRBuilder builder, LLVMTypeRef type, LLVMValueRef size, string name)
        {
            LLVMValueRef bitCastSize    = builder.CreateZExtOrBitCast(size, moduleContext.LLVMContext.Int64Type, "bitCastSize"),
                         mallocSize     = builder.CreateMul(type.SizeOf(), bitCastSize, "mallocSize"),
                         mallocFunction = moduleContext.FunctionImporter.GetCachedFunction("malloc", moduleContext.CreateMallocFunction),
                         mallocCall     = builder.CreateCall(mallocFunction, new LLVMValueRef[] { mallocSize }, "malloCcall");

            return(builder.CreateBitCast(mallocCall, LLVMTypeRef.PointerType(type, 0u), name));
        }
コード例 #11
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();
        }
コード例 #12
0
ファイル: FunctionCompiler.cs プロジェクト: rebarlang/rebar
 public FunctionCompiler(
     FunctionModuleBuilder moduleBuilder,
     FunctionCompilerSharedData sharedData,
     int codeGenValueIndices)
 {
     _moduleBuilder = moduleBuilder;
     _sharedData    = sharedData;
     ModuleContext  = new FunctionModuleContext(_sharedData.Context, _sharedData.Module, _sharedData.FunctionImporter);
     _codeGenValues = new LLVMValueRef[codeGenValueIndices];
 }
コード例 #13
0
        public static void CreateCallToCopyMemory(this FunctionModuleContext moduleContext, IRBuilder builder, LLVMValueRef destinationPtr, LLVMValueRef sourcePtr, LLVMValueRef bytesToCopy)
        {
            LLVMValueRef bytesToCopyExtend  = builder.CreateSExt(bytesToCopy, moduleContext.LLVMContext.Int64Type, "bytesToCopyExtend"),
                         sourcePtrCast      = builder.CreateBitCast(sourcePtr, moduleContext.LLVMContext.BytePointerType(), "sourcePtrCast"),
                         destinationPtrCast = builder.CreateBitCast(destinationPtr, moduleContext.LLVMContext.BytePointerType(), "destinationPtrCast");

            builder.CreateCall(
                moduleContext.FunctionImporter.GetImportedCommonFunction(CommonModules.CopyMemoryName),
                new LLVMValueRef[] { destinationPtrCast, sourcePtrCast, bytesToCopyExtend },
                string.Empty);
        }
コード例 #14
0
        public static LLVMValueRef GetSpecializedFunctionWithSignature(this FunctionModuleContext moduleContext, NIType specializedSignature, Action <FunctionModuleContext, NIType, LLVMValueRef> createFunction)
        {
            string specializedFunctionName = specializedSignature.MonomorphizeFunctionName();

            return(moduleContext.FunctionImporter.GetCachedFunction(specializedFunctionName, () =>
            {
                LLVMValueRef function = moduleContext.Module.AddFunction(specializedFunctionName, moduleContext.LLVMContext.TranslateFunctionType(specializedSignature));
                createFunction(moduleContext, specializedSignature, function);
                return function;
            }));
        }
コード例 #15
0
ファイル: TraitHelpers.cs プロジェクト: rebarlang/rebar
        public static bool TryGetDropFunction(NIType type, FunctionModuleContext moduleContext, out LLVMValueRef dropFunction)
        {
            dropFunction = default(LLVMValueRef);
            Func <FunctionModuleContext, LLVMValueRef> dropFunctionCreator;

            if (TryGetDropFunctionCreator(type, out dropFunctionCreator))
            {
                dropFunction = dropFunctionCreator(moduleContext);
                return(true);
            }
            return(false);
        }
コード例 #16
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();
        }
コード例 #17
0
        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();
        }
コード例 #18
0
ファイル: TraitHelpers.cs プロジェクト: rebarlang/rebar
        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);
            }
        }
コード例 #19
0
 public FunctionCompilerSharedData(
     ContextWrapper context,
     Module module,
     IReadOnlyList <ParameterInfo> orderedParameters,
     FunctionAllocationSet allocationSet,
     FunctionVariableStorage variableStorage,
     FunctionImporter functionImporter)
 {
     Context           = context;
     Module            = module;
     OrderedParameters = orderedParameters;
     AllocationSet     = allocationSet;
     VariableStorage   = variableStorage;
     FunctionImporter  = functionImporter;
     ModuleContext     = new FunctionModuleContext(context, module, functionImporter);
 }
コード例 #20
0
ファイル: FunctionCompiler.cs プロジェクト: rebarlang/rebar
        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();
        }
コード例 #21
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();
        }
コード例 #22
0
        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();
        }
コード例 #23
0
ファイル: FunctionCompiler.cs プロジェクト: rebarlang/rebar
        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();
        }
コード例 #24
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);
        }
コード例 #25
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();
        }
コード例 #26
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();
        }
コード例 #27
0
        internal static void BuildGetNotifierReaderPromiseFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef getNotifierReaderPromiseFunction)
        {
            LLVMTypeRef valueType                 = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First()),
                        notifierReaderType        = moduleContext.LLVMContext.CreateLLVMNotifierReaderType(valueType),
                        notifierReaderPromiseType = moduleContext.LLVMContext.CreateLLVMNotifierReaderPromiseType(valueType);

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

            builder.PositionBuilderAtEnd(entryBlock);
            // Transfer the refCount pointer from the reader to the promise
            LLVMValueRef notifierReader        = getNotifierReaderPromiseFunction.GetParam(0u),
                         refCountPtr           = builder.CreateExtractValue(notifierReader, 0u, "refCountPtr"),
                         notifierReaderPromise = builder.BuildStructValue(notifierReaderPromiseType, new[] { refCountPtr });

            builder.CreateStore(notifierReaderPromise, getNotifierReaderPromiseFunction.GetParam(1u));
            builder.CreateRetVoid();
        }
コード例 #28
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();
        }
コード例 #29
0
        internal static void BuildVectorToSliceFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorToSliceFunction)
        {
            LLVMTypeRef sliceElementType   = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First());
            LLVMTypeRef sliceReferenceType = moduleContext.LLVMContext.CreateLLVMSliceReferenceType(sliceElementType);

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

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef vectorPtr          = vectorToSliceFunction.GetParam(0u),
                         vectorBufferPtrPtr = builder.CreateStructGEP(vectorPtr, 0u, "vectorBufferPtrPtr"),
                         vectorBufferPtr    = builder.CreateLoad(vectorBufferPtrPtr, "vectorBufferPtr"),
                         vectorSizePtr      = builder.CreateStructGEP(vectorPtr, 1u, "vectorSizePtr"),
                         vectorSize         = builder.CreateLoad(vectorSizePtr, "vectorSize"),
                         sliceRef           = builder.BuildSliceReferenceValue(sliceReferenceType, vectorBufferPtr, vectorSize);

            builder.CreateStore(sliceRef, vectorToSliceFunction.GetParam(1u));
            builder.CreateRetVoid();
        }
コード例 #30
0
        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();
        }