diff options
author | Chris Lattner <sabre@nondot.org> | 2010-06-23 06:00:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-06-23 06:00:24 +0000 |
commit | 788b0fd67e1992f23555454efcdb16a19dfefac3 (patch) | |
tree | 9a2fb45262ab3d833202750f6cf4c5150ed2c521 /lib | |
parent | 8dab6571b2cab96f44d0a1d6e3edbfdb68b7ed6b (diff) |
improve altivec vector bool/pixel support, patch by Anton Yartsev
with several tweaks by me.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106619 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 25 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 7 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 16 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 10 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 3 | ||||
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 55 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 11 |
10 files changed, 105 insertions, 49 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 80bda841fe..0be1778260 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1514,7 +1514,7 @@ QualType ASTContext::getIncompleteArrayType(QualType EltTy, /// getVectorType - Return the unique reference to a vector type of /// the specified element type and size. VectorType must be a built-in type. QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, - bool IsAltiVec, bool IsPixel) { + VectorType::AltiVecSpecific AltiVecSpec) { BuiltinType *baseType; baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr()); @@ -1522,8 +1522,8 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, // Check if we've already instantiated a vector of this type. llvm::FoldingSetNodeID ID; - VectorType::Profile(ID, vecType, NumElts, Type::Vector, - IsAltiVec, IsPixel); + VectorType::Profile(ID, vecType, NumElts, Type::Vector, AltiVecSpec); + void *InsertPos = 0; if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(VTP, 0); @@ -1531,16 +1531,19 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, // If the element type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!vecType.isCanonical() || IsAltiVec || IsPixel) { - Canonical = getVectorType(getCanonicalType(vecType), - NumElts, false, false); + if (!vecType.isCanonical() || (AltiVecSpec == VectorType::AltiVec)) { + // pass VectorType::NotAltiVec for AltiVecSpec to make AltiVec canonical + // vector type (except 'vector bool ...' and 'vector Pixel') the same as + // the equivalent GCC vector types + Canonical = getVectorType(getCanonicalType(vecType), NumElts, + VectorType::NotAltiVec); // Get the new insert position for the node we care about. VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } VectorType *New = new (*this, TypeAlignment) - VectorType(vecType, NumElts, Canonical, IsAltiVec, IsPixel); + VectorType(vecType, NumElts, Canonical, AltiVecSpec); VectorTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, 0); @@ -1556,7 +1559,8 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) { // Check if we've already instantiated a vector of this type. llvm::FoldingSetNodeID ID; - VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, false, false); + VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, + VectorType::NotAltiVec); void *InsertPos = 0; if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(VTP, 0); @@ -4933,7 +4937,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) { // Turn <4 x signed int> -> <4 x unsigned int> if (const VectorType *VTy = T->getAs<VectorType>()) return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()), - VTy->getNumElements(), VTy->isAltiVec(), VTy->isPixel()); + VTy->getNumElements(), VTy->getAltiVecSpecific()); // For enums, we return the unsigned version of the base type. if (const EnumType *ETy = T->getAs<EnumType>()) @@ -5091,7 +5095,8 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context, QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false); // FIXME: Don't know what to do about AltiVec. - Type = Context.getVectorType(ElementType, NumElements, false, false); + Type = Context.getVectorType(ElementType, NumElements, + VectorType::NotAltiVec); break; } case 'X': { diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index e1c2abd251..8d347d1716 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -440,9 +440,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return false; if (Vec1->getNumElements() != Vec2->getNumElements()) return false; - if (Vec1->isAltiVec() != Vec2->isAltiVec()) - return false; - if (Vec1->isPixel() != Vec2->isPixel()) + if (Vec1->getAltiVecSpecific() != Vec2->getAltiVecSpecific()) return false; break; } @@ -1191,8 +1189,7 @@ QualType ASTNodeImporter::VisitVectorType(VectorType *T) { return Importer.getToContext().getVectorType(ToElementType, T->getNumElements(), - T->isAltiVec(), - T->isPixel()); + T->getAltiVecSpecific()); } QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) { diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 2fa84f350b..a08ee1ae69 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -227,12 +227,13 @@ void TypePrinter::PrintDependentSizedExtVector( } void TypePrinter::PrintVector(const VectorType *T, std::string &S) { - if (T->isAltiVec()) { - if (T->isPixel()) + if (T->getAltiVecSpecific() != VectorType::NotAltiVec) { + if (T->getAltiVecSpecific() == VectorType::Pixel) S = "__vector __pixel " + S; else { Print(T->getElementType(), S); - S = "__vector " + S; + S = ((T->getAltiVecSpecific() == VectorType::Bool) + ? "__vector __bool " : "__vector ") + S; } } else { // FIXME: We prefer to print the size directly here, but have no way diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index e1e2f1069b..01838f98d4 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -1322,12 +1322,20 @@ void CXXNameMangler::mangleType(const ComplexType *T) { } // GNU extension: vector types -// <type> ::= <vector-type> -// <vector-type> ::= Dv <positive dimension number> _ <element type> -// ::= Dv [<dimension expression>] _ <element type> +// <type> ::= <vector-type> +// <vector-type> ::= Dv <positive dimension number> _ +// <extended element type> +// ::= Dv [<dimension expression>] _ <element type> +// <extended element type> ::= <element type> +// ::= p # AltiVec vector pixel void CXXNameMangler::mangleType(const VectorType *T) { Out << "Dv" << T->getNumElements() << '_'; - mangleType(T->getElementType()); + if (T->getAltiVecSpecific() == VectorType::Pixel) + Out << 'p'; + else if (T->getAltiVecSpecific() == VectorType::Bool) + Out << 'b'; + else + mangleType(T->getElementType()); } void CXXNameMangler::mangleType(const ExtVectorType *T) { mangleType(static_cast<const VectorType*>(T)); diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index b83445bc50..97c4d380eb 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -2060,20 +2060,20 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { } case pch::TYPE_VECTOR: { - if (Record.size() != 4) { + if (Record.size() != 3) { Error("incorrect encoding of vector type in PCH file"); return QualType(); } QualType ElementType = GetType(Record[0]); unsigned NumElements = Record[1]; - bool AltiVec = Record[2]; - bool Pixel = Record[3]; - return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel); + unsigned AltiVecSpec = Record[2]; + return Context->getVectorType(ElementType, NumElements, + (VectorType::AltiVecSpecific)AltiVecSpec); } case pch::TYPE_EXT_VECTOR: { - if (Record.size() != 4) { + if (Record.size() != 3) { Error("incorrect encoding of extended vector type in PCH file"); return QualType(); } diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 1fb90851b5..a55684a29a 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -128,8 +128,7 @@ void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { void PCHTypeWriter::VisitVectorType(const VectorType *T) { Writer.AddTypeRef(T->getElementType(), Record); Record.push_back(T->getNumElements()); - Record.push_back(T->isAltiVec()); - Record.push_back(T->isPixel()); + Record.push_back(T->getAltiVecSpecific()); Code = pch::TYPE_VECTOR; } diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index 5dc08b3dfa..2f328b0e65 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -253,7 +253,8 @@ bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); TypeSpecWidth = W; TSWLoc = Loc; - if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { + if (TypeAltiVecVector && !TypeAltiVecBool && + ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); DiagID = diag::warn_vector_long_decl_spec_combination; return true; @@ -290,13 +291,18 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, DiagID = diag::err_invalid_decl_spec_combination; return true; } + if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { + TypeAltiVecBool = true; + TSTLoc = Loc; + return false; + } TypeSpecType = T; TypeRep = Rep; TSTLoc = Loc; TypeSpecOwned = Owned; - if (TypeAltiVecVector && (TypeSpecType == TST_double)) { + if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); - DiagID = diag::err_invalid_vector_double_decl_spec_combination; + DiagID = diag::err_invalid_vector_decl_spec; return true; } return false; @@ -316,14 +322,12 @@ bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { - if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) { + if (!TypeAltiVecVector || TypeAltiVecPixel || + (TypeSpecType != TST_unspecified)) { PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); DiagID = diag::err_invalid_pixel_decl_spec_combination; return true; } - TypeSpecType = TST_int; - TypeSpecSign = TSS_unsigned; - TypeSpecWidth = TSW_short; TypeAltiVecPixel = isAltiVecPixel; TSTLoc = Loc; return false; @@ -438,6 +442,42 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { // Check the type specifier components first. SourceManager &SrcMgr = PP.getSourceManager(); + // Validate and finalize AltiVec vector declspec. + if (TypeAltiVecVector) { + if (TypeAltiVecBool) { + // Sign specifiers are not allowed with vector bool. (PIM 2.1) + if (TypeSpecSign != TSS_unspecified) { + Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + << getSpecifierName((TSS)TypeSpecSign); + } + + // Only char/int are valid with vector bool. (PIM 2.1) + if ((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && + (TypeSpecType != TST_int) || TypeAltiVecPixel) { + Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + << (TypeAltiVecPixel ? "__pixel" : + getSpecifierName((TST)TypeSpecType)); + } + + // Only 'short' is valid with vector bool. (PIM 2.1) + if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) + Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + << getSpecifierName((TSW)TypeSpecWidth); + + // Elements of vector bool are interpreted as unsigned. (PIM 2.1) + if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || + (TypeSpecWidth != TSW_unspecified)) + TypeSpecSign = TSS_unsigned; + } + + if (TypeAltiVecPixel) { + //TODO: perform validation + TypeSpecType = TST_int; + TypeSpecSign = TSS_unsigned; + TypeSpecWidth = TSW_short; + } + } + // signed/unsigned are only valid with int/char/wchar_t. if (TypeSpecSign != TSS_unspecified) { if (TypeSpecType == TST_unspecified) @@ -513,7 +553,6 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { ClearStorageClassSpecs(); } - // Okay, now we can infer the real type. // TODO: return "auto function" and other bad things based on the real type. diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d9264870ae..b61b4d65c9 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -782,7 +782,8 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { return ExprError(); } else if (numElements != numResElements) { QualType eltType = LHSType->getAs<VectorType>()->getElementType(); - resType = Context.getVectorType(eltType, numResElements, false, false); + resType = Context.getVectorType(eltType, numResElements, + VectorType::NotAltiVec); } } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 48c17cde43..244f218860 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -383,8 +383,12 @@ static QualType ConvertDeclSpecToType(Sema &TheSema, } else if (DS.isTypeAltiVecVector()) { unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(Result)); assert(typeSize > 0 && "type size for vector must be greater than 0 bits"); - Result = Context.getVectorType(Result, 128/typeSize, true, - DS.isTypeAltiVecPixel()); + VectorType::AltiVecSpecific AltiVecSpec = VectorType::AltiVec; + if (DS.isTypeAltiVecPixel()) + AltiVecSpec = VectorType::Pixel; + else if (DS.isTypeAltiVecBool()) + AltiVecSpec = VectorType::Bool; + Result = Context.getVectorType(Result, 128/typeSize, AltiVecSpec); } assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary && @@ -1162,7 +1166,8 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, } if (FTI.NumArgs && FTI.ArgInfo[0].Param == 0) { - // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition. + // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function + // definition. Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration); D.setInvalidType(true); break; @@ -1880,7 +1885,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) { /// The raw attribute should contain precisely 1 argument, the vector size for /// the variable, measured in bytes. If curType and rawAttr are well formed, /// this routine will return a new vector type. -static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, Sema &S) { +static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, + Sema &S) { // Check the attribute arugments. if (Attr.getNumArgs() != 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; @@ -1923,7 +1929,8 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, S // Success! Instantiate the vector type, the number of elements is > 0, and // not required to be a power of 2, unlike GCC. - CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, false, false); + CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, + VectorType::NotAltiVec); } void ProcessTypeAttributeList(Sema &S, QualType &Result, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index d959f1c22e..b2a405934c 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -442,7 +442,7 @@ public: /// By default, performs semantic analysis when building the vector type. /// Subclasses may override this routine to provide different behavior. QualType RebuildVectorType(QualType ElementType, unsigned NumElements, - bool IsAltiVec, bool IsPixel); + VectorType::AltiVecSpecific AltiVecSpec); /// \brief Build a new extended vector type given the element type and /// number of elements. @@ -2811,7 +2811,7 @@ QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB, if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) { Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(), - T->isAltiVec(), T->isPixel()); + T->getAltiVecSpecific()); if (Result.isNull()) return QualType(); } @@ -6345,11 +6345,10 @@ TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType, template<typename Derived> QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType, - unsigned NumElements, - bool IsAltiVec, bool IsPixel) { + unsigned NumElements, + VectorType::AltiVecSpecific AltiVecSpec) { // FIXME: semantic checking! - return SemaRef.Context.getVectorType(ElementType, NumElements, - IsAltiVec, IsPixel); + return SemaRef.Context.getVectorType(ElementType, NumElements, AltiVecSpec); } template<typename Derived> |