Skip to content

Commit b302561

Browse files
committed
[SVE][IR] Scalable Vector size queries and IR instruction support
* Adds a TypeSize struct to represent the known minimum size of a type along with a flag to indicate that the runtime size is a integer multiple of that size * Converts existing size query functions from Type.h and DataLayout.h to return a TypeSize result * Adds convenience methods (including a transparent conversion operator to uint64_t) so that most existing code 'just works' as if the return values were still scalars. * Uses the new size queries along with ElementCount to ensure that all supported instructions used with scalable vectors can be constructed in IR. Reviewers: hfinkel, lattner, rkruppe, greened, rovka, rengolin, sdesmalen Reviewed By: rovka, sdesmalen Differential Revision: https://reviews.llvm.org/D53137 llvm-svn: 374042
1 parent df6e676 commit b302561

File tree

21 files changed

+811
-110
lines changed

21 files changed

+811
-110
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4277,8 +4277,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
42774277
// Update the largest vector width if any arguments have vector types.
42784278
for (unsigned i = 0; i < IRCallArgs.size(); ++i) {
42794279
if (auto *VT = dyn_cast<llvm::VectorType>(IRCallArgs[i]->getType()))
4280-
LargestVectorWidth = std::max(LargestVectorWidth,
4281-
VT->getPrimitiveSizeInBits());
4280+
LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
4281+
VT->getPrimitiveSizeInBits().getFixedSize());
42824282
}
42834283

42844284
// Compute the calling convention and attributes.
@@ -4361,8 +4361,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
43614361

43624362
// Update largest vector width from the return type.
43634363
if (auto *VT = dyn_cast<llvm::VectorType>(CI->getType()))
4364-
LargestVectorWidth = std::max(LargestVectorWidth,
4365-
VT->getPrimitiveSizeInBits());
4364+
LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
4365+
VT->getPrimitiveSizeInBits().getFixedSize());
43664366

43674367
// Insert instrumentation or attach profile metadata at indirect call sites.
43684368
// For more details, see the comment before the definition of

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,8 +2073,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
20732073

20742074
// Update largest vector width for any vector types.
20752075
if (auto *VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back()))
2076-
LargestVectorWidth = std::max(LargestVectorWidth,
2077-
VT->getPrimitiveSizeInBits());
2076+
LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
2077+
VT->getPrimitiveSizeInBits().getFixedSize());
20782078
} else {
20792079
ArgTypes.push_back(Dest.getAddress().getType());
20802080
Args.push_back(Dest.getPointer());
@@ -2098,8 +2098,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
20982098

20992099
// Update largest vector width for any vector types.
21002100
if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2101-
LargestVectorWidth = std::max(LargestVectorWidth,
2102-
VT->getPrimitiveSizeInBits());
2101+
LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
2102+
VT->getPrimitiveSizeInBits().getFixedSize());
21032103
if (Info.allowsRegister())
21042104
InOutConstraints += llvm::utostr(i);
21052105
else
@@ -2185,8 +2185,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
21852185

21862186
// Update largest vector width for any vector types.
21872187
if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2188-
LargestVectorWidth = std::max(LargestVectorWidth,
2189-
VT->getPrimitiveSizeInBits());
2188+
LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
2189+
VT->getPrimitiveSizeInBits().getFixedSize());
21902190

21912191
ArgTypes.push_back(Arg->getType());
21922192
Args.push_back(Arg);

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,13 +431,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
431431
// Scan function arguments for vector width.
432432
for (llvm::Argument &A : CurFn->args())
433433
if (auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
434-
LargestVectorWidth = std::max(LargestVectorWidth,
435-
VT->getPrimitiveSizeInBits());
434+
LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
435+
VT->getPrimitiveSizeInBits().getFixedSize());
436436

437437
// Update vector width based on return type.
438438
if (auto *VT = dyn_cast<llvm::VectorType>(CurFn->getReturnType()))
439-
LargestVectorWidth = std::max(LargestVectorWidth,
440-
VT->getPrimitiveSizeInBits());
439+
LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
440+
VT->getPrimitiveSizeInBits().getFixedSize());
441441

442442
// Add the required-vector-width attribute. This contains the max width from:
443443
// 1. min-vector-width attribute used in the source program.

