Exemplo n.º 1
0
 public ValueReference CreateAlloca(
     TypeNode type,
     MemoryAddressSpace addressSpace)
 {
     return(CreateAlloca(
                CreatePrimitiveValue(1),
                type,
                addressSpace));
 }
Exemplo n.º 2
0
 /// <summary>
 /// Constructs a new pointer variable.
 /// </summary>
 /// <param name="id">The current variable id.</param>
 /// <param name="elementType">The pointer element type.</param>
 /// <param name="addressSpace">The associated address space.</param>
 internal PointerVariable(
     int id,
     TypeNode elementType,
     MemoryAddressSpace addressSpace)
     : base(id)
 {
     AddressSpace = addressSpace;
     ElementType  = elementType;
 }
Exemplo n.º 3
0
 private static TypeNode ComputeType(
     IRContext context,
     TypeNode allocaType,
     MemoryAddressSpace addressSpace)
 {
     return(context.CreatePointerType(
                allocaType,
                addressSpace));
 }
Exemplo n.º 4
0
 /// <summary>
 /// Creates a local allocation.
 /// </summary>
 /// <param name="location">The current location.</param>
 /// <param name="type">The type of the allocation.</param>
 /// <param name="addressSpace">The target address space.</param>
 /// <returns>A node that represents the alloca operation.</returns>
 public ValueReference CreateAlloca(
     Location location,
     TypeNode type,
     MemoryAddressSpace addressSpace) =>
 CreateAlloca(
     location,
     type,
     addressSpace,
     CreateUndefined());
Exemplo n.º 5
0
        /// <summary>
        /// Returns a cached version of an <see cref="AddressSpaceConverter"/> for known
        /// address spaces.
        /// </summary>
        /// <param name="addressSpace">The address space to convert into.</param>
        /// <returns>A cached or a new converter instance.</returns>
        public static AddressSpaceConverter GetAddressSpaceConverter(
            MemoryAddressSpace addressSpace)
        {
            int index = (int)addressSpace;

            return(index < 0 || index >= TypeConverters.Length
                ? new AddressSpaceConverter(addressSpace)
                : TypeConverters[index]);
        }
Exemplo n.º 6
0
 /// <summary>
 /// Creates a view type.
 /// </summary>
 /// <param name="elementType">The view element type.</param>
 /// <param name="addressSpace">The address space.</param>
 /// <returns>The created view type.</returns>
 public ViewType CreateViewType(
     TypeNode elementType,
     MemoryAddressSpace addressSpace)
 {
     Debug.Assert(elementType != null, "Invalid element type");
     return(CreateType(new ViewType(
                           elementType,
                           addressSpace)));
 }
Exemplo n.º 7
0
 /// <summary>
 /// Constructs a new view type.
 /// </summary>
 /// <param name="typeContext">The parent type context.</param>
 /// <param name="elementType">The element type.</param>
 /// <param name="addressSpace">The associated address space.</param>
 internal ViewType(
     IRTypeContext typeContext,
     TypeNode elementType,
     MemoryAddressSpace addressSpace)
     : base(typeContext, elementType, addressSpace)
 {
     Size = Alignment = 4;
     AddFlags(TypeFlags.ViewDependent);
 }
Exemplo n.º 8
0
 /// <summary>
 /// Creates a dynamic local memory allocation.
 /// </summary>
 /// <param name="location">The current location.</param>
 /// <param name="type">The type of the allocation.</param>
 /// <param name="addressSpace">The target address space.</param>
 /// <returns>A node that represents the alloca operation.</returns>
 public ValueReference CreateDynamicAllocaArray(
     Location location,
     TypeNode type,
     MemoryAddressSpace addressSpace) =>
 CreateStaticAllocaArray(
     location,
     CreateDynamicMemoryLengthValue(location, type, addressSpace),
     type,
     addressSpace);
Exemplo n.º 9
0
 public ValueReference CreateDynamicAllocaArray(
     Location location,
     TypeNode type,
     MemoryAddressSpace addressSpace) =>
 CreateStaticAllocaArray(
     location,
     CreatePrimitiveValue(location, -1),
     type,
     addressSpace);
Exemplo n.º 10
0
        /// <summary>
        /// Returns true if the parent cast is redundant.
        /// </summary>
        /// <param name="targetSpace">The target address space.</param>
        /// <param name="value">The current value to check.</param>
        /// <returns>True, if the parent cast is redundant.</returns>
        private static bool IsRedundantRecursive(
            MemoryAddressSpace targetSpace,
            Value value)
        {
            foreach (var use in value.Uses)
            {
                var node = use.Resolve();
                switch (node)
                {
                case MethodCall call:
                    // We cannot remove casts to other address spaces in case of a
                    // method invocation if the address spaces do not match
                    if (!call.Target.HasImplementation)
                    {
                        break;
                    }
                    var targetParam = call.Target.Parameters[use.Index];
                    if (targetParam.ParameterType is IAddressSpaceType paramType &&
                        paramType.AddressSpace == targetSpace)
                    {
                        return(false);
                    }

                    break;

                case PhiValue _:
                    // We are not allowed to remove casts in the case of phi values
                    return(false);

                case Store _:
                    // We are not allowed to remove casts in the case of alloca
                    // stores
                    if (use.Index != 0)
                    {
                        return(false);
                    }
                    break;

                case SetArrayElement _:
                case SetField _:
                    // We are not allowed to remove field or array stores to tuples
                    // with different field types
                    return(false);

                case PointerCast _:
                case LoadElementAddress _:
                case LoadFieldAddress _:
                    if (!IsRedundantRecursive(targetSpace, node))
                    {
                        return(false);
                    }
                    break;
                }
            }
            return(true);
        }
Exemplo n.º 11
0
 /// <summary>
 /// Creates an array based local allocation.
 /// </summary>
 /// <param name="location">The current location.</param>
 /// <param name="arrayLength">
 /// The array length (number of elements to allocate).
 /// </param>
 /// <param name="type">The type of the allocation.</param>
 /// <param name="addressSpace">The target address space.</param>
 /// <returns>A node that represents the alloca operation.</returns>
 public ValueReference CreateStaticAllocaArray(
     Location location,
     Value arrayLength,
     TypeNode type,
     MemoryAddressSpace addressSpace) =>
 CreateAlloca(
     location,
     type,
     addressSpace,
     arrayLength);
Exemplo n.º 12
0
 /// <summary>
 /// Constructs a new address type.
 /// </summary>
 /// <param name="typeContext">The parent type context.</param>
 /// <param name="elementType">The element type.</param>
 /// <param name="addressSpace">The associated address space.</param>
 protected AddressSpaceType(
     IRTypeContext typeContext,
     TypeNode elementType,
     MemoryAddressSpace addressSpace)
     : base(typeContext)
 {
     Debug.Assert(elementType != null, "Invalid element type");
     ElementType  = elementType;
     AddressSpace = addressSpace;
     AddFlags(elementType.Flags);
 }
Exemplo n.º 13
0
 /// <summary cref="IEnumerator.MoveNext"/>
 public bool MoveNext()
 {
     do
     {
         Current = (MemoryAddressSpace)(++index);
         if (Info.HasAddressSpace(Current))
         {
             return(true);
         }
     }while (index <= (int)MemoryAddressSpace.Local);
     return(false);
 }
Exemplo n.º 14
0
 /// <summary>
 /// Constructs a new pointer type.
 /// </summary>
 /// <param name="typeContext">The parent type context.</param>
 /// <param name="elementType">The element type.</param>
 /// <param name="addressSpace">The associated address space.</param>
 internal PointerType(
     IRTypeContext typeContext,
     TypeNode elementType,
     MemoryAddressSpace addressSpace)
     : base(typeContext, elementType, addressSpace)
 {
     Size = Alignment =
         typeContext.Context.TargetPlatform == TargetPlatform.X86
         ? 4
         : 8;
     AddFlags(TypeFlags.PointerDependent);
 }
