예제 #1
0
        /// <summary>
        /// Generate all forward type declarations.
        /// </summary>
        /// <param name="builder">The target builder.</param>
        public void GenerateTypeDeclarations(StringBuilder builder)
        {
            foreach (var entry in mapping)
            {
                switch (entry.Key)
                {
                case PointerType pointerType:
                    builder.Append(
                        CLInstructions.TypeDefStatement);
                    builder.Append(' ');
                    builder.Append(
                        CLInstructions.GetAddressSpacePrefix(
                            pointerType.AddressSpace));
                    builder.Append(' ');
                    builder.Append(mapping[pointerType.ElementType]);
                    builder.Append(CLInstructions.DereferenceOperation);
                    builder.Append(' ');
                    builder.Append(entry.Value);
                    builder.AppendLine(";");
                    break;

                case StructureType _:
                    builder.Append(entry.Value);
                    builder.AppendLine(";");
                    break;
                }
            }
            builder.AppendLine();
        }
예제 #2
0
        public string GetVariableType(Variable variable)
        {
            switch (variable)
            {
            case PrimitiveVariable primitiveVariable:
                return(CLTypeGenerator.GetBasicValueType(primitiveVariable.BasicValueType));

            case PointerVariable pointerType:
            {
                var addressSpacePrefix = CLInstructions.GetAddressSpacePrefix(pointerType.AddressSpace);
                var elementTypeName    = TypeGenerator[pointerType.ElementType];
                if (!string.IsNullOrEmpty(addressSpacePrefix))
                {
                    elementTypeName = addressSpacePrefix + " " + elementTypeName;
                }
                return(elementTypeName + CLInstructions.DereferenceOperation);
            }

            case ObjectVariable objectVariable:
                return(TypeGenerator[objectVariable.Type]);

            default:
                throw new NotSupportedException();
            }
        }
예제 #3
0
 /// <summary cref="ITypeNodeVisitor.Visit(ViewType)"/>
 public void Visit(ViewType type)
 {
     BeginStruct(type);
     Builder.Append('\t');
     Builder.Append(CLInstructions.GetAddressSpacePrefix(type.AddressSpace));
     Builder.Append(' ');
     Builder.Append(TypeGenerator[type.ElementType]);
     Builder.AppendLine("* ptr;");
     Builder.AppendLine("\tint length;");
     EndStruct();
 }
예제 #4
0
        /// <summary>
        /// Defines a pointer type in OpenCL (if applicable).
        /// </summary>
        /// <param name="typeNode">The type to define.</param>
        private void DefinePointerType(TypeNode typeNode)
        {
            if (!(typeNode is PointerType pointerType))
            {
                return;
            }

            Builder.Append("typedef ");
            Builder.Append(CLInstructions.GetAddressSpacePrefix(pointerType.AddressSpace));
            Builder.Append(' ');
            Builder.Append(this[pointerType.ElementType]);
            Builder.Append("* ");
            Builder.Append(this[pointerType]);
            Builder.AppendLine(";");
        }
예제 #5
0
        /// <summary cref="IValueVisitor.Visit(AtomicCAS)"/>
        public void Visit(AtomicCAS atomicCAS)
        {
            var target  = Load(atomicCAS.Target);
            var value   = Load(atomicCAS.Value);
            var compare = Load(atomicCAS.CompareValue);

            var tempVariable   = AllocateType(BasicValueType.Int1) as PrimitiveVariable;
            var targetVariable = Allocate(atomicCAS);

            using (var statement = BeginStatement(tempVariable))
            {
                statement.AppendCommand(CLInstructions.AtomicCASOperation);
                statement.BeginArguments();
                statement.AppendAtomicCast(atomicCAS.ArithmeticBasicValueType);
                statement.AppendArgument(target);
                statement.AppendArgumentAddressWithCast(value, $"{CLInstructions.GetAddressSpacePrefix(MemoryAddressSpace.Generic)} {CLTypeGenerator.GetBasicValueType(atomicCAS.ArithmeticBasicValueType)} {CLInstructions.DereferenceOperation}");
                statement.AppendArgument(compare);
                statement.EndArguments();
            }

            // The OpenCL way is not compatible with the internal CAS semantic
            // We should adapt to the more general way of returning a bool in the future
            // For now, check the result of the operation and emit an atomic load
            // in the case of a failure.
            using (var statement = BeginStatement(targetVariable))
            {
                statement.Append(tempVariable);
                statement.AppendCommand(CLInstructions.SelectOperation1);
                statement.Append(value);
                statement.AppendCommand(CLInstructions.SelectOperation2);

                statement.AppendCommand(CLInstructions.AtomicLoadOperation);
                statement.BeginArguments();
                statement.AppendAtomicCast(atomicCAS.ArithmeticBasicValueType);
                statement.AppendArgument(target);
                statement.EndArguments();
            }
        }