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
This commit is contained in:
Richard Smith 2011-10-22 21:10:00 +00:00
parent e4383379ae
commit 2d4063412c
1 changed files with 56 additions and 47 deletions

View File

@ -790,23 +790,32 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
namespace { namespace {
class VectorExprEvaluator class VectorExprEvaluator
: public ExprEvaluatorBase<VectorExprEvaluator, APValue> { : public ExprEvaluatorBase<VectorExprEvaluator, bool> {
APValue GetZeroVector(QualType VecType); APValue &Result;
public: 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; } bool Success(const ArrayRef<APValue> &V, const Expr *E) {
APValue Error(const Expr *E) { return APValue(); } assert(V.size() == E->getType()->castAs<VectorType>()->getNumElements());
APValue ValueInitialization(const Expr *E) // FIXME: remove this APValue copy.
{ return GetZeroVector(E->getType()); } 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()); } { return Visit(E->getSubExpr()); }
APValue VisitCastExpr(const CastExpr* E); bool VisitCastExpr(const CastExpr* E);
APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
APValue VisitInitListExpr(const InitListExpr *E); bool VisitInitListExpr(const InitListExpr *E);
APValue VisitUnaryImag(const UnaryOperator *E); bool VisitUnaryImag(const UnaryOperator *E);
// FIXME: Missing: unary -, unary ~, binary add/sub/mul/div, // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div,
// binary comparisons, binary and/or/xor, // binary comparisons, binary and/or/xor,
// shufflevector, ExtVectorElementExpr // shufflevector, ExtVectorElementExpr
@ -818,12 +827,11 @@ namespace {
static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
if (!E->getType()->isVectorType()) if (!E->getType()->isVectorType())
return false; return false;
Result = VectorExprEvaluator(Info).Visit(E); return VectorExprEvaluator(Info, Result).Visit(E);
return !Result.isUninit();
} }
APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
const VectorType *VTy = E->getType()->getAs<VectorType>(); const VectorType *VTy = E->getType()->castAs<VectorType>();
QualType EltTy = VTy->getElementType(); QualType EltTy = VTy->getElementType();
unsigned NElts = VTy->getNumElements(); unsigned NElts = VTy->getNumElements();
unsigned EltWidth = Info.Ctx.getTypeSize(EltTy); unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
@ -833,35 +841,36 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
switch (E->getCastKind()) { switch (E->getCastKind()) {
case CK_VectorSplat: { case CK_VectorSplat: {
APValue Result = APValue(); APValue Val = APValue();
if (SETy->isIntegerType()) { if (SETy->isIntegerType()) {
APSInt IntResult; APSInt IntResult;
if (!EvaluateInteger(SE, IntResult, Info)) if (!EvaluateInteger(SE, IntResult, Info))
return APValue(); return Error(E);
Result = APValue(IntResult); Val = APValue(IntResult);
} else if (SETy->isRealFloatingType()) { } else if (SETy->isRealFloatingType()) {
APFloat F(0.0); APFloat F(0.0);
if (!EvaluateFloat(SE, F, Info)) if (!EvaluateFloat(SE, F, Info))
return APValue(); return Error(E);
Result = APValue(F); Val = APValue(F);
} else { } else {
return APValue(); return Error(E);
} }
// Splat and create vector APValue. // Splat and create vector APValue.
SmallVector<APValue, 4> Elts(NElts, Result); SmallVector<APValue, 4> Elts(NElts, Val);
return APValue(&Elts[0], Elts.size()); return Success(Elts, E);
} }
case CK_BitCast: { case CK_BitCast: {
// FIXME: this is wrong for any cast other than a no-op cast.
if (SETy->isVectorType()) if (SETy->isVectorType())
return Visit(SE); return Visit(SE);
if (!SETy->isIntegerType()) if (!SETy->isIntegerType())
return APValue(); return Error(E);
APSInt Init; APSInt Init;
if (!EvaluateInteger(SE, Init, Info)) if (!EvaluateInteger(SE, Init, Info))
return APValue(); return Error(E);
assert((EltTy->isIntegerType() || EltTy->isRealFloatingType()) && assert((EltTy->isIntegerType() || EltTy->isRealFloatingType()) &&
"Vectors must be composed of ints or floats"); "Vectors must be composed of ints or floats");
@ -877,24 +886,24 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
Init >>= EltWidth; Init >>= EltWidth;
} }
return APValue(&Elts[0], Elts.size()); return Success(Elts, E);
} }
case CK_LValueToRValue: case CK_LValueToRValue:
case CK_NoOp: case CK_NoOp:
return Visit(SE); return Visit(SE);
default: default:
return APValue(); return Error(E);
} }
} }
APValue bool
VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
return this->Visit(E->getInitializer()); return Visit(E->getInitializer());
} }
APValue bool
VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
const VectorType *VT = E->getType()->getAs<VectorType>(); const VectorType *VT = E->getType()->castAs<VectorType>();
unsigned NumInits = E->getNumInits(); unsigned NumInits = E->getNumInits();
unsigned NumElements = VT->getNumElements(); unsigned NumElements = VT->getNumElements();
@ -905,22 +914,22 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
// becomes every element of the vector, not just the first. // becomes every element of the vector, not just the first.
// This is the behavior described in the IBM AltiVec documentation. // This is the behavior described in the IBM AltiVec documentation.
if (NumInits == 1) { 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). // vector (OpenCL 6.1.6).
if (E->getInit(0)->getType()->isVectorType()) if (E->getInit(0)->getType()->isVectorType())
return this->Visit(const_cast<Expr*>(E->getInit(0))); return Visit(E->getInit(0));
APValue InitValue; APValue InitValue;
if (EltTy->isIntegerType()) { if (EltTy->isIntegerType()) {
llvm::APSInt sInt(32); llvm::APSInt sInt(32);
if (!EvaluateInteger(E->getInit(0), sInt, Info)) if (!EvaluateInteger(E->getInit(0), sInt, Info))
return APValue(); return Error(E);
InitValue = APValue(sInt); InitValue = APValue(sInt);
} else { } else {
llvm::APFloat f(0.0); llvm::APFloat f(0.0);
if (!EvaluateFloat(E->getInit(0), f, Info)) if (!EvaluateFloat(E->getInit(0), f, Info))
return APValue(); return Error(E);
InitValue = APValue(f); InitValue = APValue(f);
} }
for (unsigned i = 0; i < NumElements; i++) { for (unsigned i = 0; i < NumElements; i++) {
@ -932,7 +941,7 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
llvm::APSInt sInt(32); llvm::APSInt sInt(32);
if (i < NumInits) { if (i < NumInits) {
if (!EvaluateInteger(E->getInit(i), sInt, Info)) if (!EvaluateInteger(E->getInit(i), sInt, Info))
return APValue(); return Error(E);
} else { } else {
sInt = Info.Ctx.MakeIntValue(0, EltTy); sInt = Info.Ctx.MakeIntValue(0, EltTy);
} }
@ -941,7 +950,7 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
llvm::APFloat f(0.0); llvm::APFloat f(0.0);
if (i < NumInits) { if (i < NumInits) {
if (!EvaluateFloat(E->getInit(i), f, Info)) if (!EvaluateFloat(E->getInit(i), f, Info))
return APValue(); return Error(E);
} else { } else {
f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)); 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 bool
VectorExprEvaluator::GetZeroVector(QualType T) { VectorExprEvaluator::ValueInitialization(const Expr *E) {
const VectorType *VT = T->getAs<VectorType>(); const VectorType *VT = E->getType()->getAs<VectorType>();
QualType EltTy = VT->getElementType(); QualType EltTy = VT->getElementType();
APValue ZeroElement; APValue ZeroElement;
if (EltTy->isIntegerType()) if (EltTy->isIntegerType())
@ -964,14 +973,14 @@ VectorExprEvaluator::GetZeroVector(QualType T) {
APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy))); APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
SmallVector<APValue, 4> Elements(VT->getNumElements(), ZeroElement); 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; APValue Scratch;
if (!Evaluate(Scratch, Info, E->getSubExpr())) if (!Evaluate(Scratch, Info, E->getSubExpr()))
Info.EvalStatus.HasSideEffects = true; Info.EvalStatus.HasSideEffects = true;
return GetZeroVector(E->getType()); return ValueInitialization(E);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//