Ejemplo n.º 1
0
        /// <summary cref="CompilerDeviceFunctions.MakeGroup(InvocationContext, GroupIntrinsicKind)"/>
        protected override Value?MakeGroup(InvocationContext context, GroupIntrinsicKind kind)
        {
            var llvmContext = context.LLVMContext;
            var int32Type   = llvmContext.Int32Type;
            var builder     = context.Builder;

            LLVMValueRef barrierTarget;

            switch (kind)
            {
            case GroupIntrinsicKind.Barrier:
                BuildCall(builder, GroupBarrier.Value);
                return(null);

            case GroupIntrinsicKind.BarrierAnd:
                barrierTarget = GroupBarrierAnd.Value;
                break;

            case GroupIntrinsicKind.BarrierOr:
                barrierTarget = GroupBarrierOr.Value;
                break;

            case GroupIntrinsicKind.BarrierPopCount:
                barrierTarget = GroupBarrierPopCount.Value;
                break;

            default:
                throw context.CompilationContext.GetNotSupportedException(
                          ErrorMessages.NotSupportedGroupIntrinsic, kind);
            }
            Debug.Assert(barrierTarget.Pointer != IntPtr.Zero);

            if (context.GetArgs().Length != 1)
            {
                throw context.CompilationContext.GetNotSupportedException(
                          ErrorMessages.NotSupportedGroupIntrinsic, kind);
            }

            // Convert arg to int32
            var boolArg = context.GetArgs()[0];
            var arg     = BuildZExtOrBitCast(builder, boolArg.LLVMValue, int32Type, string.Empty);
            var result  = BuildCall(builder, barrierTarget, arg);

            // Convert return type to match the managed signature
            var method = context.Method as MethodInfo;

            Debug.Assert(method != null, "Invalid invocation of a group intrinsic");
            if (method.ReturnType == typeof(bool))
            {
                result = BuildICmp(builder, LLVMIntPredicate.LLVMIntEQ, result, ConstInt(
                                       int32Type, 1, false), string.Empty);
                result = BuildTrunc(builder, result, llvmContext.Int1Type, string.Empty);
            }
            return(new Value(method.ReturnType, result));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates an atomic operation.
        /// </summary>
        /// <param name="context">The current invocation context.</param>
        /// <param name="ptr">The data pointer.</param>
        /// <param name="atomic">The atomic operation.</param>
        /// <returns>The created LLVM operation.</returns>
        private static Value MakeCudaAtomic(InvocationContext context, LLVMValueRef ptr, LLVMValueRef atomic)
        {
            var args = context.GetArgs();

            return(new Value(
                       args[1].ValueType,
                       BuildCall(context.Builder, atomic, ptr, args[1].LLVMValue)));
        }
Ejemplo n.º 3
0
 /// <summary cref="CompilerDeviceFunctions.MakeConditionAssert(InvocationContext)"/>
 protected override Value?MakeConditionAssert(InvocationContext context)
 {
     return(MakeAssert(
                context,
                context.GetArgs()[0],
                null,
                context.Unit.Name,
                0,
                context.CallerMethod.ManagedFullName));
 }
Ejemplo n.º 4
0
        /// <summary cref="CompilerDeviceFunctions.MakeMessageAssert(InvocationContext)"/>
        protected override Value?MakeMessageAssert(InvocationContext context)
        {
            var args = context.GetArgs();

            return(MakeAssert(
                       context,
                       args[0],
                       args[1],
                       context.Unit.Name,
                       0,
                       context.CallerMethod.ManagedFullName));
        }
Ejemplo n.º 5
0
        /// <summary cref="CompilerDeviceFunctions.MakeMath(InvocationContext, MathIntrinsicKind)"/>
        protected override Value?MakeMath(InvocationContext context, MathIntrinsicKind kind)
        {
            var ptxAttr = context.Method.GetCustomAttribute <PTXMathFunctionAttribute>();

            if (ptxAttr == null)
            {
                throw context.CompilationContext.GetNotSupportedException(
                          ErrorMessages.NotSupportedMathIntrinsic, kind);
            }
            string funcName = ptxAttr.Name;

            if (context.Unit.HasFlags(CompileUnitFlags.FastMath))
            {
                var ptxFastAttr = context.Method.GetCustomAttribute <PTXFastMathFunctionAttribute>();
                if (ptxFastAttr != null)
                {
                    funcName = ptxFastAttr.Name;
                }
            }

            var func = GetNamedFunction(context.Unit.LLVMModule, funcName);

            if (func.Pointer == IntPtr.Zero)
            {
                throw context.CompilationContext.GetNotSupportedException(
                          ErrorMessages.NotSupportedMathIntrinsic, kind);
            }

            var args     = context.GetArgs();
            var llvmArgs = new LLVMValueRef[args.Length];

            for (int i = 0; i < args.Length; ++i)
            {
                llvmArgs[i] = args[i].LLVMValue;
            }

            var builder = context.Builder;
            var call    = BuildCall(builder, func, llvmArgs);

            // Check for required comparison for i32 return-types instead of bool values
            if (ptxAttr.BoolAsInt32)
            {
                call = BuildTrunc(builder, call, context.LLVMContext.Int1Type, string.Empty);
            }
            var info = context.Method as MethodInfo;

            Debug.Assert(info != null, "Invalid method invocation");
            return(new Value(info.ReturnType, call));
        }
Ejemplo n.º 6
0
        /// <summary cref="CompilerDeviceFunctions.MakeGrid(InvocationContext, GridIntrinsicKind)"/>
        protected override Value?MakeGrid(InvocationContext context, GridIntrinsicKind kind)
        {
            if (context.GetArgs().Length != 0 || context.GetMethodGenericArguments().Length != 0)
            {
                throw context.CompilationContext.GetNotSupportedException(
                          ErrorMessages.NotSupportedGridIntrinsic, kind);
            }

            Lazy <LLVMValueRef>[] indices;
            switch (kind)
            {
            case GridIntrinsicKind.GetGridDimension:
                indices = GetGridDimensions;
                break;

            case GridIntrinsicKind.GetGroupDimension:
                indices = GetBlockDimensions;
                break;

            default:
                throw context.CompilationContext.GetNotSupportedException(
                          ErrorMessages.NotSupportedGridIntrinsic, kind);
            }

            Debug.Assert(indices != null, "Invalid grid indices");

            var builder    = context.Builder;
            var indexValue = GetUndef(context.Unit.GetType(typeof(Index3)));

            for (int i = 0; i < 3; ++i)
            {
                var resolvedValue = BuildCall(builder, indices[i].Value);
                indexValue = BuildInsertValue(builder, indexValue, resolvedValue, i, string.Empty);
            }

            return(new Value(typeof(Index3), indexValue));
        }