Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===-- OptimizedStructLayout.h - Struct layout algorithm ---------*- C++ -*-=//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file provides an interface for laying out a sequence of fields
11
/// as a struct in a way that attempts to minimizes the total space
12
/// requirements of the struct while still satisfying the layout
13
/// requirements of the individual fields.  The resulting layout may be
14
/// substantially more compact than simply laying out the fields in their
15
/// original order.
16
///
17
/// Fields may be pre-assigned fixed offsets.  They may also be given sizes
18
/// that are not multiples of their alignments.  There is no currently no
19
/// way to describe that a field has interior padding that other fields may
20
/// be allocated into.
21
///
22
/// This algorithm does not claim to be "optimal" for several reasons:
23
///
24
/// - First, it does not guarantee that the result is minimal in size.
25
///   There is no known efficient algoorithm to achieve minimality for
26
///   unrestricted inputs.  Nonetheless, this algorithm
27
///
28
/// - Second, there are other ways that a struct layout could be optimized
29
///   besides space usage, such as locality.  This layout may have a mixed
30
///   impact on locality: less overall memory may be used, but adjacent
31
///   fields in the original array may be moved further from one another.
32
///
33
//===----------------------------------------------------------------------===//
34
 
35
#ifndef LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H
36
#define LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H
37
 
38
#include "llvm/Support/Alignment.h"
39
#include "llvm/ADT/ArrayRef.h"
40
#include <utility>
41
 
42
namespace llvm {
43
 
44
/// A field in a structure.
45
struct OptimizedStructLayoutField {
46
  /// A special value for Offset indicating that the field can be moved
47
  /// anywhere.
48
  static constexpr uint64_t FlexibleOffset = ~(uint64_t)0;
49
 
50
  OptimizedStructLayoutField(const void *Id, uint64_t Size, Align Alignment,
51
                             uint64_t FixedOffset = FlexibleOffset)
52
      : Offset(FixedOffset), Size(Size), Id(Id), Alignment(Alignment) {
53
    assert(Size > 0 && "adding an empty field to the layout");
54
  }
55
 
56
  /// The offset of this field in the final layout.  If this is
57
  /// initialized to FlexibleOffset, layout will overwrite it with
58
  /// the assigned offset of the field.
59
  uint64_t Offset;
60
 
61
  /// The required size of this field in bytes.  Does not have to be
62
  /// a multiple of Alignment.  Must be non-zero.
63
  uint64_t Size;
64
 
65
  /// A opaque value which uniquely identifies this field.
66
  const void *Id;
67
 
68
  /// Private scratch space for the algorithm.  The implementation
69
  /// must treat this as uninitialized memory on entry.
70
  void *Scratch;
71
 
72
  /// The required alignment of this field.
73
  Align Alignment;
74
 
75
  /// Return true if this field has been assigned a fixed offset.
76
  /// After layout, this will be true of all the fields.
77
  bool hasFixedOffset() const {
78
    return (Offset != FlexibleOffset);
79
  }
80
 
81
  /// Given that this field has a fixed offset, return the offset
82
  /// of the first byte following it.
83
  uint64_t getEndOffset() const {
84
    assert(hasFixedOffset());
85
    return Offset + Size;
86
  }
87
};
88
 
89
/// Compute a layout for a struct containing the given fields, making a
90
/// best-effort attempt to minimize the amount of space required.
91
///
92
/// Two features are supported which require a more careful solution
93
/// than the well-known "sort by decreasing alignment" solution:
94
///
95
/// - Fields may be assigned a fixed offset in the layout.  If there are
96
///   gaps among the fixed-offset fields, the algorithm may attempt
97
///   to allocate flexible-offset fields into those gaps.  If that's
98
///   undesirable, the caller should "block out" those gaps by e.g.
99
///   just creating a single fixed-offset field that represents the
100
///   entire "header".
101
///
102
/// - The size of a field is not required to be a multiple of, or even
103
///   greater than, the field's required alignment.  The only constraint
104
///   on fields is that they must not be zero-sized.
105
///
106
/// To simplify the implementation, any fixed-offset fields in the
107
/// layout must appear at the start of the field array, and they must
108
/// be ordered by increasing offset.
109
///
110
/// The algorithm will produce a guaranteed-minimal layout with no
111
/// interior padding in the following "C-style" case:
112
///
113
/// - every field's size is a multiple of its required alignment and
114
/// - either no fields have initially fixed offsets, or the fixed-offset
115
///   fields have no interior padding and end at an offset that is at
116
///   least as aligned as all the flexible-offset fields.
117
///
118
/// Otherwise, while the algorithm will make a best-effort attempt to
119
/// avoid padding, it cannot guarantee a minimal layout, as there is
120
/// no known efficient algorithm for doing so.
121
///
122
/// The layout produced by this algorithm may not be stable across LLVM
123
/// releases.  Do not use this anywhere where ABI stability is required.
124
///
125
/// Flexible-offset fields with the same size and alignment will be ordered
126
/// the same way they were in the initial array.  Otherwise the current
127
/// algorithm makes no effort to preserve the initial order of
128
/// flexible-offset fields.
129
///
130
/// On return, all fields will have been assigned a fixed offset, and the
131
/// array will be sorted in order of ascending offsets.  Note that this
132
/// means that the fixed-offset fields may no longer form a strict prefix
133
/// if there's any padding before they end.
134
///
135
/// The return value is the total size of the struct and its required
136
/// alignment.  Note that the total size is not rounded up to a multiple
137
/// of the required alignment; clients which require this can do so easily.
138
std::pair<uint64_t, Align> performOptimizedStructLayout(
139
                        MutableArrayRef<OptimizedStructLayoutField> Fields);
140
 
141
} // namespace llvm
142
 
143
#endif