r351368 - [Fixed Point Arithmetic] Add APFixedPoint to APValue

Leonard Chan via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 16 10:53:05 PST 2019


Author: leonardchan
Date: Wed Jan 16 10:53:05 2019
New Revision: 351368

URL: http://llvm.org/viewvc/llvm-project?rev=351368&view=rev
Log:
[Fixed Point Arithmetic] Add APFixedPoint to APValue

This adds APFixedPoint to the union of values that can be represented with an APValue.

Differential Revision: https://reviews.llvm.org/D56746

Modified:
    cfe/trunk/include/clang/AST/APValue.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Basic/FixedPoint.h
    cfe/trunk/lib/AST/APValue.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Basic/FixedPoint.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/APValue.h (original)
+++ cfe/trunk/include/clang/AST/APValue.h Wed Jan 16 10:53:05 2019
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_APVALUE_H
 #define LLVM_CLANG_AST_APVALUE_H
 
+#include "clang/Basic/FixedPoint.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APSInt.h"
@@ -43,6 +44,7 @@ public:
     Uninitialized,
     Int,
     Float,
+    FixedPoint,
     ComplexInt,
     ComplexFloat,
     LValue,
@@ -175,6 +177,9 @@ public:
   explicit APValue(APFloat F) : Kind(Uninitialized) {
     MakeFloat(); setFloat(std::move(F));
   }
+  explicit APValue(APFixedPoint FX) : Kind(Uninitialized) {
+    MakeFixedPoint(std::move(FX));
+  }
   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
     MakeVector(); setVector(E, N);
   }
@@ -233,6 +238,7 @@ public:
   bool isUninit() const { return Kind == Uninitialized; }
   bool isInt() const { return Kind == Int; }
   bool isFloat() const { return Kind == Float; }
+  bool isFixedPoint() const { return Kind == FixedPoint; }
   bool isComplexInt() const { return Kind == ComplexInt; }
   bool isComplexFloat() const { return Kind == ComplexFloat; }
   bool isLValue() const { return Kind == LValue; }
@@ -265,6 +271,14 @@ public:
     return const_cast<APValue*>(this)->getFloat();
   }
 
+  APFixedPoint &getFixedPoint() {
+    assert(isFixedPoint() && "Invalid accessor");
+    return *(APFixedPoint *)(char *)Data.buffer;
+  }
+  const APFixedPoint &getFixedPoint() const {
+    return const_cast<APValue *>(this)->getFixedPoint();
+  }
+
   APSInt &getComplexIntReal() {
     assert(isComplexInt() && "Invalid accessor");
     return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
@@ -406,6 +420,10 @@ public:
     assert(isFloat() && "Invalid accessor");
     *(APFloat *)(char *)Data.buffer = std::move(F);
   }
+  void setFixedPoint(APFixedPoint FX) {
+    assert(isFixedPoint() && "Invalid accessor");
+    *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
+  }
   void setVector(const APValue *E, unsigned N) {
     assert(isVector() && "Invalid accessor");
     ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
@@ -465,6 +483,11 @@ private:
     new ((void*)(char*)Data.buffer) APFloat(0.0);
     Kind = Float;
   }
+  void MakeFixedPoint(APFixedPoint &&FX) {
+    assert(isUninit() && "Bad state change");
+    new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
+    Kind = FixedPoint;
+  }
   void MakeVector() {
     assert(isUninit() && "Bad state change");
     new ((void*)(char*)Data.buffer) Vec();

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jan 16 10:53:05 2019
@@ -6848,6 +6848,8 @@ QualType DecayedType::getPointeeType() c
 
 // Get the decimal string representation of a fixed point type, represented
 // as a scaled integer.
+// TODO: At some point, we should change the arguments to instead just accept an
+// APFixedPoint instead of APSInt and scale.
 void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val,
                              unsigned Scale);
 

Modified: cfe/trunk/include/clang/Basic/FixedPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FixedPoint.h?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/FixedPoint.h (original)
+++ cfe/trunk/include/clang/Basic/FixedPoint.h Wed Jan 16 10:53:05 2019
@@ -18,6 +18,7 @@
 #define LLVM_CLANG_BASIC_FIXEDPOINT_H
 
 #include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
