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