Esempio n. 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)));
 }
        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);
        }
Esempio n. 3
0
        static LLVMValueRef createMain()
        {
            var          context  = LLVM.GetGlobalContext();
            LLVMTypeRef  funcType = LLVMTypeRef.FunctionType(LLVMTypeRef.Int64Type(), new LLVMTypeRef[] {  }, false);
            LLVMValueRef function = LLVM.AddFunction(module, "main", funcType);

            return(function);
        }
 public static LLVMTypeRef PollFunctionType(ContextWrapper context) => LLVMTypeRef.FunctionType(
     context.VoidType,
     new LLVMTypeRef[]
 {
     context.VoidPointerType(),
     LLVMTypeRef.PointerType(context.ScheduledTaskFunctionType(), 0u),
     context.VoidPointerType()
 },
     false);
Esempio n. 5
0
        static ulong GetIntrinsic(string name)
        {
            var func = LLVM.GetNamedFunction(Module, name);

            func = func.Pointer == IntPtr.Zero
                                ? LLVM.AddFunction(Module, name,
                                                   LLVMTypeRef.FunctionType(LLVMTypeRef.VoidType(), new LLVMTypeRef[0], false))
                                : func;
            return((ulong)LLVM.GetPointerToGlobal(ExecutionEngine, func));
        }
        public AsynchronousFunctionModuleBuilder(
            FunctionCompilerSharedData sharedData,
            string functionName,
            IEnumerable <AsyncStateGroup> asyncStateGroups)
            : base(sharedData)
        {
            _functionName     = functionName;
            _asyncStateGroups = asyncStateGroups;

            var fireCountFields = new Dictionary <AsyncStateGroup, StateFieldValueSource>();

            foreach (AsyncStateGroup asyncStateGroup in _asyncStateGroups)
            {
                string groupName = asyncStateGroup.Label;
                if (asyncStateGroup.MaxFireCount > 1)
                {
                    fireCountFields[asyncStateGroup] = SharedData.AllocationSet.CreateStateField($"{groupName}FireCount", NITypes.Int32);
                }
            }
            SharedData.AllocationSet.InitializeStateType(sharedData.Module, functionName);
            LLVMTypeRef groupFunctionType = LLVMTypeRef.FunctionType(
                SharedData.Context.VoidType,
                new LLVMTypeRef[] { LLVMTypeRef.PointerType(SharedData.AllocationSet.StateType, 0u) },
                false);

            var functions = new Dictionary <string, LLVMValueRef>();

            foreach (AsyncStateGroup asyncStateGroup in _asyncStateGroups)
            {
                LLVMValueRef groupFunction;
                if (!functions.TryGetValue(asyncStateGroup.FunctionId, out groupFunction))
                {
                    string groupFunctionName = $"{functionName}::{asyncStateGroup.FunctionId}";
                    groupFunction = Module.AddFunction(groupFunctionName, groupFunctionType);
                    functions[asyncStateGroup.FunctionId] = groupFunction;
                }

                LLVMBasicBlockRef groupBasicBlock    = groupFunction.AppendBasicBlock($"{asyncStateGroup.Label}_begin");
                LLVMBasicBlockRef continueBasicBlock = asyncStateGroup.IsSkippable
                    ? groupFunction.AppendBasicBlock($"{asyncStateGroup.Label}_continue")
                    : default(LLVMBasicBlockRef);
                LLVMBasicBlockRef endBasicBlock = asyncStateGroup.IsSkippable
                    ? groupFunction.AppendBasicBlock($"{asyncStateGroup.Label}_end")
                    : default(LLVMBasicBlockRef);
                StateFieldValueSource fireCountStateField;
                fireCountFields.TryGetValue(asyncStateGroup, out fireCountStateField);
                AsyncStateGroups[asyncStateGroup] = new AsyncStateGroupData(asyncStateGroup, SharedData.Context, groupFunction, groupBasicBlock, continueBasicBlock, endBasicBlock, fireCountStateField);
            }
        }
