/// <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)); }
/// <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))); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }