コード例 #1
0
        /// <summary cref="IValueVisitor.Visit(UnaryArithmeticValue)"/>
        public void Visit(UnaryArithmeticValue value)
        {
            var argument = Load(value.Value);
            var target   = Allocate(value, value.ArithmeticBasicValueType);

            using (var statement = BeginStatement(target))
            {
                statement.AppendCast(value.ArithmeticBasicValueType);
                var operation = CLInstructions.GetArithmeticOperation(
                    value.Kind,
                    value.BasicValueType.IsFloat(),
                    out bool isFunction);

                if (isFunction)
                {
                    statement.AppendCommand(operation);
                }
                statement.BeginArguments();
                if (!isFunction)
                {
                    statement.AppendCommand(operation);
                }

                statement.AppendCast(value.ArithmeticBasicValueType);
                statement.AppendArgument(argument);
                statement.EndArguments();
            }
        }
コード例 #2
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(UnaryArithmeticValue)"/>
        public void GenerateCode(UnaryArithmeticValue value)
        {
            var argument = Load(value.Value);
            var target   = Allocate(
                value,
                value.BasicValueType == BasicValueType.Int1
                ? ArithmeticBasicValueType.UInt1 : value.ArithmeticBasicValueType);

            using var statement = BeginStatement(target);
            if (value.BasicValueType != BasicValueType.Int1)
            {
                statement.AppendCast(value.ArithmeticBasicValueType);
            }
            var operation = CLInstructions.GetArithmeticOperation(
                value.Kind,
                value.ArithmeticBasicValueType,
                out bool isFunction);

            if (isFunction)
            {
                statement.AppendCommand(operation);
            }
            statement.BeginArguments();
            if (!isFunction)
            {
                statement.AppendCommand(operation);
            }

            statement.AppendCast(value.ArithmeticBasicValueType);
            statement.AppendArgument(argument);
            statement.EndArguments();
        }
コード例 #3
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(DynamicMemoryLengthValue)"/>
        public void GenerateCode(DynamicMemoryLengthValue value)
        {
            if (value.AddressSpace != MemoryAddressSpace.Shared)
            {
                throw new InvalidCodeGenerationException();
            }

            // Resolve the name of the global variable containing the length of the
            // shared dynamic memory buffer.
            var dynamicView        = value.GetFirstUseNode().ResolveAs <Alloca>();
            var lengthVariableName = GetSharedMemoryAllocationLengthName(dynamicView);

            // Load the dynamic memory size (in bytes) from the dynamic length variable
            // and divide by the size in bytes of the array element.
            var target = Allocate(value);

            using var statement = BeginStatement(target);
            statement.AppendCast(value.Type);
            var operation = CLInstructions.GetArithmeticOperation(
                BinaryArithmeticKind.Div,
                value.BasicValueType.IsFloat(),
                out bool isFunction);

            if (isFunction)
            {
                statement.AppendCommand(operation);
                statement.BeginArguments();
            }
            else
            {
                statement.OpenParen();
            }

            statement.AppendCast(dynamicView.ArrayLength.Type);
            statement.AppendCommand(lengthVariableName);

            if (!isFunction)
            {
                statement.AppendCommand(operation);
            }

            statement.AppendArgument();
            statement.AppendCast(value.ElementType.BasicValueType);
            statement.AppendConstant(value.ElementType.Size);

            if (isFunction)
            {
                statement.EndArguments();
            }
            else
            {
                statement.CloseParen();
            }
        }
コード例 #4
0
        /// <summary cref="IValueVisitor.Visit(BinaryArithmeticValue)"/>
        public void Visit(BinaryArithmeticValue value)
        {
            var left  = Load(value.Left);
            var right = Load(value.Right);

            var target = Allocate(value, value.ArithmeticBasicValueType);

            using (var statement = BeginStatement(target))
            {
                statement.AppendCast(value.ArithmeticBasicValueType);
                var operation = CLInstructions.GetArithmeticOperation(
                    value.Kind,
                    value.BasicValueType.IsFloat(),
                    out bool isFunction);

                if (isFunction)
                {
                    statement.AppendCommand(operation);
                    statement.BeginArguments();
                }
                else
                {
                    statement.OpenParen();
                }

                statement.AppendCast(value.ArithmeticBasicValueType);
                statement.AppendArgument(left);

                if (!isFunction)
                {
                    statement.AppendCommand(operation);
                }

                statement.AppendArgument();
                statement.AppendCast(value.ArithmeticBasicValueType);
                statement.Append(right);

                if (isFunction)
                {
                    statement.EndArguments();
                }
                else
                {
                    statement.CloseParen();
                }
            }
        }
