aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-10-22 21:10:00 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-10-22 21:10:00 +0000
commit07fc657e3077531805b0e2dbf8f8964d48daa38b (patch)
tree6cee988efbfb57c1d97b8683543f95f54c0ae197 /lib/AST/ExprConstant.cpp
parentf5c7504d046efe5bda36451e3a5719e726be4476 (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.cpp103
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);
}
//===----------------------------------------------------------------------===//