diff options
| author | Yonghong Song <yhs@fb.com> | 2019-03-28 21:59:49 +0000 |
|---|---|---|
| committer | Yonghong Song <yhs@fb.com> | 2019-03-28 21:59:49 +0000 |
| commit | 360a4e2ca6ead28b4d761b189c3995be5ac72a91 (patch) | |
| tree | 23732508543f26ec86a25e44a5622f0fef04e5e0 /llvm/lib/Target/BPF/BTFDebug.cpp | |
| parent | 3dd72ea810dbb0c45c5815d2f43cc2b393d274a1 (diff) | |
| download | bcm5719-llvm-360a4e2ca6ead28b4d761b189c3995be5ac72a91.tar.gz bcm5719-llvm-360a4e2ca6ead28b4d761b189c3995be5ac72a91.zip | |
[BPF] add proper multi-dimensional array support
For multi-dimensional array like below
int a[2][3];
the previous implementation generates BTF_KIND_ARRAY type
like below:
. element_type: int
. index_type: unsigned int
. number of elements: 6
This is not the best way to represent arrays, esp.,
when converting BTF back to headers and users will see
int a[6];
instead.
This patch generates proper support for multi-dimensional arrays.
For "int a[2][3]", the two BTF_KIND_ARRAY types will be
generated:
Type #n:
. element_type: int
. index_type: unsigned int
. number of elements: 3
Type #(n+1):
. element_type: #n
. index_type: unsigned int
. number of elements: 2
The linux kernel already supports such a multi-dimensional
array representation properly.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D59943
llvm-svn: 357215
Diffstat (limited to 'llvm/lib/Target/BPF/BTFDebug.cpp')
| -rw-r--r-- | llvm/lib/Target/BPF/BTFDebug.cpp | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index f054933a2aa..6218ef41add 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -158,45 +158,24 @@ void BTFTypeEnum::emitType(MCStreamer &OS) { } } -BTFTypeArray::BTFTypeArray(const DICompositeType *ATy) : ATy(ATy) { +BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems) { Kind = BTF::BTF_KIND_ARRAY; + BTFType.NameOff = 0; BTFType.Info = Kind << 24; + BTFType.Size = 0; + + ArrayInfo.ElemType = ElemTypeId; + ArrayInfo.Nelems = NumElems; } -/// Represent a BTF array. BTF does not record array dimensions, -/// so conceptually a BTF array is a one-dimensional array. +/// Represent a BTF array. void BTFTypeArray::completeType(BTFDebug &BDebug) { - BTFType.NameOff = BDebug.addString(ATy->getName()); - BTFType.Size = 0; - - auto *BaseType = ATy->getBaseType().resolve(); - ArrayInfo.ElemType = BDebug.getTypeId(BaseType); // The IR does not really have a type for the index. // A special type for array index should have been // created during initial type traversal. Just // retrieve that type id. ArrayInfo.IndexType = BDebug.getArrayIndexTypeId(); - - // Get the number of array elements. - // If the array size is 0, set the number of elements as 0. - // Otherwise, recursively traverse the base types to - // find the element size. The number of elements is - // the totoal array size in bits divided by - // element size in bits. - uint64_t ArraySizeInBits = ATy->getSizeInBits(); - if (!ArraySizeInBits) { - ArrayInfo.Nelems = 0; - } else { - uint32_t BaseTypeSize = BaseType->getSizeInBits(); - while (!BaseTypeSize) { - const auto *DDTy = cast<DIDerivedType>(BaseType); - BaseType = DDTy->getBaseType().resolve(); - assert(BaseType); - BaseTypeSize = BaseType->getSizeInBits(); - } - ArrayInfo.Nelems = ATy->getSizeInBits() / BaseTypeSize; - } } void BTFTypeArray::emitType(MCStreamer &OS) { @@ -447,8 +426,34 @@ void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct, } void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { - auto TypeEntry = llvm::make_unique<BTFTypeArray>(CTy); - TypeId = addType(std::move(TypeEntry), CTy); + // Visit array element type. + uint32_t ElemTypeId; + visitTypeEntry(CTy->getBaseType().resolve(), ElemTypeId); + + if (!CTy->getSizeInBits()) { + auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemTypeId, 0); + ElemTypeId = addType(std::move(TypeEntry), CTy); + } else { + // Visit array dimensions. + 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(); + + auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemTypeId, Count); + if (I == 0) + ElemTypeId = addType(std::move(TypeEntry), CTy); + else + ElemTypeId = addType(std::move(TypeEntry)); + } + } + } + + // The array TypeId is the type id of the outermost dimension. + TypeId = ElemTypeId; // The IR does not have a type for array index while BTF wants one. // So create an array index type if there is none. @@ -457,9 +462,6 @@ void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { 0, "__ARRAY_SIZE_TYPE__"); ArrayIndexTypeId = addType(std::move(TypeEntry)); } - - // Visit array element type. - visitTypeEntry(CTy->getBaseType().resolve()); } void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) { |

