/// <summary> /// Computes a linear array address. /// </summary> /// <param name="location">The current location.</param> /// <param name="arrayIndex">The array index.</param> /// <param name="arrayExtent">The array extent.</param> /// <param name="arrayExtentOffset">The extent offset.</param> /// <returns>The linear array address.</returns> internal ValueReference ComputeArrayAddress( Location location, Value arrayIndex, Value arrayExtent, int arrayExtentOffset) { int dimensions = StructureType.GetNumFields(arrayExtent.Type); Value linearIndex = CreateGetField( location, arrayIndex, new FieldSpan(dimensions - 1)); for (int i = dimensions - 2; i >= 0; --i) { var extent = CreateGetField( location, arrayExtent, new FieldSpan(i + arrayExtentOffset)); var index = CreateGetField( location, arrayIndex, new FieldSpan(i)); linearIndex = CreateArithmetic( location, linearIndex, extent, index, TernaryArithmeticKind.MultiplyAdd); } return(linearIndex); }
/// <summary> /// Computes a linear array length based on an array extent. /// </summary> /// <param name="location">The current location.</param> /// <param name="arrayExtent">The array extent.</param> /// <returns>The linear array length.</returns> internal ValueReference ComputeArrayLength( Location location, Value arrayExtent) { // Compute total number of elements var size = CreateGetField( location, arrayExtent, new FieldSpan(0)); int dimensions = StructureType.GetNumFields(arrayExtent.Type); for (int i = 1; i < dimensions; ++i) { var element = CreateGetField( location, arrayExtent, new FieldSpan(i)); size = CreateArithmetic( location, size, element, BinaryArithmeticKind.Mul); } return(size); }
/// <summary> /// Lowers array extent values. /// </summary> private static void Lower( RewriterContext context, TypeLowering <ArrayType> typeLowering, GetArrayExtent value) { var builder = context.Builder; // Create new extent structure based on all dimension entries int dimensions = StructureType.GetNumFields(typeLowering[value]); var instance = builder.CreateDynamicStructure(value.Location, dimensions); // Insert all dimension values for (int i = 0; i < dimensions; ++i) { instance.Add(builder.CreateGetField( value.Location, value.ObjectValue, new FieldSpan(i + ArrayTypeLowering.DimensionOffset))); } var newStructure = instance.Seal(); context.ReplaceAndRemove(value, newStructure); }