- //===-- OptimizedStructLayout.h - Struct layout algorithm ---------*- C++ -*-=// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- /// 
- /// \file 
- /// This file provides an interface for laying out a sequence of fields 
- /// as a struct in a way that attempts to minimizes the total space 
- /// requirements of the struct while still satisfying the layout 
- /// requirements of the individual fields.  The resulting layout may be 
- /// substantially more compact than simply laying out the fields in their 
- /// original order. 
- /// 
- /// Fields may be pre-assigned fixed offsets.  They may also be given sizes 
- /// that are not multiples of their alignments.  There is no currently no 
- /// way to describe that a field has interior padding that other fields may 
- /// be allocated into. 
- /// 
- /// This algorithm does not claim to be "optimal" for several reasons: 
- /// 
- /// - First, it does not guarantee that the result is minimal in size. 
- ///   There is no known efficient algoorithm to achieve minimality for 
- ///   unrestricted inputs.  Nonetheless, this algorithm 
- /// 
- /// - Second, there are other ways that a struct layout could be optimized 
- ///   besides space usage, such as locality.  This layout may have a mixed 
- ///   impact on locality: less overall memory may be used, but adjacent 
- ///   fields in the original array may be moved further from one another. 
- /// 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H 
- #define LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H 
-   
- #include "llvm/Support/Alignment.h" 
- #include "llvm/ADT/ArrayRef.h" 
- #include <utility> 
-   
- namespace llvm { 
-   
- /// A field in a structure. 
- struct OptimizedStructLayoutField { 
-   /// A special value for Offset indicating that the field can be moved 
-   /// anywhere. 
-   static constexpr uint64_t FlexibleOffset = ~(uint64_t)0; 
-   
-   OptimizedStructLayoutField(const void *Id, uint64_t Size, Align Alignment, 
-                              uint64_t FixedOffset = FlexibleOffset) 
-       : Offset(FixedOffset), Size(Size), Id(Id), Alignment(Alignment) { 
-     assert(Size > 0 && "adding an empty field to the layout"); 
-   } 
-   
-   /// The offset of this field in the final layout.  If this is 
-   /// initialized to FlexibleOffset, layout will overwrite it with 
-   /// the assigned offset of the field. 
-   uint64_t Offset; 
-   
-   /// The required size of this field in bytes.  Does not have to be 
-   /// a multiple of Alignment.  Must be non-zero. 
-   uint64_t Size; 
-   
-   /// A opaque value which uniquely identifies this field. 
-   const void *Id; 
-   
-   /// Private scratch space for the algorithm.  The implementation 
-   /// must treat this as uninitialized memory on entry. 
-   void *Scratch; 
-   
-   /// The required alignment of this field. 
-   Align Alignment; 
-   
-   /// Return true if this field has been assigned a fixed offset. 
-   /// After layout, this will be true of all the fields. 
-   bool hasFixedOffset() const { 
-     return (Offset != FlexibleOffset); 
-   } 
-   
-   /// Given that this field has a fixed offset, return the offset 
-   /// of the first byte following it. 
-   uint64_t getEndOffset() const { 
-     assert(hasFixedOffset()); 
-     return Offset + Size; 
-   } 
- }; 
-   
- /// Compute a layout for a struct containing the given fields, making a 
- /// best-effort attempt to minimize the amount of space required. 
- /// 
- /// Two features are supported which require a more careful solution 
- /// than the well-known "sort by decreasing alignment" solution: 
- /// 
- /// - Fields may be assigned a fixed offset in the layout.  If there are 
- ///   gaps among the fixed-offset fields, the algorithm may attempt 
- ///   to allocate flexible-offset fields into those gaps.  If that's 
- ///   undesirable, the caller should "block out" those gaps by e.g. 
- ///   just creating a single fixed-offset field that represents the 
- ///   entire "header". 
- /// 
- /// - The size of a field is not required to be a multiple of, or even 
- ///   greater than, the field's required alignment.  The only constraint 
- ///   on fields is that they must not be zero-sized. 
- /// 
- /// To simplify the implementation, any fixed-offset fields in the 
- /// layout must appear at the start of the field array, and they must 
- /// be ordered by increasing offset. 
- /// 
- /// The algorithm will produce a guaranteed-minimal layout with no 
- /// interior padding in the following "C-style" case: 
- /// 
- /// - every field's size is a multiple of its required alignment and 
- /// - either no fields have initially fixed offsets, or the fixed-offset 
- ///   fields have no interior padding and end at an offset that is at 
- ///   least as aligned as all the flexible-offset fields. 
- /// 
- /// Otherwise, while the algorithm will make a best-effort attempt to 
- /// avoid padding, it cannot guarantee a minimal layout, as there is 
- /// no known efficient algorithm for doing so. 
- /// 
- /// The layout produced by this algorithm may not be stable across LLVM 
- /// releases.  Do not use this anywhere where ABI stability is required. 
- /// 
- /// Flexible-offset fields with the same size and alignment will be ordered 
- /// the same way they were in the initial array.  Otherwise the current 
- /// algorithm makes no effort to preserve the initial order of 
- /// flexible-offset fields. 
- /// 
- /// On return, all fields will have been assigned a fixed offset, and the 
- /// array will be sorted in order of ascending offsets.  Note that this 
- /// means that the fixed-offset fields may no longer form a strict prefix 
- /// if there's any padding before they end. 
- /// 
- /// The return value is the total size of the struct and its required 
- /// alignment.  Note that the total size is not rounded up to a multiple 
- /// of the required alignment; clients which require this can do so easily. 
- std::pair<uint64_t, Align> performOptimizedStructLayout( 
-                         MutableArrayRef<OptimizedStructLayoutField> Fields); 
-   
- } // namespace llvm 
-   
- #endif 
-