#define LLVM_CODEGEN_SELECTIONDAGNODES_H
#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
bool isBigEndian = false) const;
/// \brief Returns the splatted value or a null value if this is not a splat.
- SDValue getSplatValue(bool &HasUndefElements) const;
+ ///
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
/// \brief Returns the splatted constant or null if this is not a constant
/// splat.
- ConstantSDNode *getConstantSplatNode(bool &HasUndefElements) const;
+ ///
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ ConstantSDNode *
+ getConstantSplatNode(BitVector *UndefElements = nullptr) const;
/// \brief Returns the splatted constant FP or null if this is not a constant
/// FP splat.
- ConstantFPSDNode *getConstantFPSplatNode(bool &HasUndefElements) const;
+ ///
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ ConstantFPSDNode *
+ getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
bool isConstant() const;
return CN;
if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N)) {
- bool HasUndefElements;
- ConstantSDNode *CN = BV->getConstantSplatNode(HasUndefElements);
+ BitVector UndefElements;
+ ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements);
// BuildVectors can truncate their operands. Ignore that case here.
// FIXME: We blindly ignore splats which include undef which is overly
// pessimistic.
- if (CN && !HasUndefElements &&
+ if (CN && UndefElements.none() &&
CN->getValueType(0) == N.getValueType().getScalarType())
return CN;
}
// A splat should always show up as a build vector node.
if (auto *BV = dyn_cast<BuildVectorSDNode>(V)) {
- bool SplatHasUndefs;
- SDValue Splat = BV->getSplatValue(SplatHasUndefs);
+ BitVector UndefElements;
+ SDValue Splat = BV->getSplatValue(&UndefElements);
// If this is a splat of an undef, shuffling it is also undef.
if (Splat && Splat.getOpcode() == ISD::UNDEF)
return getUNDEF(VT);
// We only have a splat which can skip shuffles if there is a splatted
// value and no undef lanes rearranged by the shuffle.
- if (Splat && !SplatHasUndefs) {
+ if (Splat && UndefElements.none()) {
// Splat of <x, x, ..., x>, return <x, x, ..., x>, provided that the
// number of elements match or the value splatted is a zero constant.
if (V.getValueType().getVectorNumElements() ==
return true;
}
-SDValue BuildVectorSDNode::getSplatValue(bool &HasUndefElements) const {
- HasUndefElements = false;
+SDValue BuildVectorSDNode::getSplatValue(BitVector *UndefElements) const {
+ if (UndefElements) {
+ UndefElements->clear();
+ UndefElements->resize(getNumOperands());
+ }
SDValue Splatted;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
SDValue Op = getOperand(i);
- if (Op.getOpcode() == ISD::UNDEF)
- HasUndefElements = true;
- else if (!Splatted)
+ if (Op.getOpcode() == ISD::UNDEF) {
+ if (UndefElements)
+ (*UndefElements)[i] = true;
+ } else if (!Splatted) {
Splatted = Op;
- else if (Splatted != Op)
+ } else if (Splatted != Op) {
return SDValue();
+ }
}
if (!Splatted) {
}
ConstantSDNode *
-BuildVectorSDNode::getConstantSplatNode(bool &HasUndefElements) const {
+BuildVectorSDNode::getConstantSplatNode(BitVector *UndefElements) const {
return dyn_cast_or_null<ConstantSDNode>(
- getSplatValue(HasUndefElements).getNode());
+ getSplatValue(UndefElements).getNode());
}
ConstantFPSDNode *
-BuildVectorSDNode::getConstantFPSplatNode(bool &HasUndefElements) const {
+BuildVectorSDNode::getConstantFPSplatNode(BitVector *UndefElements) const {
return dyn_cast_or_null<ConstantFPSDNode>(
- getSplatValue(HasUndefElements).getNode());
+ getSplatValue(UndefElements).getNode());
}
bool BuildVectorSDNode::isConstant() const {
return false;
IsVec = true;
- bool HasUndefElements;
- CN = BV->getConstantSplatNode(HasUndefElements);
+ BitVector UndefElements;
+ CN = BV->getConstantSplatNode(&UndefElements);
// Only interested in constant splats, and we don't try to handle undef
// elements in identifying boolean constants.
- if (!CN || HasUndefElements)
+ if (!CN || UndefElements.none())
return false;
}
return false;
IsVec = true;
- bool HasUndefElements;
- CN = BV->getConstantSplatNode(HasUndefElements);
+ BitVector UndefElements;
+ CN = BV->getConstantSplatNode(&UndefElements);
// Only interested in constant splats, and we don't try to handle undef
// elements in identifying boolean constants.
- if (!CN || HasUndefElements)
+ if (!CN || UndefElements.none())
return false;
}