diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Type.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 7 |
9 files changed, 44 insertions, 13 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 0b553bf991d..a23afac27b7 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -708,6 +708,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax); KEYWORD(umin); + KEYWORD(vscale); KEYWORD(x); KEYWORD(blockaddress); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index ab645348c53..085f3bd2999 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -2747,7 +2747,18 @@ bool LLParser::ParseStructBody(SmallVectorImpl<Type*> &Body) { /// Type /// ::= '[' APSINTVAL 'x' Types ']' /// ::= '<' APSINTVAL 'x' Types '>' +/// ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>' bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { + bool Scalable = false; + + if (isVector && Lex.getKind() == lltok::kw_vscale) { + Lex.Lex(); // consume the 'vscale' + if (ParseToken(lltok::kw_x, "expected 'x' after vscale")) + return true; + + Scalable = true; + } + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() || Lex.getAPSIntVal().getBitWidth() > 64) return TokError("expected number in address space"); @@ -2774,7 +2785,7 @@ bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { return Error(SizeLoc, "size too large for vector"); if (!VectorType::isValidElementType(EltTy)) return Error(TypeLoc, "invalid vector element type"); - Result = VectorType::get(EltTy, unsigned(Size)); + Result = VectorType::get(EltTy, unsigned(Size), Scalable); } else { if (!ArrayType::isValidElementType(EltTy)) return Error(TypeLoc, "invalid array element type"); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index acdfaa5ae90..8b0118e6942 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -37,6 +37,7 @@ enum Kind { bar, // | colon, // : + kw_vscale, kw_x, kw_true, kw_false, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 22d1b2165fd..a339f6eb710 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1878,7 +1878,8 @@ Error BitcodeReader::parseTypeTableBody() { return error("Invalid type"); ResultTy = ArrayType::get(ResultTy, Record[0]); break; - case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] + case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or + // [numelts, eltty, scalable] if (Record.size() < 2) return error("Invalid record"); if (Record[0] == 0) @@ -1886,7 +1887,8 @@ Error BitcodeReader::parseTypeTableBody() { ResultTy = getTypeByID(Record[1]); if (!ResultTy || !StructType::isValidElementType(ResultTy)) return error("Invalid type"); - ResultTy = VectorType::get(ResultTy, Record[0]); + bool Scalable = Record.size() > 2 ? Record[2] : false; + ResultTy = VectorType::get(ResultTy, Record[0], Scalable); break; } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 90de4688c8c..547889f82c7 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -941,10 +941,13 @@ void ModuleBitcodeWriter::writeTypeTable() { } case Type::VectorTyID: { VectorType *VT = cast<VectorType>(T); - // VECTOR [numelts, eltty] + // VECTOR [numelts, eltty] or + // [numelts, eltty, scalable] Code = bitc::TYPE_CODE_VECTOR; TypeVals.push_back(VT->getNumElements()); TypeVals.push_back(VE.getTypeID(VT->getElementType())); + if (VT->isScalable()) + TypeVals.push_back(VT->isScalable()); break; } } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index a5adfd9c8a6..eb5760daecb 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -620,7 +620,10 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { } case Type::VectorTyID: { VectorType *PTy = cast<VectorType>(Ty); - OS << "<" << PTy->getNumElements() << " x "; + OS << "<"; + if (PTy->isScalable()) + OS << "vscale x "; + OS << PTy->getNumElements() << " x "; print(PTy->getElementType(), OS); OS << '>'; return; diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 4560617624e..78cf707e0e7 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1334,7 +1334,7 @@ public: unsigned NamedStructTypesUniqueID = 0; DenseMap<std::pair<Type *, uint64_t>, ArrayType*> ArrayTypes; - DenseMap<std::pair<Type *, unsigned>, VectorType*> VectorTypes; + DenseMap<std::pair<Type *, ElementCount>, VectorType*> VectorTypes; DenseMap<Type*, PointerType*> PointerTypes; // Pointers in AddrSpace = 0 DenseMap<std::pair<Type*, unsigned>, PointerType*> ASPointerTypes; diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp index 4016bb10ba3..8ece7f223dd 100644 --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -504,6 +504,8 @@ StringRef StructType::getName() const { } bool StructType::isValidElementType(Type *ElemTy) { + if (auto *VTy = dyn_cast<VectorType>(ElemTy)) + return !VTy->isScalable(); return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() && !ElemTy->isTokenTy(); @@ -590,6 +592,8 @@ ArrayType *ArrayType::get(Type *ElementType, uint64_t NumElements) { } bool ArrayType::isValidElementType(Type *ElemTy) { + if (auto *VTy = dyn_cast<VectorType>(ElemTy)) + return !VTy->isScalable(); return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() && !ElemTy->isTokenTy(); @@ -599,21 +603,20 @@ bool ArrayType::isValidElementType(Type *ElemTy) { // VectorType Implementation //===----------------------------------------------------------------------===// -VectorType::VectorType(Type *ElType, unsigned NumEl) - : SequentialType(VectorTyID, ElType, NumEl) {} +VectorType::VectorType(Type *ElType, ElementCount EC) + : SequentialType(VectorTyID, ElType, EC.Min), Scalable(EC.Scalable) {} -VectorType *VectorType::get(Type *ElementType, unsigned NumElements) { - assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0"); +VectorType *VectorType::get(Type *ElementType, ElementCount EC) { + assert(EC.Min > 0 && "#Elements of a VectorType must be greater than 0"); assert(isValidElementType(ElementType) && "Element type of a VectorType must " "be an integer, floating point, or " "pointer type."); LLVMContextImpl *pImpl = ElementType->getContext().pImpl; VectorType *&Entry = ElementType->getContext().pImpl - ->VectorTypes[std::make_pair(ElementType, NumElements)]; - + ->VectorTypes[std::make_pair(ElementType, EC)]; if (!Entry) - Entry = new (pImpl->Alloc) VectorType(ElementType, NumElements); + Entry = new (pImpl->Alloc) VectorType(ElementType, EC); return Entry; } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 0ab421e057d..b0464346557 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -691,6 +691,13 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { "DIGlobalVariableExpression"); } + // Scalable vectors cannot be global variables, since we don't know + // the runtime size. If the global is a struct or an array containing + // scalable vectors, that will be caught by the isValidElementType methods + // in StructType or ArrayType instead. + if (auto *VTy = dyn_cast<VectorType>(GV.getValueType())) + Assert(!VTy->isScalable(), "Globals cannot contain scalable vectors", &GV); + if (!GV.hasInitializer()) { visitGlobalValue(GV); return; |