diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-04-13 20:58:55 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-04-13 20:58:55 +0000 |
commit | ab970f90ce31a53fe7e6375a37536bf0832fd922 (patch) | |
tree | dca72794ebe2bac936e3a1516ad07fc54112d899 /lib/CodeGen/CGRecordLayout.h | |
parent | 4895a8ca41352b9ce572cd64ffa93208898e7546 (diff) |
IRgen: Enhance CGBitFieldInfo with enough information to fully describe the "policy" with which a bit-field should be accessed.
- For now, these policies are computed to match the current IRgen strategy, although the new information isn't being used yet (except in -fdump-record-layouts).
- Design comments appreciated.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101178 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGRecordLayout.h')
-rw-r--r-- | lib/CodeGen/CGRecordLayout.h | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h index 2fb8191cf2..234f859118 100644 --- a/lib/CodeGen/CGRecordLayout.h +++ b/lib/CodeGen/CGRecordLayout.h @@ -20,10 +20,74 @@ namespace llvm { namespace clang { namespace CodeGen { -/// Helper object for describing how to generate the code for access to a +/// \brief Helper object for describing how to generate the code for access to a /// bit-field. +/// +/// This structure is intended to describe the "policy" of how the bit-field +/// should be accessed, which may be target, language, or ABI dependent. class CGBitFieldInfo { public: + /// Descriptor for a single component of a bit-field access. The entire + /// bit-field is constituted of a bitwise OR of all of the individual + /// components. + /// + /// Each component describes an accessed value, which is how the component + /// should be transferred to/from memory, and a target placement, which is how + /// that component fits into the constituted bit-field. The pseudo-IR for a + /// load is: + /// + /// %0 = gep %base, 0, FieldIndex + /// %1 = gep (i8*) %0, FieldByteOffset + /// %2 = (i(AccessWidth) *) %1 + /// %3 = load %2, align AccessAlignment + /// %4 = shr %3, FieldBitStart + /// + /// and the composed bit-field is formed as the boolean OR of all accesses, + /// masked to TargetBitWidth bits and shifted to TargetBitOffset. + struct AccessInfo { + /// Offset of the field to load in the LLVM structure, if any. + unsigned FieldIndex; + + /// Byte offset from the field address, if any. This should generally be + /// unused as the cleanest IR comes from having a well-constructed LLVM type + /// with proper GEP instructions, but sometimes its use is required, for + /// example if an access is intended to straddle an LLVM field boundary. + unsigned FieldByteOffset; + + /// Bit offset in the accessed value to use. The width is implied by \see + /// TargetBitWidth. + unsigned FieldBitStart; + + /// Bit width of the memory access to perform. + unsigned AccessWidth; + + /// The alignment of the memory access, or 0 if the default alignment should + /// be used. + // + // FIXME: Remove use of 0 to encode default, instead have IRgen do the right + // thing when it generates the code, if avoiding align directives is + // desired. + unsigned AccessAlignment; + + /// Offset for the target value. + unsigned TargetBitOffset; + + /// Number of bits in the access that are destined for the bit-field. + unsigned TargetBitWidth; + }; + +private: + /// The number of access components to use. + unsigned NumComponents; + + /// The components to use to access the bit-field. We may need up to three + /// separate components to support up to i64 bit-field access (4 + 2 + 1 byte + /// accesses). + // + // FIXME: De-hardcode this, just allocate following the struct. + AccessInfo Components[3]; + +public: CGBitFieldInfo(const llvm::Type *FieldTy, unsigned FieldNo, unsigned Start, unsigned Size, bool IsSigned) : FieldTy(FieldTy), FieldNo(FieldNo), @@ -36,6 +100,24 @@ public: unsigned Size; bool IsSigned : 1; +public: + bool isSigned() const { return IsSigned; } + + unsigned getNumComponents() const { return NumComponents; } + void setNumComponents(unsigned Value) { + assert(Value < 4 && "Invalid number of components!"); + NumComponents = Value; + } + + const AccessInfo &getComponent(unsigned Index) const { + assert(Index < getNumComponents() && "Invalid access!"); + return Components[Index]; + } + AccessInfo &getComponent(unsigned Index) { + assert(Index < getNumComponents() && "Invalid access!"); + return Components[Index]; + } + void print(llvm::raw_ostream &OS) const; void dump() const; }; |