From 2d4063412c8a7934db3a015db97df8c7881a74cd Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 22 Oct 2011 21:10:00 +0000 Subject: [PATCH] Refactor vector constant expression evaluation to return bool like all the other const expression evaluation subclasses, and remove some APValue copying and malloc traffic in the process. llvm-svn: 142733 --- clang/lib/AST/ExprConstant.cpp | 103 ++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c3cc78e053cc..f108c1a30ebc 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -790,23 +790,32 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) { namespace { class VectorExprEvaluator - : public ExprEvaluatorBase { - APValue GetZeroVector(QualType VecType); + : public ExprEvaluatorBase { + APValue &Result; public: - VectorExprEvaluator(EvalInfo &info) : ExprEvaluatorBaseTy(info) {} + VectorExprEvaluator(EvalInfo &info, APValue &Result) + : ExprEvaluatorBaseTy(info), Result(Result) {} - APValue Success(const APValue &V, const Expr *E) { return V; } - APValue Error(const Expr *E) { return APValue(); } - APValue ValueInitialization(const Expr *E) - { return GetZeroVector(E->getType()); } + bool Success(const ArrayRef &V, const Expr *E) { + assert(V.size() == E->getType()->castAs()->getNumElements()); + // FIXME: remove this APValue copy. + Result = APValue(V.data(), V.size()); + return true; + } + bool Success(const APValue &V, const Expr *E) { + Result = V; + return true; + } + bool Error(const Expr *E) { return false; } + bool ValueInitialization(const Expr *E); - APValue VisitUnaryReal(const UnaryOperator *E) + bool VisitUnaryReal(const UnaryOperator *E) { return Visit(E->getSubExpr()); } - APValue VisitCastExpr(const CastExpr* E); - APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); - APValue VisitInitListExpr(const InitListExpr *E); - APValue VisitUnaryImag(const UnaryOperator *E); + bool VisitCastExpr(const CastExpr* E); + bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); + bool VisitInitListExpr(const InitListExpr *E); + bool VisitUnaryImag(const UnaryOperator *E); // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div, // binary comparisons, binary and/or/xor, // shufflevector, ExtVectorElementExpr @@ -818,12 +827,11 @@ namespace { static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { if (!E->getType()->isVectorType()) return false; - Result = VectorExprEvaluator(Info).Visit(E); - return !Result.isUninit(); + return VectorExprEvaluator(Info, Result).Visit(E); } -APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { - const VectorType *VTy = E->getType()->getAs(); +bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { + const VectorType *VTy = E->getType()->castAs(); QualType EltTy = VTy->getElementType(); unsigned NElts = VTy->getNumElements(); unsigned EltWidth = Info.Ctx.getTypeSize(EltTy); @@ -833,35 +841,36 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { switch (E->getCastKind()) { case CK_VectorSplat: { - APValue Result = APValue(); + APValue Val = APValue(); if (SETy->isIntegerType()) { APSInt IntResult; if (!EvaluateInteger(SE, IntResult, Info)) - return APValue(); - Result = APValue(IntResult); + return Error(E); + Val = APValue(IntResult); } else if (SETy->isRealFloatingType()) { APFloat F(0.0); if (!EvaluateFloat(SE, F, Info)) - return APValue(); - Result = APValue(F); + return Error(E); + Val = APValue(F); } else { - return APValue(); + return Error(E); } // Splat and create vector APValue. - SmallVector Elts(NElts, Result); - return APValue(&Elts[0], Elts.size()); + SmallVector Elts(NElts, Val); + return Success(Elts, E); } case CK_BitCast: { + // FIXME: this is wrong for any cast other than a no-op cast. if (SETy->isVectorType()) return Visit(SE); if (!SETy->isIntegerType()) - return APValue(); + return Error(E); APSInt Init; if (!EvaluateInteger(SE, Init, Info)) - return APValue(); + return Error(E); assert((EltTy->isIntegerType() || EltTy->isRealFloatingType()) && "Vectors must be composed of ints or floats"); @@ -877,24 +886,24 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { Init >>= EltWidth; } - return APValue(&Elts[0], Elts.size()); + return Success(Elts, E); } case CK_LValueToRValue: case CK_NoOp: return Visit(SE); default: - return APValue(); + return Error(E); } } -APValue +bool VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { - return this->Visit(E->getInitializer()); + return Visit(E->getInitializer()); } -APValue +bool VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { - const VectorType *VT = E->getType()->getAs(); + const VectorType *VT = E->getType()->castAs(); unsigned NumInits = E->getNumInits(); unsigned NumElements = VT->getNumElements(); @@ -905,22 +914,22 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { // becomes every element of the vector, not just the first. // This is the behavior described in the IBM AltiVec documentation. if (NumInits == 1) { - - // Handle the case where the vector is initialized by a another + + // Handle the case where the vector is initialized by another // vector (OpenCL 6.1.6). if (E->getInit(0)->getType()->isVectorType()) - return this->Visit(const_cast(E->getInit(0))); - + return Visit(E->getInit(0)); + APValue InitValue; if (EltTy->isIntegerType()) { llvm::APSInt sInt(32); if (!EvaluateInteger(E->getInit(0), sInt, Info)) - return APValue(); + return Error(E); InitValue = APValue(sInt); } else { llvm::APFloat f(0.0); if (!EvaluateFloat(E->getInit(0), f, Info)) - return APValue(); + return Error(E); InitValue = APValue(f); } for (unsigned i = 0; i < NumElements; i++) { @@ -932,7 +941,7 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { llvm::APSInt sInt(32); if (i < NumInits) { if (!EvaluateInteger(E->getInit(i), sInt, Info)) - return APValue(); + return Error(E); } else { sInt = Info.Ctx.MakeIntValue(0, EltTy); } @@ -941,7 +950,7 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { llvm::APFloat f(0.0); if (i < NumInits) { if (!EvaluateFloat(E->getInit(i), f, Info)) - return APValue(); + return Error(E); } else { f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)); } @@ -949,12 +958,12 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { } } } - return APValue(&Elements[0], Elements.size()); + return Success(Elements, E); } -APValue -VectorExprEvaluator::GetZeroVector(QualType T) { - const VectorType *VT = T->getAs(); +bool +VectorExprEvaluator::ValueInitialization(const Expr *E) { + const VectorType *VT = E->getType()->getAs(); QualType EltTy = VT->getElementType(); APValue ZeroElement; if (EltTy->isIntegerType()) @@ -964,14 +973,14 @@ VectorExprEvaluator::GetZeroVector(QualType T) { APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy))); SmallVector Elements(VT->getNumElements(), ZeroElement); - return APValue(&Elements[0], Elements.size()); + return Success(Elements, E); } -APValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { +bool VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { APValue Scratch; if (!Evaluate(Scratch, Info, E->getSubExpr())) Info.EvalStatus.HasSideEffects = true; - return GetZeroVector(E->getType()); + return ValueInitialization(E); } //===----------------------------------------------------------------------===//