Exemplo n.º 15
0
 /// <summary>
 /// Constructs a new convert value.
 /// </summary>
 /// <param name="context">The parent IR context.</param>
 /// <param name="basicBlock">The parent basic block.</param>
 /// <param name="value">The value to convert.</param>
 /// <param name="targetAddressSpace">The target address space.</param>
 internal AddressSpaceCast(
     IRContext context,
     BasicBlock basicBlock,
     ValueReference value,
     MemoryAddressSpace targetAddressSpace)
     : base(
         basicBlock,
         value,
         ComputeType(context, value.Type, targetAddressSpace))
 {
     Debug.Assert(
         value.Type.IsViewOrPointerType &&
         (value.Type as AddressSpaceType).AddressSpace != targetAddressSpace,
         "Invalid target address space");
 }
Exemplo n.º 16
0
        /// <summary>
        /// Creates an address-space cast.
        /// </summary>
        /// <param name="location">The current location.</param>
        /// <param name="node">The operand.</param>
        /// <param name="targetAddressSpace">The target address space.</param>
        /// <returns>A node that represents the cast operation.</returns>
        public ValueReference CreateAddressSpaceCast(
            Location location,
            Value node,
            MemoryAddressSpace targetAddressSpace)
        {
            var type = node.Type.As <AddressSpaceType>(location);

            var sourceAddressSpace = type.AddressSpace;

            return(sourceAddressSpace == targetAddressSpace
                ? (ValueReference)node
                : Append(new AddressSpaceCast(
                             GetInitializer(location),
                             node,
                             targetAddressSpace)));
        }
