2828#include " llvm/IR/Intrinsics.h"
2929#include " llvm/IR/Module.h"
3030#include " llvm/Support/raw_ostream.h"
31+ #include " llvm/Support/MathExtras.h"
3132
3233#include " DxilDiaSession.h"
3334#include " DxilDiaTableSymbols.h"
@@ -596,20 +597,23 @@ class SymbolManagerInit {
596597 TypeInfo (const TypeInfo &) = delete ;
597598 TypeInfo (TypeInfo &&) = default ;
598599
599- explicit TypeInfo (DWORD dwTypeID) : m_dwTypeID(dwTypeID) {}
600+ TypeInfo (DWORD dwTypeID, uint64_t alignInBits ) : m_dwTypeID(dwTypeID), m_alignInBytes(alignInBits / 8 ) {}
600601
601602 DWORD GetTypeID () const { return m_dwTypeID; }
602603 DWORD GetCurrentSizeInBytes () const { return m_dwCurrentSizeInBytes; }
604+ uint64_t GetAlignmentInBytes () const { return m_alignInBytes; }
603605 const std::vector<llvm::DIType *> &GetLayout () const { return m_Layout; }
604606
605607 void Embed (const TypeInfo &TI);
606608
607609 void AddBasicType (llvm::DIBasicType *BT);
610+ void AppendSize (uint64_t baseSize);
608611
609612 private:
610613 DWORD m_dwTypeID;
611614 std::vector<llvm::DIType *> m_Layout;
612615 DWORD m_dwCurrentSizeInBytes = 0 ;
616+ uint64_t m_alignInBytes;
613617 };
614618 using TypeToInfoMap = llvm::DenseMap<llvm::DIType *, std::unique_ptr<TypeInfo> >;
615619
@@ -662,9 +666,9 @@ class SymbolManagerInit {
662666 HRESULT GetTypeInfo (llvm::DIType *T, TypeInfo **TI);
663667
664668 template <typename Factory, typename ... Args>
665- HRESULT AddType (DWORD dwParentID, llvm::DIType *T, DWORD *pNewSymID, Args&&... args) {
669+ HRESULT AddType (DWORD dwParentID, llvm::DIType *T, DWORD *pNewSymID, uint64_t alignment, Args&&... args) {
666670 IFR (AddSymbol<Factory>(dwParentID, pNewSymID, std::forward<Args>(args)...));
667- if (!m_TypeToInfo.insert (std::make_pair (T, llvm::make_unique<TypeInfo>(*pNewSymID))).second ) {
671+ if (!m_TypeToInfo.insert (std::make_pair (T, llvm::make_unique<TypeInfo>(*pNewSymID, alignment ))).second ) {
668672 return E_FAIL;
669673 }
670674 return S_OK;
@@ -1140,13 +1144,28 @@ void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::Embed(const TypeInfo &
11401144 for (const auto &E : TI.GetLayout ()) {
11411145 m_Layout.emplace_back (E);
11421146 }
1147+ uint64_t alignmentInBytes = TI.GetAlignmentInBytes ();
1148+ if (alignmentInBytes != 0 ) {
1149+ m_dwCurrentSizeInBytes =
1150+ llvm::RoundUpToAlignment (m_dwCurrentSizeInBytes, alignmentInBytes);
1151+ }
11431152 m_dwCurrentSizeInBytes += TI.m_dwCurrentSizeInBytes ;
11441153}
11451154
1155+ void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::AppendSize (
1156+ uint64_t baseSize) {
1157+ static constexpr DWORD kNumBitsPerByte = 8 ;
1158+ m_dwCurrentSizeInBytes += baseSize / kNumBitsPerByte ;
1159+ }
1160+
11461161void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::AddBasicType (llvm::DIBasicType *BT) {
11471162 m_Layout.emplace_back (BT);
11481163
11491164 static constexpr DWORD kNumBitsPerByte = 8 ;
1165+ uint64_t alignmentInBytes = BT->getAlignInBits () / kNumBitsPerByte ;
1166+ if (alignmentInBytes != 0 ) {
1167+ m_dwCurrentSizeInBytes = llvm::RoundUpToAlignment (m_dwCurrentSizeInBytes, alignmentInBytes);
1168+ }
11501169 m_dwCurrentSizeInBytes += BT->getSizeInBits () / kNumBitsPerByte ;
11511170}
11521171
@@ -1402,7 +1421,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateSubroutineType(DWORD dw
14021421 };
14031422 }
14041423
1405- IFR (AddType<symbol_factory::Type>(dwParentID, ST, pNewTypeID, SymTagFunctionType, ST, LazyName));
1424+ IFR (AddType<symbol_factory::Type>(dwParentID, ST, pNewTypeID, 0 /* alignment */ , SymTagFunctionType, ST, LazyName));
14061425
14071426 return S_OK;
14081427}
@@ -1418,7 +1437,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateBasicType(DWORD dwParen
14181437 return S_OK;
14191438 };
14201439
1421- IFR (AddType<symbol_factory::Type>(dwParentID, BT, pNewTypeID, SymTagBaseType, BT, LazyName));
1440+ IFR (AddType<symbol_factory::Type>(dwParentID, BT, pNewTypeID, BT-> getAlignInBits (), SymTagBaseType, BT, LazyName));
14221441
14231442 TypeInfo *TI;
14241443 IFR (GetTypeInfo (BT, &TI));
@@ -1427,6 +1446,33 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateBasicType(DWORD dwParen
14271446 return S_OK;
14281447}
14291448
1449+ static uint64_t getBaseClassSize (llvm::DIType * Ty)
1450+ {
1451+ uint64_t sizeInBits = Ty->getSizeInBits ();
1452+ auto *DerivedTy = llvm::dyn_cast<llvm::DIDerivedType>(Ty);
1453+ if (DerivedTy != nullptr ) {
1454+ // Working around a bug where byte size is stored instead of bit size
1455+ if (sizeInBits == 4 && Ty->getSizeInBits () == 32 ) {
1456+ sizeInBits = 32 ;
1457+ }
1458+ if (sizeInBits == 0 ) {
1459+ const llvm::DITypeIdentifierMap EmptyMap;
1460+ switch (DerivedTy->getTag ()) {
1461+ case llvm::dwarf::DW_TAG_restrict_type:
1462+ case llvm::dwarf::DW_TAG_reference_type:
1463+ case llvm::dwarf::DW_TAG_const_type:
1464+ case llvm::dwarf::DW_TAG_typedef: {
1465+ llvm::DIType *baseType = DerivedTy->getBaseType ().resolve (EmptyMap);
1466+ if (baseType != nullptr ) {
1467+ return getBaseClassSize (baseType);
1468+ }
1469+ }
1470+ }
1471+ }
1472+ }
1473+ return sizeInBits;
1474+ }
1475+
14301476HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType (DWORD dwParentID, llvm::DICompositeType *CT, DWORD *pNewTypeID) {
14311477 switch (CT->getTag ()) {
14321478 case llvm::dwarf::DW_TAG_array_type: {
@@ -1477,7 +1523,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType(DWORD dwP
14771523 return S_OK;
14781524 };
14791525
1480- IFR (AddType<symbol_factory::Type>(dwParentID, CT, pNewTypeID, SymTagArrayType, CT, LazyName));
1526+ IFR (AddType<symbol_factory::Type>(dwParentID, CT, pNewTypeID, BaseType-> getAlignInBits (), SymTagArrayType, CT, LazyName));
14811527 TypeInfo *ctTI;
14821528 IFR (GetTypeInfo (CT, &ctTI));
14831529 TypeInfo *baseTI;
@@ -1512,18 +1558,32 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType(DWORD dwP
15121558 return S_OK;
15131559 };
15141560
1515- IFR (AddType<symbol_factory::UDT>(dwParentID, CT, pNewTypeID, CT, LazyName));
1561+ IFR (AddType<symbol_factory::UDT>(dwParentID, CT, pNewTypeID, CT-> getAlignInBits (), CT , LazyName));
15161562
15171563 TypeInfo *udtTI;
15181564 IFR (GetTypeInfo (CT, &udtTI));
15191565 auto udtScope = BeginUDTScope (udtTI);
1520- for (llvm::DINode *N : CT->getElements ()) {
1521- if (auto *Field = llvm::dyn_cast<llvm::DIType>(N)) {
1522- DWORD dwUnusedFieldID;
1523- IFR (CreateType (Field, &dwUnusedFieldID));
1566+ if (CT->getElements ().size () == 0 ) {
1567+ // "Resources" (textures, samplers, etc.) are composite types without any elements,
1568+ // but they do have a size.
1569+ udtTI->AppendSize (CT->getSizeInBits ());
1570+ } else {
1571+ for (llvm::DINode *N : CT->getElements ()) {
1572+ if (auto *Field = llvm::dyn_cast<llvm::DIType>(N)) {
1573+ DWORD dwUnusedFieldID;
1574+ IFR (CreateType (Field, &dwUnusedFieldID));
1575+ if (Field->getTag () == llvm::dwarf::DW_TAG_inheritance) {
1576+ // The base class is a type of its own, so will have contributed to
1577+ // its own TypeInfo. But we still need to remember the size that it
1578+ // contributed to this type:
1579+ auto *DerivedType = llvm::cast<llvm::DIDerivedType>(Field);
1580+ const llvm::DITypeIdentifierMap EmptyMap;
1581+ llvm::DIType *BaseType = DerivedType->getBaseType ().resolve (EmptyMap);
1582+ udtTI->AppendSize (getBaseClassSize (BaseType));
1583+ }
1584+ }
15241585 }
15251586 }
1526-
15271587 return S_OK;
15281588}
15291589
@@ -1612,7 +1672,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateHLSLVectorType(llvm::DI
16121672 }
16131673
16141674 const DWORD dwParentID = HlslProgramId;
1615- IFR (AddType<symbol_factory::VectorType>(dwParentID, T, pNewTypeID, T, dwElemTyID, ElemCnt->getLimitedValue ()));
1675+ IFR (AddType<symbol_factory::VectorType>(dwParentID, T, pNewTypeID, T-> getAlignInBits (), T , dwElemTyID, ElemCnt->getLimitedValue ()));
16161676
16171677 TypeInfo *vecTI;
16181678 IFR (GetTypeInfo (T, &vecTI));
@@ -1676,7 +1736,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::HandleDerivedType(DWORD dwPar
16761736 return E_FAIL;
16771737 }
16781738
1679- IFR (AddType<symbol_factory::TypedefType>(dwParentID, DT, pNewTypeID, DT, dwBaseTypeID));
1739+ IFR (AddType<symbol_factory::TypedefType>(dwParentID, DT, pNewTypeID, BaseTy-> getAlignInBits (), DT, dwBaseTypeID));
16801740
16811741 TypeInfo *dtTI;
16821742 IFR (GetTypeInfo (DT, &dtTI));
@@ -1715,7 +1775,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::HandleDerivedType(DWORD dwPar
17151775 }
17161776 }
17171777
1718- IFR (AddType<symbol_factory::Type>(dwParentID, DT, pNewTypeID, st, DT, LazyName));
1778+ IFR (AddType<symbol_factory::Type>(dwParentID, DT, pNewTypeID, DT-> getAlignInBits (), st, DT, LazyName));
17191779
17201780 if (DT->getTag () == llvm::dwarf::DW_TAG_const_type) {
17211781 TypeInfo *dtTI;
@@ -1788,13 +1848,16 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateUDTField(DWORD dwParent
17881848 DWORD dwLVTypeID;
17891849 IFR (CreateType (FieldTy, &dwLVTypeID));
17901850 if (m_pCurUDT != nullptr ) {
1791- const DWORD dwOffsetInBytes = CurrentUDTInfo ().GetCurrentSizeInBytes ();
1851+ TypeInfo *lvTI;
1852+ IFR (GetTypeInfo (FieldTy, &lvTI));
1853+ const DWORD dwOffsetInBytes =
1854+ (lvTI->GetAlignmentInBytes () == 0 )
1855+ ? CurrentUDTInfo ().GetCurrentSizeInBytes ()
1856+ : llvm::RoundUpToAlignment (CurrentUDTInfo ().GetCurrentSizeInBytes (), lvTI->GetAlignmentInBytes ());
17921857 DXASSERT_ARGS (dwOffsetInBytes == Field->getOffsetInBits () / 8 ,
17931858 " %d vs %d" ,
17941859 dwOffsetInBytes,
17951860 Field->getOffsetInBits () / 8 );
1796- TypeInfo *lvTI;
1797- IFR (GetTypeInfo (FieldTy, &lvTI));
17981861 CurrentUDTInfo ().Embed (*lvTI);
17991862 }
18001863
0 commit comments