Files
archived-llvm-mirror/include/llvm/Support/OptimizedStructLayout.h
Nicolás Alvarez 0bad578cf3 [docs] Fix doxygen comments wrongly attached to the llvm namespace
Looking at the Doxygen-generated documentation for the llvm namespace
currently shows all sorts of random comments from different parts of the
codebase. These are mostly caused by:

- File doc comments that aren't marked with \file, so they're attached to
  the next declaration, which is usually "namespace llvm {".
- Class doc comments placed before the namespace rather than before the
  class.
- Code comments before the namespace that (in my opinion) shouldn't be
  extracted by doxygen at all.

This commit fixes these comments. The generated doxygen documentation now
has proper docs for several classes and files, and the docs for the llvm
and llvm::detail namespaces are now empty.

Reviewed By: thakis, mizvekov

Differential Revision: https://reviews.llvm.org/D96736
2021-04-07 01:20:18 +02:00

144 lines
5.9 KiB
C++

//===-- 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