Remove all "cached" data from BuildVectorSDNode, preferring to retrieve

results via reference parameters.

This patch also appears to fix Evan's reported problem supplied as a
reduced bugpoint test case.

llvm-svn: 65426
This commit is contained in:
Scott Michel 2009-02-25 03:12:50 +00:00
parent dce7846c24
commit bb878288cb
3 changed files with 29 additions and 52 deletions

View File

@ -1933,13 +1933,6 @@ public:
/// encapsulate common BUILD_VECTOR code and operations such as constant splat
/// testing.
class BuildVectorSDNode : public SDNode {
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// Constant splat state:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
//! We've computed the splat already?
bool computedSplat;
//! It is a splat?
bool isSplatVector;
//! Splat has undefined bits in it
bool hasUndefSplatBitsFlag;
//! The splat value
@ -1959,36 +1952,25 @@ protected:
public:
//! Constant splat predicate.
/*!
Determine if this ISD::BUILD_VECTOR is a constant splat. The results are
cached to prevent recomputation.
Determine if this ISD::BUILD_VECTOR is a constant splat. This method
returns information about the splat in \a hasUndefSplatBitsFlag,
\a SplatBits, \a SplatUndef and \a SplatSize if the return value is
true.
@param MinSplatBits: minimum number of bits in the constant splat, defaults
\param[out] hasUndefSplatBitsFlag: true if the constant splat contains
any undefined bits in the splat.
\param[out] SplatBits: The constant splat value
\param[out] SplatUndef: The undefined bits in the splat value
\param[out] SplatSize: The size of the constant splat in bytes
\param MinSplatBits: minimum number of bits in the constant splat, defaults
to 0 for 'don't care', but normally one of [8, 16, 32, 64].
@return true if the splat has the required minimum number of bits and the
\return true if the splat has the required minimum number of bits and the
splat really is a constant splat (accounting for undef bits).
*/
bool isConstantSplat(int MinSplatBits = 0);
//! Get the splatbits
uint64_t getSplatBits() const {
assert(computedSplat && "BuildVectorSDNode: compute splat bits first!");
return SplatBits;
}
uint64_t getSplatUndef() const {
assert(computedSplat && "BuildVectorSDNode: compute splat bits first!");
return SplatUndef;
}
unsigned getSplatSize() const {
assert(computedSplat && "BuildVectorSDNode: compute splat bits first!");
return SplatSize;
}
bool hasAnyUndefBits() const {
assert(computedSplat && "BuildVectorSDNode: compute splat bits first!");
return hasUndefSplatBitsFlag;
}
bool isConstantSplat(bool &hasUndefSplatBitsFlag, uint64_t &SplatBits,
uint64_t &SplatUndef, unsigned &SplatSize,
int MinSplatBits = 0);
static bool classof(const BuildVectorSDNode *) { return true; }
static bool classof(const SDNode *N) {

View File

@ -4856,27 +4856,25 @@ MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
BuildVectorSDNode::BuildVectorSDNode(MVT vecVT, DebugLoc dl,
const SDValue *Elts, unsigned NumElts)
: SDNode(ISD::BUILD_VECTOR, dl, getSDVTList(vecVT), Elts, NumElts),
computedSplat(false), isSplatVector(false), hasUndefSplatBitsFlag(false),
SplatBits(0LL), SplatUndef(0LL), SplatSize(0)
: SDNode(ISD::BUILD_VECTOR, dl, getSDVTList(vecVT), Elts, NumElts)
{ }
bool BuildVectorSDNode::isConstantSplat(int MinSplatBits) {
bool BuildVectorSDNode::isConstantSplat(bool &hasUndefSplatBitsFlag,
uint64_t &SplatBits,
uint64_t &SplatUndef,
unsigned &SplatSize,
int MinSplatBits) {
unsigned int nOps = getNumOperands();
assert(nOps > 0 && "isConstantSplat has 0-size build vector");
// Return early if we already know the answer:
if (computedSplat)
return isSplatVector;
// Assume that this isn't a constant splat.
bool isSplatVector = false;
// The vector's used (non-undef) bits
uint64_t VectorBits[2] = { 0, 0 };
// The vector's undefined bits
uint64_t UndefBits[2] = { 0, 0 };
// Assume that this isn't a constant splat.
isSplatVector = false;
// Gather the constant and undefined bits
unsigned EltBitSize = getOperand(0).getValueType().getSizeInBits();
for (unsigned i = 0; i < nOps; ++i) {
@ -4901,7 +4899,6 @@ bool BuildVectorSDNode::isConstantSplat(int MinSplatBits) {
EltBits = DoubleToBits(apf.convertToDouble());
} else {
// Nonconstant element -> not a splat.
computedSplat = true;
return isSplatVector;
}
@ -4910,7 +4907,6 @@ bool BuildVectorSDNode::isConstantSplat(int MinSplatBits) {
if ((VectorBits[0] & ~UndefBits[1]) != (VectorBits[1] & ~UndefBits[0])) {
// Can't be a splat if two pieces don't match.
computedSplat = true;
return isSplatVector;
}
@ -4954,7 +4950,6 @@ bool BuildVectorSDNode::isConstantSplat(int MinSplatBits) {
isSplatVector = true;
}
computedSplat = true;
return isSplatVector;
}

View File

@ -3171,16 +3171,16 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Op.getNode());
assert(BVN != 0 && "Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
uint64_t SplatBits;
uint64_t SplatUndef;
unsigned SplatSize;
bool HasAnyUndefs;
// If this is a splat (repetition) of a value across the whole vector, return
// the smallest size that splats it. For example, "0x01010101010101..." is a
// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
// SplatSize = 1 byte.
if (BVN->isConstantSplat()) {
uint64_t SplatBits = BVN->getSplatBits();
uint64_t SplatUndef = BVN->getSplatUndef();
unsigned SplatSize = BVN->getSplatSize();
bool HasAnyUndefs = BVN->hasAnyUndefBits();
if (BVN->isConstantSplat(HasAnyUndefs, SplatBits, SplatUndef, SplatSize)) {
// First, handle single instruction cases.
// All zeros?