diff options
author | Nate Begeman <natebegeman@mac.com> | 2009-01-18 03:20:47 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2009-01-18 03:20:47 +0000 |
commit | 59b5da6d853b4368b984700315adf7b37de05764 (patch) | |
tree | a87909833d6430bb5abcd31c866393a438fc67a8 | |
parent | 77ecb3a28f21496ecfdbb3d5f5b66b0d2abf48c9 (diff) |
Support evaluation of vector constant expressions, and codegen of same.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62455 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/APValue.cpp | 4 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 5 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 78 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 11 | ||||
-rw-r--r-- | test/CodeGen/ext-vector.c | 2 |
6 files changed, 94 insertions, 10 deletions
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index 87d9fc3442..23e9e980c5 100644 --- a/lib/AST/APValue.cpp +++ b/lib/AST/APValue.cpp @@ -91,7 +91,9 @@ void APValue::print(llvm::raw_ostream &OS) const { OS << "Float: " << GetApproxValue(getFloat()); return; case Vector: - OS << "Vector: <todo>"; + OS << "Vector: " << getVectorElt(0); + for (unsigned i = 1; i != getVectorLength(); ++i) + OS << ", " << getVectorElt(i); return; case ComplexInt: OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 4dd06b924a..03b49499ee 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -487,6 +487,7 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const { // An assignment expression [...] is not an lvalue. return LV_InvalidExpression; } + // FIXME: OverloadExprClass case CallExprClass: case CXXOperatorCallExprClass: case CXXMemberCallExprClass: { @@ -701,6 +702,10 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { break; case StringLiteralClass: return true; + case CompoundLiteralExprClass: { + const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer(); + return Exp->isConstantExpr(Ctx, Loc); + } case InitListExprClass: { const InitListExpr *Exp = cast<InitListExpr>(this); unsigned numInits = Exp->getNumInits(); diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index b5a234c508..f45bd787b5 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -318,6 +318,78 @@ APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { } //===----------------------------------------------------------------------===// +// Vector Evaluation +//===----------------------------------------------------------------------===// + +namespace { + class VISIBILITY_HIDDEN VectorExprEvaluator + : public StmtVisitor<VectorExprEvaluator, APValue> { + EvalInfo &Info; + public: + + VectorExprEvaluator(EvalInfo &info) : Info(info) {} + + APValue VisitStmt(Stmt *S) { + return APValue(); + } + + APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + APValue VisitCastExpr(const CastExpr* E); + APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); + APValue VisitInitListExpr(const InitListExpr *E); + }; +} // end anonymous namespace + +static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { + if (!E->getType()->isVectorType()) + return false; + Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E)); + return !Result.isUninit(); +} + +APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { + const Expr* SE = E->getSubExpr(); + + // Check for vector->vector bitcast. + if (SE->getType()->isVectorType()) + return this->Visit(const_cast<Expr*>(SE)); + + return APValue(); +} + +APValue +VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { + return this->Visit(const_cast<Expr*>(E->getInitializer())); +} + +APValue +VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { + const VectorType *VT = E->getType()->getAsVectorType(); + unsigned NumInits = E->getNumInits(); + + if (!VT || VT->getNumElements() != NumInits) + return APValue(); + + QualType EltTy = VT->getElementType(); + llvm::SmallVector<APValue, 4> Elements; + + for (unsigned i = 0; i < NumInits; i++) { + if (EltTy->isIntegerType()) { + llvm::APSInt sInt(32); + if (!EvaluateInteger(E->getInit(i), sInt, Info)) + return APValue(); + Elements.push_back(APValue(sInt)); + } else { + llvm::APFloat f(0.0); + if (!EvaluateFloat(E->getInit(i), f, Info)) + return APValue(); + Elements.push_back(APValue(f)); + } + } + return APValue(&Elements[0], Elements.size()); +} + +//===----------------------------------------------------------------------===// // Integer Evaluation //===----------------------------------------------------------------------===// @@ -1067,6 +1139,7 @@ bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) { Expr* SubExpr = E->getSubExpr(); + const llvm::fltSemantics& destSemantics = Info.Ctx.getFloatTypeSemantics(E->getType()); if (SubExpr->getType()->isIntegralType()) { @@ -1189,7 +1262,10 @@ APValue ComplexFloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const { EvalInfo Info(Ctx, Result); - if (getType()->isIntegerType()) { + if (getType()->isVectorType()) { + if (!EvaluateVector(this, Result.Val, Info)) + return false; + } else if (getType()->isIntegerType()) { llvm::APSInt sInt(32); if (!EvaluateInteger(this, sInt, Info)) return false; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 82c8ea099d..cff01c6530 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2187,11 +2187,9 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { } bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) { - Expr::EvalResult Result; - Init = Init->IgnoreParens(); - if (Init->Evaluate(Result, Context) && !Result.HasSideEffects) + if (Init->isEvaluatable(Context)) return false; // Look through CXXDefaultArgExprs; they have no meaning in this context. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 7d08132cd6..2bc6ff2f12 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2925,13 +2925,14 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex, return lType; const VectorType *VTy = lType->getAsVectorType(); - - // FIXME: need to deal with non-32b int / non-64b long long unsigned TypeSize = Context.getTypeSize(VTy->getElementType()); - if (TypeSize == 32) { + if (TypeSize == Context.getTypeSize(Context.IntTy)) return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); - } - assert(TypeSize == 64 && "Unhandled vector element size in vector compare"); + else if (TypeSize == Context.getTypeSize(Context.LongTy)) + return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); + + assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && + "Unhandled vector element size in vector compare"); return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); } diff --git a/test/CodeGen/ext-vector.c b/test/CodeGen/ext-vector.c index ae877edb81..0a57397d7c 100644 --- a/test/CodeGen/ext-vector.c +++ b/test/CodeGen/ext-vector.c @@ -6,6 +6,8 @@ typedef __attribute__(( ext_vector_type(4) )) int int4; float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 }; +const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() }; + float4 test1(float4 V) { return V.wzyx+V; } |