Skip to content

Commit 360d438

Browse files
nikicgithub-actions[bot]
authored andcommitted
Automerge: [DataLayout] Specialize the getTypeAllocSize() implementation (#156687)
getTypeAllocSize() currently works by taking the type store size and aligning it to the ABI alignment. However, this ends up doing redundant work in various cases, for example arrays will unnecessarily repeat the alignment step, and structs will fetch the StructLayout multiple times. As this code is rather hot (it is called every time we need to calculate GEP offsets for example), specialize the implementation. This repeats a small amount of logic from getAlignment(), but I think that's worthwhile.
2 parents 41006c6 + 4d927a5 commit 360d438

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

llvm/include/llvm/IR/DataLayout.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -501,10 +501,7 @@ class DataLayout {
501501
///
502502
/// This is the amount that alloca reserves for this type. For example,
503503
/// returns 12 or 16 for x86_fp80, depending on alignment.
504-
TypeSize getTypeAllocSize(Type *Ty) const {
505-
// Round up to the next alignment boundary.
506-
return alignTo(getTypeStoreSize(Ty), getABITypeAlign(Ty).value());
507-
}
504+
TypeSize getTypeAllocSize(Type *Ty) const;
508505

509506
/// Returns the offset in bits between successive objects of the
510507
/// specified type, including alignment padding; always a multiple of 8.

llvm/lib/IR/DataLayout.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,44 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
844844
}
845845
}
846846

847+
TypeSize DataLayout::getTypeAllocSize(Type *Ty) const {
848+
switch (Ty->getTypeID()) {
849+
case Type::ArrayTyID: {
850+
// The alignment of the array is the alignment of the element, so there
851+
// is no need for further adjustment.
852+
auto *ATy = cast<ArrayType>(Ty);
853+
return ATy->getNumElements() * getTypeAllocSize(ATy->getElementType());
854+
}
855+
case Type::StructTyID: {
856+
const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
857+
TypeSize Size = Layout->getSizeInBytes();
858+
859+
if (cast<StructType>(Ty)->isPacked())
860+
return Size;
861+
862+
Align A = std::max(StructABIAlignment, Layout->getAlignment());
863+
return alignTo(Size, A.value());
864+
}
865+
case Type::IntegerTyID: {
866+
unsigned BitWidth = Ty->getIntegerBitWidth();
867+
TypeSize Size = TypeSize::getFixed(divideCeil(BitWidth, 8));
868+
Align A = getIntegerAlignment(BitWidth, /*ABI=*/true);
869+
return alignTo(Size, A.value());
870+
}
871+
case Type::PointerTyID: {
872+
unsigned AS = Ty->getPointerAddressSpace();
873+
TypeSize Size = TypeSize::getFixed(getPointerSize(AS));
874+
return alignTo(Size, getPointerABIAlignment(AS).value());
875+
}
876+
case Type::TargetExtTyID: {
877+
Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();
878+
return getTypeAllocSize(LayoutTy);
879+
}
880+
default:
881+
return alignTo(getTypeStoreSize(Ty), getABITypeAlign(Ty).value());
882+
}
883+
}
884+
847885
Align DataLayout::getABITypeAlign(Type *Ty) const {
848886
return getAlignment(Ty, true);
849887
}

llvm/test/CodeGen/AArch64/alloca-oversized.ll

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ define void @test_oversized(ptr %dst, i32 %cond) {
1010
; CHECK-NEXT: .cfi_offset w30, -8
1111
; CHECK-NEXT: .cfi_offset w29, -16
1212
; CHECK-NEXT: mov x8, sp
13-
; CHECK-NEXT: mov x9, #2305843009213693952 // =0x2000000000000000
14-
; CHECK-NEXT: sub x8, x8, x9
1513
; CHECK-NEXT: sub x9, x29, #32
16-
; CHECK-NEXT: mov sp, x8
1714
; CHECK-NEXT: cmp w1, #0
1815
; CHECK-NEXT: csel x8, x9, x8, eq
1916
; CHECK-NEXT: str x8, [x0]

0 commit comments

Comments
 (0)