Esempio n. 7
0
        public static LLVMTypeRef ToLLVMType(this Type type)
        {
            if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Vector128 <>))
            {
                var et = type.GetGenericArguments()[0];
                return(LLVMTypeRef.VectorType(et.ToLLVMType(), 16U / (uint)Marshal.SizeOf(et)));
            }
            if (typeof(MulticastDelegate).IsAssignableFrom(type))
            {
                var mi = type.GetMethod("Invoke");
                return(LLVMTypeRef.FunctionType(mi.ReturnType.ToLLVMType(),
                                                mi.GetParameters().Select(x => x.ParameterType.ToLLVMType()).ToArray(), false));
            }
            if (type == typeof(void))
            {
                return(LLVMTypeRef.VoidType());
            }
            if (type.IsPointer)
            {
                return(LLVMTypeRef.Int64Type());
            }
            switch (Activator.CreateInstance(type))
            {
            case sbyte _:
            case byte _: return(LLVMTypeRef.Int8Type());

            case short _:
            case ushort _: return(LLVMTypeRef.Int16Type());

            case int _:
            case uint _: return(LLVMTypeRef.Int32Type());

            case long _:
            case ulong _: return(LLVMTypeRef.Int64Type());

            case Int128 _:
            case UInt128 _: return(LLVMTypeRef.IntType(128));

            case float _: return(LLVMTypeRef.FloatType());

            case double _: return(LLVMTypeRef.DoubleType());

            case bool _: return(LLVMTypeRef.IntType(1));

            default: throw new NotSupportedException(type.Name);
            }
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        private static LLVMTypeRef GetLlvmType([NotNull] Type lambdaTypeParam)
        {
            switch (lambdaTypeParam)
            {
            case PrimaryType primaryType:
                if (string.Equals(primaryType.Name, "f64", Ordinal))
                {
                    return(LLVMSharp.LLVM.DoubleType());
                }
                if (string.Equals(primaryType.Name, "f32", Ordinal))
                {
                    return(LLVMTypeRef.FloatType());
                }
                if (string.Equals(primaryType.Name, "i8", Ordinal))
                {
                    return(LLVMTypeRef.Int8Type());
                }
                if (string.Equals(primaryType.Name, "i16", Ordinal))
                {
                    return(LLVMTypeRef.Int16Type());
                }
                if (string.Equals(primaryType.Name, "i32", Ordinal))
                {
                    return(LLVMTypeRef.Int32Type());
                }
                if (string.Equals(primaryType.Name, "i64", Ordinal))
                {
                    return(LLVMTypeRef.Int64Type());
                }
                break;

            case LambdaType lambdaType:
                return(LLVMTypeRef.FunctionType(GetLlvmType(lambdaType.RetType),
                                                (from type in lambdaType.ParamsList select GetLlvmType(type)).ToArray(), false));

            case SecondaryType secondaryType:
                break;
            }
            throw new NotImplementedException();
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        private static void declareCFunctions()
        {
            LLVMTypeRef PutCharType = LLVMTypeRef.FunctionType(LLVM.Int32Type(), new LLVMTypeRef[] { LLVM.Int32Type() }, false);

            LLVM.AddFunction(module, "putchar", PutCharType);
        }
Esempio n. 12
0
 public static LLVMTypeRef ScheduledTaskFunctionType(this ContextWrapper context) => LLVMTypeRef.FunctionType(context.VoidType, new[] { context.VoidPointerType() }, false);
Esempio n. 13
0
 private static LLVMTypeRef MethodPollFunctionType(this ContextWrapper context) => LLVMTypeRef.FunctionType(
     context.VoidType,
     new LLVMTypeRef[]
 {
     context.VoidPointerType(),
     LLVMTypeRef.PointerType(context.ScheduledTaskFunctionType(), 0u),
     context.VoidPointerType()
 },
     false);