llvm/include/llvm/ADT/DenseMapInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "llvm/ADT/Hashing.h"
1818
#include "llvm/ADT/StringRef.h"
1919
#include "llvm/Support/PointerLikeTypeTraits.h"
20-
#include "llvm/Support/ScalableSize.h"
20+
#include "llvm/Support/TypeSize.h"
2121
#include <cassert>
2222
#include <cstddef>
2323
#include <cstdint>

llvm/include/llvm/IR/DataLayout.h

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/Support/ErrorHandling.h"
3131
#include "llvm/Support/MathExtras.h"
3232
#include "llvm/Support/Alignment.h"
33+
#include "llvm/Support/TypeSize.h"
3334
#include <cassert>
3435
#include <cstdint>
3536
#include <string>
@@ -437,23 +438,33 @@ class DataLayout {
437438

438439
/// Returns the number of bits necessary to hold the specified type.
439440
///
441+
/// If Ty is a scalable vector type, the scalable property will be set and
442+
/// the runtime size will be a positive integer multiple of the base size.
443+
///
440444
/// For example, returns 36 for i36 and 80 for x86_fp80. The type passed must
441445
/// have a size (Type::isSized() must return true).
442-
uint64_t getTypeSizeInBits(Type *Ty) const;
446+
TypeSize getTypeSizeInBits(Type *Ty) const;
443447

444448
/// Returns the maximum number of bytes that may be overwritten by
445449
/// storing the specified type.
446450
///
451+
/// If Ty is a scalable vector type, the scalable property will be set and
452+
/// the runtime size will be a positive integer multiple of the base size.
453+
///
447454
/// For example, returns 5 for i36 and 10 for x86_fp80.
448-
uint64_t getTypeStoreSize(Type *Ty) const {
449-
return (getTypeSizeInBits(Ty) + 7) / 8;
455+
TypeSize getTypeStoreSize(Type *Ty) const {
456+
auto BaseSize = getTypeSizeInBits(Ty);
457+
return { (BaseSize.getKnownMinSize() + 7) / 8, BaseSize.isScalable() };
450458
}
451459

452460
/// Returns the maximum number of bits that may be overwritten by
453461
/// storing the specified type; always a multiple of 8.
454462
///
463+
/// If Ty is a scalable vector type, the scalable property will be set and
464+
/// the runtime size will be a positive integer multiple of the base size.
465+
///
455466
/// For example, returns 40 for i36 and 80 for x86_fp80.
456-
uint64_t getTypeStoreSizeInBits(Type *Ty) const {
467+
TypeSize getTypeStoreSizeInBits(Type *Ty) const {
457468
return 8 * getTypeStoreSize(Ty);
458469
}
459470

@@ -468,19 +479,25 @@ class DataLayout {
468479
/// Returns the offset in bytes between successive objects of the
469480
/// specified type, including alignment padding.
470481
///
482+
/// If Ty is a scalable vector type, the scalable property will be set and
483+
/// the runtime size will be a positive integer multiple of the base size.
484+
///
471485
/// This is the amount that alloca reserves for this type. For example,
472486
/// returns 12 or 16 for x86_fp80, depending on alignment.
473-
uint64_t getTypeAllocSize(Type *Ty) const {
487+
TypeSize getTypeAllocSize(Type *Ty) const {
474488
// Round up to the next alignment boundary.
475489
return alignTo(getTypeStoreSize(Ty), getABITypeAlignment(Ty));
476490
}
477491

478492
/// Returns the offset in bits between successive objects of the
479493
/// specified type, including alignment padding; always a multiple of 8.
480494
///
495+
/// If Ty is a scalable vector type, the scalable property will be set and
496+
/// the runtime size will be a positive integer multiple of the base size.
497+
///
481498
/// This is the amount that alloca reserves for this type. For example,
482499
/// returns 96 or 128 for x86_fp80, depending on alignment.
483-
uint64_t getTypeAllocSizeInBits(Type *Ty) const {
500+
TypeSize getTypeAllocSizeInBits(Type *Ty) const {
484501
return 8 * getTypeAllocSize(Ty);
485502
}
486503

@@ -598,40 +615,44 @@ class StructLayout {
598615

599616
// The implementation of this method is provided inline as it is particularly
600617
// well suited to constant folding when called on a specific Type subclass.
601-
inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
618+
inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
602619
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
603620
switch (Ty->getTypeID()) {
604621
case Type::LabelTyID:
605-
return getPointerSizeInBits(0);
622+
return TypeSize::Fixed(getPointerSizeInBits(0));
606623
case Type::PointerTyID:
607-
return getPointerSizeInBits(Ty->getPointerAddressSpace());
624+
return TypeSize::Fixed(getPointerSizeInBits(Ty->getPointerAddressSpace()));
608625
case Type::ArrayTyID: {
609626
ArrayType *ATy = cast<ArrayType>(Ty);
610627
return ATy->getNumElements() *
611628
getTypeAllocSizeInBits(ATy->getElementType());
612629
}
613630
case Type::StructTyID:
614631
// Get the layout annotation... which is lazily created on demand.
615-
return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
632+
return TypeSize::Fixed(
633+
getStructLayout(cast<StructType>(Ty))->getSizeInBits());
616634
case Type::IntegerTyID:
617-
return Ty->getIntegerBitWidth();
635+
return TypeSize::Fixed(Ty->getIntegerBitWidth());
618636
case Type::HalfTyID:
619-
return 16;
637+
return TypeSize::Fixed(16);
620638
case Type::FloatTyID:
621-
return 32;
639+
return TypeSize::Fixed(32);
622640
case Type::DoubleTyID:
623641
case Type::X86_MMXTyID:
624-
return 64;
642+
return TypeSize::Fixed(64);
625643
case Type::PPC_FP128TyID:
626644
case Type::FP128TyID:
627-
return 128;
645+
return TypeSize::Fixed(128);
628646
// In memory objects this is always aligned to a higher boundary, but
629647
// only 80 bits contain information.
630648
case Type::X86_FP80TyID:
631-
return 80;
649+
return TypeSize::Fixed(80);
632650
case Type::VectorTyID: {
633651
VectorType *VTy = cast<VectorType>(Ty);
634-
return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType());
652+
auto EltCnt = VTy->getElementCount();
653+
uint64_t MinBits = EltCnt.Min *
654+
getTypeSizeInBits(VTy->getElementType()).getFixedSize();
655+
return TypeSize(MinBits, EltCnt.Scalable);
635656
}
636657
default:
637658
llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");

llvm/include/llvm/IR/DerivedTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "llvm/IR/Type.h"
2424
#include "llvm/Support/Casting.h"
2525
#include "llvm/Support/Compiler.h"
26-
#include "llvm/Support/ScalableSize.h"
26+
#include "llvm/Support/TypeSize.h"
2727
#include <cassert>
2828
#include <cstdint>
2929

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ class CmpInst : public Instruction {
975975
static Type* makeCmpResultType(Type* opnd_type) {
976976
if (VectorType* vt = dyn_cast<VectorType>(opnd_type)) {
977977
return VectorType::get(Type::getInt1Ty(opnd_type->getContext()),
978-
vt->getNumElements());
978+
vt->getElementCount());
979979
}
980980
return Type::getInt1Ty(opnd_type->getContext());
981981
}

llvm/include/llvm/IR/Type.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/Support/Casting.h"
2222
#include "llvm/Support/Compiler.h"
2323
#include "llvm/Support/ErrorHandling.h"
24+
#include "llvm/Support/TypeSize.h"
2425
#include <cassert>
2526
#include <cstdint>
2627
#include <iterator>
@@ -281,12 +282,15 @@ class Type {
281282
/// This will return zero if the type does not have a size or is not a
282283
/// primitive type.
283284
///
285+
/// If this is a scalable vector type, the scalable property will be set and
286+
/// the runtime size will be a positive integer multiple of the base size.
287+
///
284288
/// Note that this may not reflect the size of memory allocated for an
285289
/// instance of the type or the number of bytes that are written when an
286290
/// instance of the type is stored to memory. The DataLayout class provides
287291
/// additional query functions to provide this information.
288292
///
289-
unsigned getPrimitiveSizeInBits() const LLVM_READONLY;
293+
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY;
290294

291295
/// If this is a vector type, return the getPrimitiveSizeInBits value for the
292296
/// element type. Otherwise return the getPrimitiveSizeInBits value for this

llvm/include/llvm/Support/MachineValueType.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "llvm/ADT/iterator_range.h"
1818
#include "llvm/Support/ErrorHandling.h"
1919
#include "llvm/Support/MathExtras.h"
20-
#include "llvm/Support/ScalableSize.h"
20+
#include "llvm/Support/TypeSize.h"
2121
#include <cassert>
2222

2323
namespace llvm {

llvm/include/llvm/Support/ScalableSize.h

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)