1c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===- llvm/DataLayout.h - Data size & alignment info -----------*- C++ -*-===//
2c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
3c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//                     The LLVM Compiler Infrastructure
4c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
5c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file is distributed under the University of Illinois Open Source
6c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// License. See LICENSE.TXT for details.
7c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
8c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===//
9c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
10c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file defines layout properties related to datatype size/offset/alignment
11c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// information.  It uses lazy annotations to cache information about how
12c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// structure types are laid out and used.
13c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
14c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This structure should be created once, filled in if the defaults are not
15c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// correct and then passed around by const&.  None of the members functions
16c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// require modification to the object.
17c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
18c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===//
19c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
20c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#ifndef LLVM_IR_DATALAYOUT_H
21c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#define LLVM_IR_DATALAYOUT_H
22c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
23c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/ArrayRef.h"
24c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/STLExtras.h"
25c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/SmallVector.h"
26c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/StringRef.h"
27c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/DerivedTypes.h"
28c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/Type.h"
29c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Pass.h"
30c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/Casting.h"
31c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/ErrorHandling.h"
32c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/MathExtras.h"
33c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cassert>
34c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cstdint>
35c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <string>
36c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
37c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This needs to be outside of the namespace, to avoid conflict with llvm-c
38c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// decl.
39c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotusing LLVMTargetDataRef = struct LLVMOpaqueTargetData *;
40c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
41c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotnamespace llvm {
42c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
43c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass GlobalVariable;
44c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass LLVMContext;
45c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass Module;
46c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass StructLayout;
47c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass Triple;
48c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass Value;
49c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
50c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Enum used to categorize the alignment types stored by LayoutAlignElem
51c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotenum AlignTypeEnum {
52c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  INVALID_ALIGN = 0,
53c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  INTEGER_ALIGN = 'i',
54c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  VECTOR_ALIGN = 'v',
55c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  FLOAT_ALIGN = 'f',
56c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  AGGREGATE_ALIGN = 'a'
57c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
58c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
59c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// FIXME: Currently the DataLayout string carries a "preferred alignment"
60c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// for types. As the DataLayout is module/global, this should likely be
61c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// sunk down to an FTTI element that is queried rather than a global
62c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// preference.
63c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
64c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \brief Layout alignment element.
65c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot///
66c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Stores the alignment data associated with a given alignment type (integer,
67c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// vector, float) and type bit width.
68c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot///
69c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \note The unusual order of elements in the structure attempts to reduce
70c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// padding and make the structure slightly more cache friendly.
71c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotstruct LayoutAlignElem {
72c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Alignment type from \c AlignTypeEnum
73c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned AlignType : 8;
74c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned TypeBitWidth : 24;
75c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned ABIAlign : 16;
76c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned PrefAlign : 16;
77c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
78c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
79c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                             unsigned pref_align, uint32_t bit_width);
80c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
81c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool operator==(const LayoutAlignElem &rhs) const;
82c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
83c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
84c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \brief Layout pointer alignment element.
85c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot///
86c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Stores the alignment data associated with a given pointer and address space.
87c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot///
88c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \note The unusual order of elements in the structure attempts to reduce
89c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// padding and make the structure slightly more cache friendly.
90c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotstruct PointerAlignElem {
91c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned ABIAlign;
92c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned PrefAlign;
93c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint32_t TypeByteWidth;
94c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint32_t AddressSpace;
95c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
96c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Initializer
97c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
98c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                              unsigned PrefAlign, uint32_t TypeByteWidth);
99c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool operator==(const PointerAlignElem &rhs) const;
101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \brief A parsed version of the target data layout string in and methods for
104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// querying it.
105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot///
106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// The target data layout string is specified *by the target* - a frontend
107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// generating LLVM IR is required to generate the right target data for the
108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// target being codegen'd to.
109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass DataLayout {
110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate:
111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Defaults to false.
112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool BigEndian;
113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned AllocaAddrSpace;
115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned StackNaturalAlign;
116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  enum ManglingModeT {
118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    MM_None,
119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    MM_ELF,
120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    MM_MachO,
121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    MM_WinCOFF,
122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    MM_WinCOFFX86,
123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    MM_Mips
124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  };
125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ManglingModeT ManglingMode;
126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  SmallVector<unsigned char, 8> LegalIntWidths;
128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Primitive type alignment data. This is sorted by type and bit
130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// width during construction.
131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using AlignmentsTy = SmallVector<LayoutAlignElem, 16>;
132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  AlignmentsTy Alignments;
133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  AlignmentsTy::const_iterator
135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  findAlignmentLowerBound(AlignTypeEnum AlignType, uint32_t BitWidth) const {
136c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return const_cast<DataLayout *>(this)->findAlignmentLowerBound(AlignType,
137c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                                                                   BitWidth);
138c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
139c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
140c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  AlignmentsTy::iterator
141c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  findAlignmentLowerBound(AlignTypeEnum AlignType, uint32_t BitWidth);
142c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
143c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief The string representation used to create this DataLayout
144c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  std::string StringRepresentation;
145c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
146c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using PointersTy = SmallVector<PointerAlignElem, 8>;
147c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  PointersTy Pointers;
148c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
149c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  PointersTy::const_iterator
150c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  findPointerLowerBound(uint32_t AddressSpace) const {
151c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return const_cast<DataLayout *>(this)->findPointerLowerBound(AddressSpace);
152c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
153c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
154c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  PointersTy::iterator findPointerLowerBound(uint32_t AddressSpace);
155c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
156c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // The StructType -> StructLayout map.
157c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  mutable void *LayoutMap = nullptr;
158c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
159c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Pointers in these address spaces are non-integral, and don't have a
160c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// well-defined bitwise representation.
161c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  SmallVector<unsigned, 8> NonIntegralAddressSpaces;
162c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
163c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void setAlignment(AlignTypeEnum align_type, unsigned abi_align,
164c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                    unsigned pref_align, uint32_t bit_width);
165c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
166c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                            bool ABIAlign, Type *Ty) const;
167c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
168c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                           unsigned PrefAlign, uint32_t TypeByteWidth);
169c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
170c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Internal helper method that returns requested alignment for type.
171c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getAlignment(Type *Ty, bool abi_or_pref) const;
172c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
173c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Parses a target data specification string. Assert if the string is
174c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// malformed.
175c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void parseSpecifier(StringRef LayoutDescription);
176c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
177c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // Free all internal data structures.
178c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void clear();
179c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
180c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
181c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Constructs a DataLayout from a specification string. See reset().
182c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit DataLayout(StringRef LayoutDescription) {
183c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    reset(LayoutDescription);
184c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
185c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
186c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Initialize target data from properties stored in the module.
187c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit DataLayout(const Module *M);
188c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
189c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  DataLayout(const DataLayout &DL) { *this = DL; }
190c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
191c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ~DataLayout(); // Not virtual, do not subclass this class
192c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
193c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  DataLayout &operator=(const DataLayout &DL) {
194c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    clear();
195c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    StringRepresentation = DL.StringRepresentation;
196c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BigEndian = DL.isBigEndian();
197c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    AllocaAddrSpace = DL.AllocaAddrSpace;
198c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    StackNaturalAlign = DL.StackNaturalAlign;
199c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    ManglingMode = DL.ManglingMode;
200c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    LegalIntWidths = DL.LegalIntWidths;
201c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Alignments = DL.Alignments;
202c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Pointers = DL.Pointers;
203c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    NonIntegralAddressSpaces = DL.NonIntegralAddressSpaces;
204c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return *this;
205c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
206c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
207c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool operator==(const DataLayout &Other) const;
208c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool operator!=(const DataLayout &Other) const { return !(*this == Other); }
209c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
210c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void init(const Module *M);
211c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
212c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Parse a data layout string (with fallback to default values).
213c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void reset(StringRef LayoutDescription);
214c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
215c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Layout endianness...
216c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool isLittleEndian() const { return !BigEndian; }
217c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool isBigEndian() const { return BigEndian; }
218c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
219c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the string representation of the DataLayout.
220c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
221c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This representation is in the same format accepted by the string
222c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// constructor above. This should not be used to compare two DataLayout as
223c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// different string can represent the same layout.
224c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const std::string &getStringRepresentation() const {
225c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return StringRepresentation;
226c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
227c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
228c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Test if the DataLayout was constructed from an empty string.
229c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool isDefault() const { return StringRepresentation.empty(); }
230c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
231c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns true if the specified type is known to be a native integer
232c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// type supported by the CPU.
233c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
234c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// For example, i64 is not native on most 32-bit CPUs and i37 is not native
235c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// on any known one. This returns false if the integer width is not legal.
236c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
237c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// The width is specified in bits.
238c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool isLegalInteger(uint64_t Width) const {
239c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    for (unsigned LegalIntWidth : LegalIntWidths)
240c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (LegalIntWidth == Width)
241c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return true;
242c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return false;
243c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
244c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
245c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool isIllegalInteger(uint64_t Width) const { return !isLegalInteger(Width); }
246c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
247c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Returns true if the given alignment exceeds the natural stack alignment.
248c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool exceedsNaturalStackAlignment(unsigned Align) const {
249c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return (StackNaturalAlign != 0) && (Align > StackNaturalAlign);
250c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
251c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
252c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getStackAlignment() const { return StackNaturalAlign; }
253c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; }
254c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
255c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool hasMicrosoftFastStdCallMangling() const {
256c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return ManglingMode == MM_WinCOFFX86;
257c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
258c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
259c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; }
260c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
261c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  StringRef getLinkerPrivateGlobalPrefix() const {
262c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (ManglingMode == MM_MachO)
263c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return "l";
264c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return "";
265c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
266c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
267c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  char getGlobalPrefix() const {
268c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    switch (ManglingMode) {
269c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_None:
270c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_ELF:
271c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_Mips:
272c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_WinCOFF:
273c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return '\0';
274c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_MachO:
275c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_WinCOFFX86:
276c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return '_';
277c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
278c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    llvm_unreachable("invalid mangling mode");
279c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
280c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
281c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  StringRef getPrivateGlobalPrefix() const {
282c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    switch (ManglingMode) {
283c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_None:
284c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return "";
285c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_ELF:
286c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_WinCOFF:
287c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return ".L";
288c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_Mips:
289c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return "$";
290c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_MachO:
291c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    case MM_WinCOFFX86:
292c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return "L";
293c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
294c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    llvm_unreachable("invalid mangling mode");
295c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
296c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
297c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static const char *getManglingComponent(const Triple &T);
298c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
299c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns true if the specified type fits in a native integer type
300c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// supported by the CPU.
301c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
302c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// For example, if the CPU only supports i32 as a native integer type, then
303c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// i27 fits in a legal integer type but i45 does not.
304c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool fitsInLegalInteger(unsigned Width) const {
305c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    for (unsigned LegalIntWidth : LegalIntWidths)
306c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (Width <= LegalIntWidth)
307c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return true;
308c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return false;
309c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
310c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
311c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Layout pointer alignment
312c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// FIXME: The defaults need to be removed once all of
313c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// the backends/clients are updated.
314c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPointerABIAlignment(unsigned AS = 0) const;
315c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
316c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Return target's alignment for stack-based pointers
317c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// FIXME: The defaults need to be removed once all of
318c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// the backends/clients are updated.
319c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPointerPrefAlignment(unsigned AS = 0) const;
320c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
321c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Layout pointer size
322c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// FIXME: The defaults need to be removed once all of
323c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// the backends/clients are updated.
324c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPointerSize(unsigned AS = 0) const;
325c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
326c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Return the address spaces containing non-integral pointers.  Pointers in
327c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// this address space don't have a well-defined bitwise representation.
328c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ArrayRef<unsigned> getNonIntegralAddressSpaces() const {
329c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return NonIntegralAddressSpaces;
330c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
331c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
332c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool isNonIntegralPointerType(PointerType *PT) const {
333c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    ArrayRef<unsigned> NonIntegralSpaces = getNonIntegralAddressSpaces();
334c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return find(NonIntegralSpaces, PT->getAddressSpace()) !=
335c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot           NonIntegralSpaces.end();
336c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
337c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
338c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool isNonIntegralPointerType(Type *Ty) const {
339c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    auto *PTy = dyn_cast<PointerType>(Ty);
340c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return PTy && isNonIntegralPointerType(PTy);
341c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
342c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
343c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Layout pointer size, in bits
344c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// FIXME: The defaults need to be removed once all of
345c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// the backends/clients are updated.
346c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPointerSizeInBits(unsigned AS = 0) const {
347c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return getPointerSize(AS) * 8;
348c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
349c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
350c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Layout pointer size, in bits, based on the type.  If this function is
351c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// called with a pointer type, then the type size of the pointer is returned.
352c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// If this function is called with a vector of pointers, then the type size
353c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// of the pointer is returned.  This should only be called with a pointer or
354c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// vector of pointers.
355c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPointerTypeSizeInBits(Type *) const;
356c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
357c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPointerTypeSize(Type *Ty) const {
358c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return getPointerTypeSizeInBits(Ty) / 8;
359c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
360c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
361c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Size examples:
362c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
363c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Type        SizeInBits  StoreSizeInBits  AllocSizeInBits[*]
364c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// ----        ----------  ---------------  ---------------
365c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  i1            1           8                8
366c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  i8            8           8                8
367c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  i19          19          24               32
368c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  i32          32          32               32
369c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  i100        100         104              128
370c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  i128        128         128              128
371c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  Float        32          32               32
372c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  Double       64          64               64
373c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///  X86_FP80     80          80               96
374c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
375c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// [*] The alloc size depends on the alignment, and thus on the target.
376c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///     These values are for x86-32 linux.
377c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
378c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the number of bits necessary to hold the specified type.
379c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
380c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// For example, returns 36 for i36 and 80 for x86_fp80. The type passed must
381c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// have a size (Type::isSized() must return true).
382c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getTypeSizeInBits(Type *Ty) const;
383c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
384c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the maximum number of bytes that may be overwritten by
385c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// storing the specified type.
386c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
387c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// For example, returns 5 for i36 and 10 for x86_fp80.
388c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getTypeStoreSize(Type *Ty) const {
389c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return (getTypeSizeInBits(Ty) + 7) / 8;
390c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
391c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
392c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the maximum number of bits that may be overwritten by
393c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// storing the specified type; always a multiple of 8.
394c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
395c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// For example, returns 40 for i36 and 80 for x86_fp80.
396c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getTypeStoreSizeInBits(Type *Ty) const {
397c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return 8 * getTypeStoreSize(Ty);
398c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
399c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
400c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the offset in bytes between successive objects of the
401c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// specified type, including alignment padding.
402c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
403c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is the amount that alloca reserves for this type. For example,
404c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// returns 12 or 16 for x86_fp80, depending on alignment.
405c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getTypeAllocSize(Type *Ty) const {
406c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Round up to the next alignment boundary.
407c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return alignTo(getTypeStoreSize(Ty), getABITypeAlignment(Ty));
408c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
409c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
410c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the offset in bits between successive objects of the
411c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// specified type, including alignment padding; always a multiple of 8.
412c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
413c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is the amount that alloca reserves for this type. For example,
414c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// returns 96 or 128 for x86_fp80, depending on alignment.
415c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getTypeAllocSizeInBits(Type *Ty) const {
416c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return 8 * getTypeAllocSize(Ty);
417c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
418c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
419c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the minimum ABI-required alignment for the specified type.
420c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getABITypeAlignment(Type *Ty) const;
421c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
422c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the minimum ABI-required alignment for an integer type of
423c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// the specified bitwidth.
424c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const;
425c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
426c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the preferred stack/global alignment for the specified
427c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// type.
428c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
429c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is always at least as good as the ABI alignment.
430c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPrefTypeAlignment(Type *Ty) const;
431c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
432c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the preferred alignment for the specified type, returned as
433c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// log2 of the value (a shift amount).
434c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPreferredTypeAlignmentShift(Type *Ty) const;
435c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
436c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns an integer type with size at least as big as that of a
437c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// pointer in the given address space.
438c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const;
439c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
440c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns an integer (vector of integer) type with size at least as
441c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// big as that of a pointer of the given pointer (vector of pointer) type.
442c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  Type *getIntPtrType(Type *) const;
443c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
444c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the smallest integer type with size at least as big as
445c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Width bits.
446c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const;
447c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
448c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the largest legal integer type, or null if none are set.
449c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  Type *getLargestLegalIntType(LLVMContext &C) const {
450c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned LargestSize = getLargestLegalIntTypeSizeInBits();
451c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return (LargestSize == 0) ? nullptr : Type::getIntNTy(C, LargestSize);
452c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
453c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
454c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the size of largest legal integer type size, or 0 if none
455c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// are set.
456c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getLargestLegalIntTypeSizeInBits() const;
457c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
458c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the offset from the beginning of the type for the specified
459c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// indices.
460c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
461c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Note that this takes the element type, not the pointer type.
462c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is used to implement getelementptr.
463c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  int64_t getIndexedOffsetInType(Type *ElemTy, ArrayRef<Value *> Indices) const;
464c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
465c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns a StructLayout object, indicating the alignment of the
466c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// struct, its size, and the offsets of its fields.
467c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
468c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Note that this information is lazily cached.
469c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const StructLayout *getStructLayout(StructType *Ty) const;
470c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
471c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the preferred alignment of the specified global.
472c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
473c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This includes an explicitly requested alignment (if the global has one).
474c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPreferredAlignment(const GlobalVariable *GV) const;
475c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
476c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Returns the preferred alignment of the specified global, returned
477c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// in log form.
478c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
479c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This includes an explicitly requested alignment (if the global has one).
480c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const;
481c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
482c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
483c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotinline DataLayout *unwrap(LLVMTargetDataRef P) {
484c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  return reinterpret_cast<DataLayout *>(P);
485c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}
486c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
487c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotinline LLVMTargetDataRef wrap(const DataLayout *P) {
488c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P));
489c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}
490c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
491c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Used to lazily calculate structure layout information for a target machine,
492c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// based on the DataLayout structure.
493c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass StructLayout {
494c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t StructSize;
495c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned StructAlignment;
496c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned IsPadded : 1;
497c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned NumElements : 31;
498c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t MemberOffsets[1]; // variable sized array!
499c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
500c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
501c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getSizeInBytes() const { return StructSize; }
502c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
503c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getSizeInBits() const { return 8 * StructSize; }
504c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
505c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getAlignment() const { return StructAlignment; }
506c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
507c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Returns whether the struct has padding or not between its fields.
508c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// NB: Padding in nested element is not taken into account.
509c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool hasPadding() const { return IsPadded; }
510c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
511c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Given a valid byte offset into the structure, returns the structure
512c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// index that contains it.
513c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getElementContainingOffset(uint64_t Offset) const;
514c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
515c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getElementOffset(unsigned Idx) const {
516c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    assert(Idx < NumElements && "Invalid element idx!");
517c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return MemberOffsets[Idx];
518c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
519c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
520c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getElementOffsetInBits(unsigned Idx) const {
521c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return getElementOffset(Idx) * 8;
522c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
523c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
524c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate:
525c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  friend class DataLayout; // Only DataLayout can create this class
526c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
527c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  StructLayout(StructType *ST, const DataLayout &DL);
528c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
529c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
530c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// The implementation of this method is provided inline as it is particularly
531c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// well suited to constant folding when called on a specific Type subclass.
532c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotinline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
533c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
534c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  switch (Ty->getTypeID()) {
535c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::LabelTyID:
536c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return getPointerSizeInBits(0);
537c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::PointerTyID:
538c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return getPointerSizeInBits(Ty->getPointerAddressSpace());
539c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::ArrayTyID: {
540c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    ArrayType *ATy = cast<ArrayType>(Ty);
541c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return ATy->getNumElements() *
542c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot           getTypeAllocSizeInBits(ATy->getElementType());
543c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
544c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::StructTyID:
545c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Get the layout annotation... which is lazily created on demand.
546c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
547c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::IntegerTyID:
548c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return Ty->getIntegerBitWidth();
549c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::HalfTyID:
550c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return 16;
551c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::FloatTyID:
552c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return 32;
553c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::DoubleTyID:
554c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::X86_MMXTyID:
555c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return 64;
556c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::PPC_FP128TyID:
557c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::FP128TyID:
558c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return 128;
559c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // In memory objects this is always aligned to a higher boundary, but
560c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // only 80 bits contain information.
561c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::X86_FP80TyID:
562c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return 80;
563c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  case Type::VectorTyID: {
564c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    VectorType *VTy = cast<VectorType>(Ty);
565c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType());
566c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
567c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  default:
568c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");
569c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
570c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}
571c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
572c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} // end namespace llvm
573c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
574c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#endif // LLVM_IR_DATALAYOUT_H
575