1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

[BPF] Generate array dimension size properly for zero-size elements

Currently, if an array element type size is 0, the number of
array elements will be set to 0, regardless of what user
specified. This implementation is done in the beginning where
BTF is mostly used to calculate the member offset.

For example,
  struct s {};
  struct s1 {
        int b;
        struct s a[2];
  };
  struct s1 s1;
The BTF will have struct "s1" member "a" with element count 0.

Now BTF types are used for compile-once and run-everywhere
relocations and we need more precise type representation
for type comparison. Andrii reported the issue as there
are differences between original structure and BTF-generated
structure.

This patch made the change to correctly assign "2"
as the number elements of member "a".
Some dead codes related to ElemSize compuation are also removed.

Differential Revision: https://reviews.llvm.org/D67979

llvm-svn: 372785
This commit is contained in:
Yonghong Song 2019-09-24 22:38:43 +00:00
parent 5a01f5b084
commit 3cc43e7b0b
2 changed files with 20 additions and 26 deletions

View File

@ -473,35 +473,29 @@ void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
// Visit array element type. // Visit array element type.
uint32_t ElemTypeId, ElemSize; uint32_t ElemTypeId;
const DIType *ElemType = CTy->getBaseType(); const DIType *ElemType = CTy->getBaseType();
visitTypeEntry(ElemType, ElemTypeId, false, false); visitTypeEntry(ElemType, ElemTypeId, false, false);
// Strip qualifiers from element type to get accurate element size. // Visit array dimensions.
ElemSize = ElemType->getSizeInBits() >> 3; DINodeArray Elements = CTy->getElements();
for (int I = Elements.size() - 1; I >= 0; --I) {
if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
const DISubrange *SR = cast<DISubrange>(Element);
auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
int64_t Count = CI->getSExtValue();
if (!CTy->getSizeInBits()) { // For struct s { int b; char c[]; }, the c[] will be represented
auto TypeEntry = std::make_unique<BTFTypeArray>(ElemTypeId, 0); // as an array with Count = -1.
ElemTypeId = addType(std::move(TypeEntry), CTy); auto TypeEntry =
} else { std::make_unique<BTFTypeArray>(ElemTypeId,
// Visit array dimensions. Count >= 0 ? Count : 0);
DINodeArray Elements = CTy->getElements(); if (I == 0)
for (int I = Elements.size() - 1; I >= 0; --I) { ElemTypeId = addType(std::move(TypeEntry), CTy);
if (auto *Element = dyn_cast_or_null<DINode>(Elements[I])) else
if (Element->getTag() == dwarf::DW_TAG_subrange_type) { ElemTypeId = addType(std::move(TypeEntry));
const DISubrange *SR = cast<DISubrange>(Element); }
auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
int64_t Count = CI->getSExtValue();
auto TypeEntry =
std::make_unique<BTFTypeArray>(ElemTypeId, Count);
if (I == 0)
ElemTypeId = addType(std::move(TypeEntry), CTy);
else
ElemTypeId = addType(std::move(TypeEntry));
ElemSize = ElemSize * Count;
}
}
} }
// The array TypeId is the type id of the outermost dimension. // The array TypeId is the type id of the outermost dimension.

View File

@ -32,7 +32,7 @@
; CHECK-NEXT: .long 0 ; CHECK-NEXT: .long 0
; CHECK-NEXT: .long 1 ; CHECK-NEXT: .long 1
; CHECK-NEXT: .long 3 ; CHECK-NEXT: .long 3
; CHECK-NEXT: .long 0 ; CHECK-NEXT: .long 10
; CHECK-NEXT: .long 3 # BTF_KIND_INT(id = 3) ; CHECK-NEXT: .long 3 # BTF_KIND_INT(id = 3)
; CHECK-NEXT: .long 16777216 # 0x1000000 ; CHECK-NEXT: .long 16777216 # 0x1000000
; CHECK-NEXT: .long 4 ; CHECK-NEXT: .long 4