From 3d309f9d62a6f9f634b869937139d533ccd7265b Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Sun, 18 Jan 2009 01:01:34 +0000 Subject: [PATCH] Add support for vectors to APValue. Vector constant evaluator and tests coming. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62438 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/APValue.h | 33 ++++++++++++++++++++++++++++++++- lib/AST/APValue.cpp | 10 ++++++++++ lib/CodeGen/CGExprConstant.cpp | 13 +++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index 48a9bf1a6e..8fbb04e975 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -32,7 +32,8 @@ public: Float, ComplexInt, ComplexFloat, - LValue + LValue, + Vector }; private: ValueKind Kind; @@ -50,6 +51,11 @@ private: Expr* Base; uint64_t Offset; }; + struct Vec { + APValue *Elts; + unsigned NumElts; + ~Vec() { delete[] Elts; } + }; enum { MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ? @@ -68,6 +74,9 @@ public: explicit APValue(const APFloat &F) : Kind(Uninitialized) { MakeFloat(); setFloat(F); } + explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { + MakeVector(); setVector(E, N); + } APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) { MakeComplexInt(); setComplexInt(R, I); } @@ -91,6 +100,7 @@ public: bool isComplexInt() const { return Kind == ComplexInt; } bool isComplexFloat() const { return Kind == ComplexFloat; } bool isLValue() const { return Kind == LValue; } + bool isVector() const { return Kind == Vector; } void print(llvm::raw_ostream &OS) const; void dump() const; @@ -111,6 +121,15 @@ public: return const_cast(this)->getFloat(); } + APValue &getVectorElt(unsigned i) const { + assert(isVector() && "Invalid accessor"); + return ((Vec*)(void*)Data)->Elts[i]; + } + unsigned getVectorLength() const { + assert(isVector() && "Invalid accessor"); + return ((Vec*)(void *)Data)->NumElts; + } + APSInt &getComplexIntReal() { assert(isComplexInt() && "Invalid accessor"); return ((ComplexAPSInt*)(void*)Data)->Real; @@ -160,6 +179,13 @@ public: assert(isFloat() && "Invalid accessor"); *(APFloat*)(void*)Data = F; } + void setVector(const APValue *E, unsigned N) { + assert(isVector() && "Invalid accessor"); + ((Vec*)(void*)Data)->Elts = new APValue[N]; + ((Vec*)(void*)Data)->NumElts = N; + for (unsigned i = 0; i != N; ++i) + ((Vec*)(void*)Data)->Elts[i] = E[i]; + } void setComplexInt(const APSInt &R, const APSInt &I) { assert(isComplexInt() && "Invalid accessor"); ((ComplexAPSInt*)(void*)Data)->Real = R; @@ -190,6 +216,11 @@ private: new ((APFloat*)(void*)Data) APFloat(0.0); Kind = Float; } + void MakeVector() { + assert(isUninit() && "Bad state change"); + new ((Vec*)(void*)Data) Vec(); + Kind = Vector; + } void MakeComplexInt() { assert(isUninit() && "Bad state change"); new ((ComplexAPSInt*)(void*)Data) ComplexAPSInt(); diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index 38a89aa99e..87d9fc3442 100644 --- a/lib/AST/APValue.cpp +++ b/lib/AST/APValue.cpp @@ -23,6 +23,8 @@ const APValue &APValue::operator=(const APValue &RHS) { MakeInt(); else if (RHS.isFloat()) MakeFloat(); + else if (RHS.isVector()) + MakeVector(); else if (RHS.isComplexInt()) MakeComplexInt(); else if (RHS.isComplexFloat()) @@ -34,6 +36,8 @@ const APValue &APValue::operator=(const APValue &RHS) { setInt(RHS.getInt()); else if (isFloat()) setFloat(RHS.getFloat()); + else if (isVector()) + setVector(((Vec*)(void*)RHS.Data)->Elts, RHS.getVectorLength()); else if (isComplexInt()) setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); else if (isComplexFloat()) @@ -48,6 +52,8 @@ void APValue::MakeUninit() { ((APSInt*)(void*)Data)->~APSInt(); else if (Kind == Float) ((APFloat*)(void*)Data)->~APFloat(); + else if (Kind == Vector) + ((Vec*)(void*)Data)->~Vec(); else if (Kind == ComplexInt) ((ComplexAPSInt*)(void*)Data)->~ComplexAPSInt(); else if (Kind == ComplexFloat) @@ -55,6 +61,7 @@ void APValue::MakeUninit() { else if (Kind == LValue) { ((LV*)(void*)Data)->~LV(); } + Kind = Uninitialized; } void APValue::dump() const { @@ -83,6 +90,9 @@ void APValue::print(llvm::raw_ostream &OS) const { case Float: OS << "Float: " << GetApproxValue(getFloat()); return; + case Vector: + OS << "Vector: "; + return; case ComplexInt: OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); return; diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 72674f77fb..b7c4f7fd39 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -697,6 +697,19 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, return llvm::ConstantStruct::get(Complex, 2); } + case APValue::Vector: { + llvm::SmallVector Inits; + unsigned NumElts = Result.Val.getVectorLength(); + + for (unsigned i = 0; i != NumElts; ++i) { + APValue &Elt = Result.Val.getVectorElt(i); + if (Elt.isInt()) + Inits.push_back(llvm::ConstantInt::get(Elt.getInt())); + else + Inits.push_back(llvm::ConstantFP::get(Elt.getFloat())); + } + return llvm::ConstantVector::get(&Inits[0], Inits.size()); + } } } -- 2.40.0