[llvm] r308112 - [IR] Implement Constant::isNegativeZeroValue/isZeroValue/isAllOnesValue/isOneValue/isMinSignedValue for ConstantDataVector without going through getElementAsConstant
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 15 15:06:19 PDT 2017
Author: ctopper
Date: Sat Jul 15 15:06:19 2017
New Revision: 308112
URL: http://llvm.org/viewvc/llvm-project?rev=308112&view=rev
Log:
[IR] Implement Constant::isNegativeZeroValue/isZeroValue/isAllOnesValue/isOneValue/isMinSignedValue for ConstantDataVector without going through getElementAsConstant
Summary:
Currently these methods call ConstantDataVector::getSplatValue which uses getElementsAsConstant to create a Constant object representing the element value. This method incurs a map lookup to see if we already have created such a Constant before and if not allocates a new Constant object.
This patch changes these methods to use getElementAsAPFloat and getElementAsInteger so we can just examine the data values directly.
Reviewers: spatel, pcc, dexonsmith, bogner, craig.topper
Reviewed By: craig.topper
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D35040
Modified:
llvm/trunk/include/llvm/IR/Constants.h
llvm/trunk/lib/IR/Constants.cpp
Modified: llvm/trunk/include/llvm/IR/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constants.h?rev=308112&r1=308111&r2=308112&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Constants.h (original)
+++ llvm/trunk/include/llvm/IR/Constants.h Sat Jul 15 15:06:19 2017
@@ -598,6 +598,10 @@ public:
/// specified element in the low bits of a uint64_t.
uint64_t getElementAsInteger(unsigned i) const;
+ /// If this is a sequential container of integers (of any size), return the
+ /// specified element as an APInt.
+ APInt getElementAsAPInt(unsigned i) const;
+
/// If this is a sequential container of floating point type, return the
/// specified element as an APFloat.
APFloat getElementAsAPFloat(unsigned i) const;
@@ -761,6 +765,10 @@ public:
/// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
static Constant *getSplat(unsigned NumElts, Constant *Elt);
+ /// Returns true if this is a splat constant, meaning that all elements have
+ /// the same value.
+ bool isSplat() const;
+
/// If this is a splat constant, meaning that all of the elements have the
/// same value, return that value. Otherwise return NULL.
Constant *getSplatValue() const;
Modified: llvm/trunk/lib/IR/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=308112&r1=308111&r2=308112&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Constants.cpp (original)
+++ llvm/trunk/lib/IR/Constants.cpp Sat Jul 15 15:06:19 2017
@@ -44,8 +44,8 @@ bool Constant::isNegativeZeroValue() con
// Equivalent for a vector of -0.0's.
if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
- if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
- if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative())
+ if (CV->getElementType()->isFloatingPointTy() && CV->isSplat())
+ if (CV->getElementAsAPFloat(0).isNegZero())
return true;
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
@@ -70,8 +70,8 @@ bool Constant::isZeroValue() const {
// Equivalent for a vector of -0.0's.
if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
- if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
- if (SplatCFP && SplatCFP->isZero())
+ if (CV->getElementType()->isFloatingPointTy() && CV->isSplat())
+ if (CV->getElementAsAPFloat(0).isZero())
return true;
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
@@ -113,9 +113,13 @@ bool Constant::isAllOnesValue() const {
return Splat->isAllOnesValue();
// Check for constant vectors which are splats of -1 values.
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
- if (Constant *Splat = CV->getSplatValue())
- return Splat->isAllOnesValue();
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
+ if (CV->isSplat()) {
+ if (CV->getElementType()->isFloatingPointTy())
+ return CV->getElementAsAPFloat(0).bitcastToAPInt().isAllOnesValue();
+ return CV->getElementAsAPInt(0).isAllOnesValue();
+ }
+ }
return false;
}
@@ -135,9 +139,13 @@ bool Constant::isOneValue() const {
return Splat->isOneValue();
// Check for constant vectors which are splats of 1 values.
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
- if (Constant *Splat = CV->getSplatValue())
- return Splat->isOneValue();
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
+ if (CV->isSplat()) {
+ if (CV->getElementType()->isFloatingPointTy())
+ return CV->getElementAsAPFloat(0).bitcastToAPInt().isOneValue();
+ return CV->getElementAsAPInt(0).isOneValue();
+ }
+ }
return false;
}
@@ -157,9 +165,13 @@ bool Constant::isMinSignedValue() const
return Splat->isMinSignedValue();
// Check for constant vectors which are splats of INT_MIN values.
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
- if (Constant *Splat = CV->getSplatValue())
- return Splat->isMinSignedValue();
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
+ if (CV->isSplat()) {
+ if (CV->getElementType()->isFloatingPointTy())
+ return CV->getElementAsAPFloat(0).bitcastToAPInt().isMinSignedValue();
+ return CV->getElementAsAPInt(0).isMinSignedValue();
+ }
+ }
return false;
}
@@ -179,9 +191,13 @@ bool Constant::isNotMinSignedValue() con
return Splat->isNotMinSignedValue();
// Check for constant vectors which are splats of INT_MIN values.
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
- if (Constant *Splat = CV->getSplatValue())
- return Splat->isNotMinSignedValue();
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
+ if (CV->isSplat()) {
+ if (CV->getElementType()->isFloatingPointTy())
+ return !CV->getElementAsAPFloat(0).bitcastToAPInt().isMinSignedValue();
+ return !CV->getElementAsAPInt(0).isMinSignedValue();
+ }
+ }
// It *may* contain INT_MIN, we can't tell.
return false;
@@ -2565,6 +2581,34 @@ uint64_t ConstantDataSequential::getElem
}
}
+APInt ConstantDataSequential::getElementAsAPInt(unsigned Elt) const {
+ assert(isa<IntegerType>(getElementType()) &&
+ "Accessor can only be used when element is an integer");
+ const char *EltPtr = getElementPointer(Elt);
+
+ // The data is stored in host byte order, make sure to cast back to the right
+ // type to load with the right endianness.
+ switch (getElementType()->getIntegerBitWidth()) {
+ default: llvm_unreachable("Invalid bitwidth for CDS");
+ case 8: {
+ auto EltVal = *reinterpret_cast<const uint8_t *>(EltPtr);
+ return APInt(8, EltVal);
+ }
+ case 16: {
+ auto EltVal = *reinterpret_cast<const uint16_t *>(EltPtr);
+ return APInt(16, EltVal);
+ }
+ case 32: {
+ auto EltVal = *reinterpret_cast<const uint32_t *>(EltPtr);
+ return APInt(32, EltVal);
+ }
+ case 64: {
+ auto EltVal = *reinterpret_cast<const uint64_t *>(EltPtr);
+ return APInt(64, EltVal);
+ }
+ }
+}
+
APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
const char *EltPtr = getElementPointer(Elt);
@@ -2623,17 +2667,21 @@ bool ConstantDataSequential::isCString()
return Str.drop_back().find(0) == StringRef::npos;
}
-Constant *ConstantDataVector::getSplatValue() const {
+bool ConstantDataVector::isSplat() const {
const char *Base = getRawDataValues().data();
// Compare elements 1+ to the 0'th element.
unsigned EltSize = getElementByteSize();
for (unsigned i = 1, e = getNumElements(); i != e; ++i)
if (memcmp(Base, Base+i*EltSize, EltSize))
- return nullptr;
+ return false;
+
+ return true;
+}
+Constant *ConstantDataVector::getSplatValue() const {
// If they're all the same, return the 0th one as a representative.
- return getElementAsConstant(0);
+ return isSplat() ? getElementAsConstant(0) : nullptr;
}
//===----------------------------------------------------------------------===//
More information about the llvm-commits
mailing list