@@ -104,19 +105,25 @@ class APFixedPoint {
        : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()),
                       Sema) {}
 
+   // Zero initialization.
+   APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
+
    llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); }
    inline unsigned getWidth() const { return Sema.getWidth(); }
    inline unsigned getScale() const { return Sema.getScale(); }
    inline bool isSaturated() const { return Sema.isSaturated(); }
    inline bool isSigned() const { return Sema.isSigned(); }
    inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
+   FixedPointSemantics getSemantics() const { return Sema; }
+
+   bool getBoolValue() const { return Val.getBoolValue(); }
 
    // Convert this number to match the semantics provided.
    APFixedPoint convert(const FixedPointSemantics &DstSema) const;
 
    APFixedPoint shr(unsigned Amt) const {
      return APFixedPoint(Val >> Amt, Sema);
-  }
+   }
 
   APFixedPoint shl(unsigned Amt) const {
     return APFixedPoint(Val << Amt, Sema);
@@ -129,6 +136,13 @@ class APFixedPoint {
       return Val >> getScale();
   }
 
+  void toString(llvm::SmallVectorImpl<char> &Str) const;
+  std::string toString() const {
+    llvm::SmallString<40> S;
+    toString(S);
+    return S.str();
+  }
+
   // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
   int compare(const APFixedPoint &Other) const;
   bool operator==(const APFixedPoint &Other) const {
@@ -154,6 +168,12 @@ private:
   FixedPointSemantics Sema;
 };
 
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     const APFixedPoint &FX) {
+  OS << FX.toString();
+  return OS;
+}
+
 }  // namespace clang
 
 #endif

Modified: cfe/trunk/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/APValue.cpp?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/lib/AST/APValue.cpp (original)
+++ cfe/trunk/lib/AST/APValue.cpp Wed Jan 16 10:53:05 2019
@@ -176,6 +176,11 @@ APValue::APValue(const APValue &RHS) : K
     MakeFloat();
     setFloat(RHS.getFloat());
     break;
+  case FixedPoint: {
+    APFixedPoint FXCopy = RHS.getFixedPoint();
+    MakeFixedPoint(std::move(FXCopy));
+    break;
+  }
   case Vector:
     MakeVector();
     setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
@@ -233,6 +238,8 @@ void APValue::DestroyDataAndMakeUninit()
     ((APSInt*)(char*)Data.buffer)->~APSInt();
   else if (Kind == Float)
     ((APFloat*)(char*)Data.buffer)->~APFloat();
+  else if (Kind == FixedPoint)
+    ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
   else if (Kind == Vector)
     ((Vec*)(char*)Data.buffer)->~Vec();
   else if (Kind == ComplexInt)
