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:
parent
e4383379ae
commit
2d4063412c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
Loading…
Reference in New Issue