コード例 #5
0
        /// <summary cref="IValueVisitor.Visit(ViewCast)"/>
        public void Visit(ViewCast value)
        {
            var target = AllocateView(value);
            var source = LoadView(value.Value);

            // Declare view
            Declare(target);

            using (var statement = BeginStatement(target, target.PointerFieldIndex))
            {
                statement.AppendPointerCast(TypeGenerator[target.ElementType]);
                statement.Append(source);
                statement.AppendField(source.PointerFieldIndex);
            }

            var sourceElementSize = ABI.GetSizeOf(value.SourceElementType);
            var targetElementSize = ABI.GetSizeOf(value.TargetElementType);

            // var newLength = length * sourceElementSize / targetElementSize;
            using (var statement = BeginStatement(target, target.LengthFieldIndex))
            {
                statement.OpenParen();
                statement.Append(source);
                statement.AppendField(source.LengthFieldIndex);
                statement.AppendOperation(
                    CLInstructions.GetArithmeticOperation(
                        BinaryArithmeticKind.Mul,
                        false,
                        out bool _));
                statement.AppendConstant(sourceElementSize);
                statement.CloseParen();
                statement.AppendOperation(
                    CLInstructions.GetArithmeticOperation(
                        BinaryArithmeticKind.Div,
                        false,
                        out bool _));
                statement.AppendConstant(targetElementSize);
            }
        }
コード例 #6
0
        /// <summary cref="IValueVisitor.Visit(ViewCast)"/>
        public void Visit(ViewCast value)
        {
            var source  = LoadAs <ViewVariable>(value.Value);
            var pointer = source.Pointer;
            var length  = source.Length;

            var sourceElementSize = ABI.GetSizeOf(value.SourceElementType);
            var targetElementSize = ABI.GetSizeOf(value.TargetElementType);

            // var newLength = length * sourceElementSize / targetElementSize;
            var newLength = AllocateType(BasicValueType.Int32) as PrimitiveVariable;

            using (var statement = BeginStatement(newLength))
            {
                statement.OpenParen();
                statement.Append(length);
                statement.AppendOperation(
                    CLInstructions.GetArithmeticOperation(
                        BinaryArithmeticKind.Mul,
                        false,
                        out bool _));
                statement.AppendConstant(sourceElementSize);
                statement.CloseParen();
                statement.AppendOperation(
                    CLInstructions.GetArithmeticOperation(
                        BinaryArithmeticKind.Div,
                        false,
                        out bool _));
                statement.AppendConstant(targetElementSize);
            }

            var newView = new ViewVariable(
                value.Type as ViewType,
                pointer,
                newLength);

            Bind(value, newView);
        }
コード例 #7
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(AlignTo)"/>
        public void GenerateCode(AlignTo value)
        {
            // Load the base view pointer
            var source                   = Load(value.Source);
            var target                   = Allocate(value);
            var alignmentVariable        = Load(value.AlignmentInBytes);
            var arithmeticBasicValueType =
                value.Source.BasicValueType.GetArithmeticBasicValueType(true);

            // var baseOffset = (int)ptr & (alignmentInBytes - 1);
            var baseOffset = AllocateType(arithmeticBasicValueType);

            using (var statement = BeginStatement(baseOffset))
            {
                statement.AppendCast(arithmeticBasicValueType);
                statement.AppendArgument(source);
                statement.AppendCommand(CLInstructions.GetArithmeticOperation(
                                            BinaryArithmeticKind.And,
                                            isFloat: false,
                                            out bool _));
                // Optimize for the case in which the alignment is a constant value
                if (value.TryGetAlignmentConstant(out int alignment))
                {
                    statement.AppendConstant(alignment - 1);
                }
                else
                {
                    statement.AppendCommand('(');
                    statement.AppendArgument(alignmentVariable);
                    statement.AppendCommand(CLInstructions.GetArithmeticOperation(
                                                BinaryArithmeticKind.Sub,
                                                isFloat: false,
                                                out bool _));
                    statement.AppendConstant(1);
                    statement.AppendCommand(')');
                }
            }

            // if (baseOffset == 0) { 0 } else { alignment - baseOffset }
            var adjustment = AllocateType(arithmeticBasicValueType);

            using (var selectStatement = BeginStatement(adjustment))
            {
                selectStatement.AppendArgument(baseOffset);
                selectStatement.AppendCommand(" == 0 ? 0 : (");
                if (value.TryGetAlignmentConstant(out int alignmentConstant))
                {
                    selectStatement.AppendConstant(alignmentConstant);
                }
                else
                {
                    selectStatement.AppendArgument(alignmentVariable);
                }
                selectStatement.AppendCommand(CLInstructions.GetArithmeticOperation(
                                                  BinaryArithmeticKind.Sub,
                                                  isFloat: false,
                                                  out bool _));
                selectStatement.AppendArgument(baseOffset);
                selectStatement.AppendCommand(')');
            }

            // Adjust the given pointer
            using var command = BeginStatement(target);
            command.AppendCast(value.Type);
            command.AppendCommand('(');
            command.AppendCast(arithmeticBasicValueType);
            command.AppendArgument(source);
            command.AppendCommand(CLInstructions.GetArithmeticOperation(
                                      BinaryArithmeticKind.Add,
                                      isFloat: false,
                                      out bool _));
            command.AppendArgument(adjustment);
            command.AppendCommand(')');
        }