diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-22 21:10:00 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-22 21:10:00 +0000 |
commit | 07fc657e3077531805b0e2dbf8f8964d48daa38b (patch) | |
tree | 6cee988efbfb57c1d97b8683543f95f54c0ae197 /lib/AST/ExprConstant.cpp | |
parent | f5c7504d046efe5bda36451e3a5719e726be4476 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142733 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 103 |
1 files changed, 56 insertions, 47 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index c3cc78e053..f108c1a30e 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -790,23 +790,32 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) { namespace { class VectorExprEvaluator - : public ExprEvaluatorBase<VectorExprEvaluator, APValue> { - APValue GetZeroVector(QualType VecType); + : public ExprEvaluatorBase<VectorExprEvaluator, bool> { + 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<APValue> &V, const Expr *E) { + assert(V.size() == E->getType()->castAs<VectorType>()->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<VectorType>(); +bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { + const VectorType *VTy = E->getType()->castAs<VectorType>(); 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<APValue, 4> Elts(NElts, Result); - return APValue(&Elts[0], Elts.size()); + SmallVector<APValue, 4> 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<VectorType>(); + const VectorType *VT = E->getType()->castAs<VectorType>(); 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<Expr*>(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<VectorType>(); +bool +VectorExprEvaluator::ValueInitialization(const Expr *E) { + const VectorType *VT = E->getType()->getAs<VectorType>(); 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<APValue, 4> 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); } //===----------------------------------------------------------------------===// |