@@ -268,6 +275,8 @@ bool APValue::needsCleanup() const {
     return getInt().needsCleanup();
   case Float:
     return getFloat().needsCleanup();
+  case FixedPoint:
+    return getFixedPoint().getValue().needsCleanup();
   case ComplexFloat:
     assert(getComplexFloatImag().needsCleanup() ==
                getComplexFloatReal().needsCleanup() &&
@@ -321,6 +330,9 @@ void APValue::dump(raw_ostream &OS) cons
   case Float:
     OS << "Float: " << GetApproxValue(getFloat());
     return;
+  case FixedPoint:
+    OS << "FixedPoint : " << getFixedPoint();
+    return;
   case Vector:
     OS << "Vector: ";
     getVectorElt(0).dump(OS);
@@ -397,6 +409,9 @@ void APValue::printPretty(raw_ostream &O
   case APValue::Float:
     Out << GetApproxValue(getFloat());
     return;
+  case APValue::FixedPoint:
+    Out << getFixedPoint();
+    return;
   case APValue::Vector: {
     Out << '{';
     QualType ElemTy = Ty->getAs<VectorType>()->getElementType();

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Jan 16 10:53:05 2019
@@ -2027,6 +2027,9 @@ static bool HandleConversionToBool(const
   case APValue::Int:
     Result = Val.getInt().getBoolValue();
     return true;
+  case APValue::FixedPoint:
+    Result = Val.getFixedPoint().getBoolValue();
+    return true;
   case APValue::Float:
     Result = !Val.getFloat().isZero();
     return true;

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Jan 16 10:53:05 2019
@@ -4016,25 +4016,8 @@ CXXRecordDecl *MemberPointerType::getMos
 
 void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
                                     llvm::APSInt Val, unsigned Scale) {
-  if (Val.isSigned() && Val.isNegative() && Val != -Val) {
-    Val = -Val;
-    Str.push_back('-');
-  }
-
-  llvm::APSInt IntPart = Val >> Scale;
-
-  // Add 4 digits to hold the value after multiplying 10 (the radix)
-  unsigned Width = Val.getBitWidth() + 4;
-  llvm::APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
-  llvm::APInt FractPartMask = llvm::APInt::getAllOnesValue(Scale).zext(Width);
-  llvm::APInt RadixInt = llvm::APInt(Width, 10);
-
-  IntPart.toString(Str, /*radix=*/10);
-  Str.push_back('.');
-  do {
-    (FractPart * RadixInt)
-        .lshr(Scale)
-        .toString(Str, /*radix=*/10, Val.isSigned());
-    FractPart = (FractPart * RadixInt) & FractPartMask;
-  } while (FractPart != 0);
+  FixedPointSemantics FXSema(Val.getBitWidth(), Scale, Val.isSigned(),
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+  APFixedPoint(Val, FXSema).toString(Str);
 }

Modified: cfe/trunk/lib/Basic/FixedPoint.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FixedPoint.cpp?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/FixedPoint.cpp (original)
+++ cfe/trunk/lib/Basic/FixedPoint.cpp Wed Jan 16 10:53:05 2019
@@ -137,4 +137,31 @@ FixedPointSemantics FixedPointSemantics:
                              ResultIsSaturated, ResultHasUnsignedPadding);
 }
 
+void APFixedPoint::toString(llvm::SmallVectorImpl<char> &Str) const {
+  llvm::APSInt Val = getValue();
+  unsigned Scale = getScale();
+
+  if (Val.isSigned() && Val.isNegative() && Val != -Val) {
+    Val = -Val;
+    Str.push_back('-');
+  }
+
+  llvm::APSInt IntPart = Val >> Scale;
+
+  // Add 4 digits to hold the value after multiplying 10 (the radix)
+  unsigned Width = Val.getBitWidth() + 4;
+  llvm::APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
+  llvm::APInt FractPartMask = llvm::APInt::getAllOnesValue(Scale).zext(Width);
+  llvm::APInt RadixInt = llvm::APInt(Width, 10);
+
+  IntPart.toString(Str, /*radix=*/10);
+  Str.push_back('.');
+  do {
+    (FractPart * RadixInt)
+        .lshr(Scale)
+        .toString(Str, /*radix=*/10, Val.isSigned());
+    FractPart = (FractPart * RadixInt) & FractPartMask;
+  } while (FractPart != 0);
+}
+
 }  // namespace clang

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Jan 16 10:53:05 2019
@@ -1873,6 +1873,9 @@ llvm::Constant *ConstantEmitter::tryEmit
     return ConstantLValueEmitter(*this, Value, DestType).tryEmit();
   case APValue::Int:
     return llvm::ConstantInt::get(CGM.getLLVMContext(), Value.getInt());
+  case APValue::FixedPoint:
+    return llvm::ConstantInt::get(CGM.getLLVMContext(),
+                                  Value.getFixedPoint().getValue());
   case APValue::ComplexInt: {
     llvm::Constant *Complex[2];
 

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=351368&r1=351367&r2=351368&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jan 16 10:53:05 2019
@@ -6342,6 +6342,7 @@ ExprResult Sema::CheckTemplateArgument(N
     }
     case APValue::AddrLabelDiff:
       return Diag(StartLoc, diag::err_non_type_template_arg_addr_label_diff);
+    case APValue::FixedPoint:
     case APValue::Float:
     case APValue::ComplexInt:
     case APValue::ComplexFloat:




More information about the cfe-commits mailing list