brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · 44e888c Raw
244 lines · c
1//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H10#define LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H11 12#include "clang/AST/CharUnits.h"13#include "clang/AST/DeclCXX.h"14#include "clang/Basic/LLVM.h"15#include "llvm/ADT/DenseMap.h"16#include "llvm/IR/DerivedTypes.h"17 18namespace llvm {19  class StructType;20}21 22namespace clang {23namespace CodeGen {24 25/// Structure with information about how a bitfield should be accessed.26///27/// Often we layout a sequence of bitfields as a contiguous sequence of bits.28/// When the AST record layout does this, we represent it in the LLVM IR's type29/// as either a sequence of i8 members or a byte array to reserve the number of30/// bytes touched without forcing any particular alignment beyond the basic31/// character alignment.32///33/// Then accessing a particular bitfield involves converting this byte array34/// into a single integer of that size (i24 or i40 -- may not be power-of-two35/// size), loading it, and shifting and masking to extract the particular36/// subsequence of bits which make up that particular bitfield. This structure37/// encodes the information used to construct the extraction code sequences.38/// The CGRecordLayout also has a field index which encodes which byte-sequence39/// this bitfield falls within. Let's assume the following C struct:40///41///   struct S {42///     char a, b, c;43///     unsigned bits : 3;44///     unsigned more_bits : 4;45///     unsigned still_more_bits : 7;46///   };47///48/// This will end up as the following LLVM type. The first array is the49/// bitfield, and the second is the padding out to a 4-byte alignment.50///51///   %t = type { i8, i8, i8, i8, i8, [3 x i8] }52///53/// When generating code to access more_bits, we'll generate something54/// essentially like this:55///56///   define i32 @foo(%t* %base) {57///     %0 = gep %t* %base, i32 0, i32 358///     %2 = load i8* %159///     %3 = lshr i8 %2, 360///     %4 = and i8 %3, 1561///     %5 = zext i8 %4 to i3262///     ret i32 %i63///   }64///65struct CGBitFieldInfo {66  /// The offset within a contiguous run of bitfields that are represented as67  /// a single "field" within the LLVM struct type. This offset is in bits.68  unsigned Offset : 16;69 70  /// The total size of the bit-field, in bits.71  unsigned Size : 15;72 73  /// Whether the bit-field is signed.74  LLVM_PREFERRED_TYPE(bool)75  unsigned IsSigned : 1;76 77  /// The storage size in bits which should be used when accessing this78  /// bitfield.79  unsigned StorageSize;80 81  /// The offset of the bitfield storage from the start of the struct.82  CharUnits StorageOffset;83 84  /// The offset within a contiguous run of bitfields that are represented as a85  /// single "field" within the LLVM struct type, taking into account the AAPCS86  /// rules for volatile bitfields. This offset is in bits.87  unsigned VolatileOffset : 16;88 89  /// The storage size in bits which should be used when accessing this90  /// bitfield.91  unsigned VolatileStorageSize;92 93  /// The offset of the bitfield storage from the start of the struct.94  CharUnits VolatileStorageOffset;95 96  CGBitFieldInfo()97      : Offset(), Size(), IsSigned(), StorageSize(), VolatileOffset(),98        VolatileStorageSize() {}99 100  CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned,101                 unsigned StorageSize, CharUnits StorageOffset)102      : Offset(Offset), Size(Size), IsSigned(IsSigned),103        StorageSize(StorageSize), StorageOffset(StorageOffset) {}104 105  void print(raw_ostream &OS) const;106  void dump() const;107 108  /// Given a bit-field decl, build an appropriate helper object for109  /// accessing that field (which is expected to have the given offset and110  /// size).111  static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types,112                                 const FieldDecl *FD,113                                 uint64_t Offset, uint64_t Size,114                                 uint64_t StorageSize,115                                 CharUnits StorageOffset);116};117 118/// CGRecordLayout - This class handles struct and union layout info while119/// lowering AST types to LLVM types.120///121/// These layout objects are only created on demand as IR generation requires.122class CGRecordLayout {123  friend class CodeGenTypes;124 125  CGRecordLayout(const CGRecordLayout &) = delete;126  void operator=(const CGRecordLayout &) = delete;127 128private:129  /// The LLVM type corresponding to this record layout; used when130  /// laying it out as a complete object.131  llvm::StructType *CompleteObjectType;132 133  /// The LLVM type for the non-virtual part of this record layout;134  /// used when laying it out as a base subobject.135  llvm::StructType *BaseSubobjectType;136 137  /// Map from (non-bit-field) struct field to the corresponding llvm struct138  /// type field no. This info is populated by record builder.139  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;140 141  /// Map from (bit-field) struct field to the corresponding llvm struct type142  /// field no. This info is populated by record builder.143  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;144 145  // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single146  // map for both virtual and non-virtual bases.147  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;148 149  /// Map from virtual bases to their field index in the complete object.150  llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases;151 152  /// False if any direct or indirect subobject of this class, when153  /// considered as a complete object, requires a non-zero bitpattern154  /// when zero-initialized.155  bool IsZeroInitializable : 1;156 157  /// False if any direct or indirect subobject of this class, when158  /// considered as a base subobject, requires a non-zero bitpattern159  /// when zero-initialized.160  bool IsZeroInitializableAsBase : 1;161 162public:163  CGRecordLayout(llvm::StructType *CompleteObjectType,164                 llvm::StructType *BaseSubobjectType,165                 bool IsZeroInitializable,166                 bool IsZeroInitializableAsBase)167    : CompleteObjectType(CompleteObjectType),168      BaseSubobjectType(BaseSubobjectType),169      IsZeroInitializable(IsZeroInitializable),170      IsZeroInitializableAsBase(IsZeroInitializableAsBase) {}171 172  /// Return the "complete object" LLVM type associated with173  /// this record.174  llvm::StructType *getLLVMType() const {175    return CompleteObjectType;176  }177 178  /// Return the "base subobject" LLVM type associated with179  /// this record.180  llvm::StructType *getBaseSubobjectLLVMType() const {181    return BaseSubobjectType;182  }183 184  /// Check whether this struct can be C++ zero-initialized185  /// with a zeroinitializer.186  bool isZeroInitializable() const {187    return IsZeroInitializable;188  }189 190  /// Check whether this struct can be C++ zero-initialized191  /// with a zeroinitializer when considered as a base subobject.192  bool isZeroInitializableAsBase() const {193    return IsZeroInitializableAsBase;194  }195 196  bool containsFieldDecl(const FieldDecl *FD) const {197    return FieldInfo.count(FD) != 0;198  }199 200  /// Return llvm::StructType element number that corresponds to the201  /// field FD.202  unsigned getLLVMFieldNo(const FieldDecl *FD) const {203    FD = FD->getCanonicalDecl();204    assert(FieldInfo.count(FD) && "Invalid field for record!");205    return FieldInfo.lookup(FD);206  }207 208  // Return whether the following non virtual base has a corresponding209  // entry in the LLVM struct.210  bool hasNonVirtualBaseLLVMField(const CXXRecordDecl *RD) const {211    return NonVirtualBases.count(RD);212  }213 214  unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {215    assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!");216    return NonVirtualBases.lookup(RD);217  }218 219  /// Return the LLVM field index corresponding to the given220  /// virtual base.  Only valid when operating on the complete object.221  unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const {222    assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!");223    return CompleteObjectVirtualBases.lookup(base);224  }225 226  /// Return the BitFieldInfo that corresponds to the field FD.227  const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {228    FD = FD->getCanonicalDecl();229    assert(FD->isBitField() && "Invalid call for non-bit-field decl!");230    llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator231      it = BitFields.find(FD);232    assert(it != BitFields.end() && "Unable to find bitfield info");233    return it->second;234  }235 236  void print(raw_ostream &OS) const;237  void dump() const;238};239 240}  // end namespace CodeGen241}  // end namespace clang242 243#endif244