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> /// Appends the address of the given register argument with a cast. /// </summary> /// <param name="argument">The argument to append.</param> /// <param name="valueType">The value type.</param> public void AppendArgumentAddressWithCast( Variable argument, ArithmeticBasicValueType valueType) { AppendArgument(); stringBuilder.Append('('); stringBuilder.Append( CLTypeGenerator.GetBasicValueType(valueType)); stringBuilder.Append(CLInstructions.DereferenceOperation); stringBuilder.Append(')'); AppendCommand(CLInstructions.AddressOfOperation); Append(argument); }
/// <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(); } }
/// <summary> /// Appends a cast to the given arithmetic basic value type. /// </summary> /// <param name="type">The target type.</param> public void AppendCast(ArithmeticBasicValueType type) { var typeExpression = CLTypeGenerator.GetBasicValueType(type); AppendCast(typeExpression); }