Exemplo n.º 17
0
        public static Type GetManagedType(this MemoryAddressSpace space)
        {
            switch (space)
            {
            case MemoryAddressSpace.Global:
                return(typeof(AddressSpaces.Global));

            case MemoryAddressSpace.Local:
                return(typeof(AddressSpaces.Local));

            case MemoryAddressSpace.Shared:
                return(typeof(AddressSpaces.Shared));

            default:
                return(typeof(AddressSpaces.Generic));
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Creates an address-space cast conversion.
        /// </summary>
        /// <param name="sourceRegister">The source register.</param>
        /// <param name="targetRegister">The target register.</param>
        /// <param name="sourceAddressSpace">The source address space.</param>
        /// <param name="targetAddressSpace">The target address space.</param>
        private void CreateAddressSpaceCast(
            PrimitiveRegister sourceRegister,
            HardwareRegister targetRegister,
            MemoryAddressSpace sourceAddressSpace,
            MemoryAddressSpace targetAddressSpace)
        {
            var toGeneric                   = targetAddressSpace == MemoryAddressSpace.Generic;
            var addressSpaceOperation       = PTXInstructions.GetAddressSpaceCast(toGeneric);
            var addressSpaceOperationSuffix =
                PTXInstructions.GetAddressSpaceCastSuffix(Backend);

            using var command = BeginCommand(addressSpaceOperation);
            command.AppendAddressSpace(
                toGeneric ? sourceAddressSpace : targetAddressSpace);
            command.AppendSuffix(addressSpaceOperationSuffix);
            command.AppendArgument(targetRegister);
            command.AppendArgument(sourceRegister);
        }
Exemplo n.º 19
0
 /// <summary>
 /// Constructs a new pointer type.
 /// </summary>
 /// <param name="typeContext">The parent type context.</param>
 /// <param name="elementType">The element type.</param>
 /// <param name="addressSpace">The associated address space.</param>
 internal PointerType(
     IRTypeContext typeContext,
     TypeNode elementType,
     MemoryAddressSpace addressSpace)
     : base(typeContext, elementType, addressSpace)
 {
     if (typeContext.TargetPlatform == TargetPlatform.X86)
     {
         Size           = Alignment = 4;
         BasicValueType = BasicValueType.Int32;
     }
     else
     {
         Size           = Alignment = 8;
         BasicValueType = BasicValueType.Int64;
     }
     AddFlags(TypeFlags.PointerDependent);
 }
Exemplo n.º 20
0
        /// <summary>
        /// Tries to specialize a view or a pointer address space.
        /// </summary>
        /// <param name="type">The pointer or view type.</param>
        /// <param name="addressSpace">The target address space.</param>
        /// <param name="specializedType">The specialized type.</param>
        /// <returns>True, iff the type could be specialized.</returns>
        public bool TrySpecializeAddressSpaceType(
            TypeNode type,
            MemoryAddressSpace addressSpace,
            out TypeNode specializedType)
        {
            Debug.Assert(type != null, "Invalid type");

            if (type is AddressSpaceType addressSpaceType)
            {
                specializedType = SpecializeAddressSpaceType(
                    addressSpaceType,
                    addressSpace);
            }
            else
            {
                specializedType = null;
            }
            return(specializedType != null);
        }
Exemplo n.º 21
0
 private static AddressSpaceType ComputeType(
     IRContext context,
     TypeNode sourceType,
     MemoryAddressSpace targetAddressSpace)
 {
     if (sourceType is ViewType viewType)
     {
         return(context.CreateViewType(
                    viewType.ElementType,
                    targetAddressSpace));
     }
     else
     {
         var pointerType = sourceType as PointerType;
         return(context.CreatePointerType(
                    pointerType.ElementType,
                    targetAddressSpace));
     }
 }
Exemplo n.º 22
0
            /// <summary>
            /// Appends the given address space
            /// </summary>
            /// <param name="addressSpace">The address space.</param>
            public void AppendAddressSpace(MemoryAddressSpace addressSpace)
            {
                switch (addressSpace)
                {
                case MemoryAddressSpace.Global:
                    stringBuilder.Append(".global");
                    break;

                case MemoryAddressSpace.Shared:
                    stringBuilder.Append(".shared");
                    break;

                case MemoryAddressSpace.Local:
                    stringBuilder.Append(".local");
                    break;

                default:
                    break;
                }
            }
Exemplo n.º 23
0
        /// <summary>
        /// Specializes the address space of the given <seeVoidType cref="AddressSpaceType"/>.
        /// </summary>
        /// <param name="addressSpaceType">The source type.</param>
        /// <param name="addressSpace">The new address space.</param>
        /// <returns>The created specialzized <see cref="AddressSpaceType"/>.</returns>
        public AddressSpaceType SpecializeAddressSpaceType(
            AddressSpaceType addressSpaceType,
            MemoryAddressSpace addressSpace)
        {
            Debug.Assert(addressSpaceType != null, "Invalid address space type");

            if (addressSpaceType is PointerType pointerType)
            {
                return(CreatePointerType(
                           pointerType.ElementType,
                           addressSpace));
            }
            else
            {
                var viewType = addressSpaceType as ViewType;
                return(CreateViewType(
                           viewType.ElementType,
                           addressSpace));
            }
        }
Exemplo n.º 24
0
        /// <summary>
        /// Creates a local allocation.
        /// </summary>
        /// <param name="location">The current location.</param>
        /// <param name="type">The type of the allocation.</param>
        /// <param name="addressSpace">The target address space.</param>
        /// <param name="arrayLength">
        /// The array length (number of elements to allocate or undefined).
        /// </param>
        /// <returns>A node that represents the alloca operation.</returns>
        internal ValueReference CreateAlloca(
            Location location,
            TypeNode type,
            MemoryAddressSpace addressSpace,
            Value arrayLength)
        {
            location.Assert(
                addressSpace == MemoryAddressSpace.Local ||
                addressSpace == MemoryAddressSpace.Shared);

            return(arrayLength is PrimitiveValue primitiveValue &&
                   primitiveValue.Int32Value == 0
                ? CreateNull(
                       location,
                       CreatePointerType(type, addressSpace))
                : Append(new Alloca(
                             GetInitializer(location),
                             arrayLength,
                             type,
                             addressSpace)));
        }
Exemplo n.º 25
0
        /// <summary>
        /// Constructs a new alloca node.
        /// </summary>
        /// <param name="context">The parent IR context.</param>
        /// <param name="basicBlock">The parent basic block.</param>
        /// <param name="arrayLength">The array length to allocate.</param>
        /// <param name="allocaType">The allocation type.</param>
        /// <param name="addressSpace">The target address space.</param>
        internal Alloca(
            IRContext context,
            BasicBlock basicBlock,
            ValueReference arrayLength,
            TypeNode allocaType,
            MemoryAddressSpace addressSpace)
            : base(
                basicBlock,
                ImmutableArray.Create(arrayLength),
                ComputeType(context, allocaType, addressSpace))
        {
            Debug.Assert(
                addressSpace == MemoryAddressSpace.Local ||
                addressSpace == MemoryAddressSpace.Shared,
                "Invalid alloca address space");

            AllocaType   = allocaType;
            AddressSpace = addressSpace;

            InvalidateType();
        }
Exemplo n.º 26
0
        /// <summary>
        /// Creates an address-space cast.
        /// </summary>
        /// <param name="location">The current location.</param>
        /// <param name="node">The operand.</param>
        /// <param name="targetAddressSpace">The target address space.</param>
        /// <returns>A node that represents the cast operation.</returns>
        public ValueReference CreateAddressSpaceCast(
            Location location,
            Value node,
            MemoryAddressSpace targetAddressSpace)
        {
            var type = node.Type.As <AddressSpaceType>(location);

            // Simplify chained casts
            if (node is AddressSpaceCast cast)
            {
                node = cast.Value;
                type = cast.SourceType;
            }

            var sourceAddressSpace = type.AddressSpace;

            return(sourceAddressSpace == targetAddressSpace
                ? (ValueReference)node
                : Append(new AddressSpaceCast(
                             GetInitializer(location),
                             node,
                             targetAddressSpace)));
        }
Exemplo n.º 27
0
        /// <summary>
        /// Creates a new generic view type that relies on an n-dimension index.
        /// </summary>
        /// <param name="elementType">The element type.</param>
        /// <param name="indexType">The index type.</param>
        /// <param name="addressSpace">The address space.</param>
        /// <returns>The created view type.</returns>
        public StructureType CreateGenericViewType(
            TypeNode elementType,
            StructureType indexType,
            MemoryAddressSpace addressSpace)
        {
            // Try to resolve the managed type
            Type managedType = null;

            if (elementType.TryResolveManagedType(out Type managedElementType) &&
                indexType.TryResolveManagedType(out Type managedIndexType))
            {
                managedType = GenericArrayViewType.MakeGenericType(managedElementType, managedIndexType);
            }

            // Create the actual type
            var viewType = CreateViewType(elementType, addressSpace);

            return(CreateStructureType(
                       StructureType.Root,
                       ImmutableArray.Create <TypeNode>(viewType, indexType),
                       ImmutableArray <string> .Empty,
                       managedType));
        }
Exemplo n.º 28
0
        /// <summary>
        /// Creates an address-space cast.
        /// </summary>
        /// <param name="node">The operand.</param>
        /// <param name="targetAddressSpace">The target address space.</param>
        /// <returns>A node that represents the cast operation.</returns>
        public ValueReference CreateAddressSpaceCast(
            Value node,
            MemoryAddressSpace targetAddressSpace)
        {
            Debug.Assert(node != null, "Invalid node");

            var type = node.Type as AddressSpaceType;

            Debug.Assert(type != null, "Invalid address space type");

            var sourceAddressSpace = type.AddressSpace;

            if (sourceAddressSpace == targetAddressSpace)
            {
                return(node);
            }

            return(Append(new AddressSpaceCast(
                              Context,
                              BasicBlock,
                              node,
                              targetAddressSpace)));
        }
Exemplo n.º 29
0
 /// <summary>
 /// Allocates a pointer type.
 /// </summary>
 /// <param name="elementType">The pointer element type to allocate.</param>
 /// <param name="addressSpace">The associated address space.</param>
 /// <returns>The allocated variable.</returns>
 public PointerVariable AllocatePointerType(
     TypeNode elementType,
     MemoryAddressSpace addressSpace) =>
 new PointerVariable(idCounter++, elementType, addressSpace);
Exemplo n.º 30
0
 /// <summary>
 /// Creates a view type.
 /// </summary>
 /// <param name="elementType">The view element type.</param>
 /// <param name="addressSpace">The address space.</param>
 /// <returns>The created view type.</returns>
 public ViewType CreateViewType(
     TypeNode elementType,
     MemoryAddressSpace addressSpace) =>
 TypeContext.CreateViewType(elementType, addressSpace);