/// <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));
        }
Esempio n. 2
0
 public GroupIntrinsicAttribute(GroupIntrinsicKind intrinsicKind)
 {
     IntrinsicKind = intrinsicKind;
 }
 /// <summary>
 /// Handles general group operations.
 /// </summary>
 /// <param name="context">The current invocation context.</param>
 /// <param name="kind">The kind of the group intrinsic.</param>
 /// <returns>The resulting value.</returns>
 protected abstract Value?MakeGroup(InvocationContext context, GroupIntrinsicKind kind);