/// <summary cref="IValueVisitor.Visit(AlignViewTo)"/> public void Visit(AlignViewTo value) => throw new InvalidCodeGenerationException();
/// <summary> /// Lowers an align-view-to operation. /// </summary> private static void Lower( RewriterContext context, TypeLowering <ViewType> typeLowering, AlignViewTo value) { var builder = context.Builder; var location = value.Location; // Extract basic view information from the converted structure var pointer = builder.CreateGetField( location, value.View, new FieldSpan(0)); var length = builder.CreateGetField( location, value.View, new FieldSpan(1)); // Create IR code that represents the required operations to create aligned // views (see ArrayView.AlignToInternal for more information). var viewType = typeLowering[value].As <ViewType>(value); // long elementsToSkip = Min( // AlignmentOffset(ptr, alignmentInBytes) / elementSize, // Length); var elementsToSkip = builder.CreateArithmetic( location, builder.CreateAlignmentOffset( location, builder.CreatePointerAsIntCast( location, pointer, BasicValueType.Int64), value.AlignmentInBytes), builder.CreateSizeOf(location, viewType.ElementType), BinaryArithmeticKind.Div); elementsToSkip = builder.CreateArithmetic( location, elementsToSkip, length, BinaryArithmeticKind.Min); // Build the final result structure instance var resultBuilder = builder.CreateDynamicStructure(location); // Create the prefix view that starts at the original pointer offset and // includes elementsToSkip many elements. { resultBuilder.Add(pointer); resultBuilder.Add(elementsToSkip); } // Create the main view that starts at the original pointer offset + // elementsToSkip and has a length of remainingLength { var mainPointer = builder.CreateLoadElementAddress( location, pointer, elementsToSkip); resultBuilder.Add(mainPointer); var remainingLength = builder.CreateArithmetic( location, length, elementsToSkip, BinaryArithmeticKind.Sub); resultBuilder.Add(remainingLength); } var result = resultBuilder.Seal(); context.ReplaceAndRemove(value, result); }