Handle more forms of constant vectors in lGetMask().
Various optimization passes depend on turning a compile-time constant mask into a bit vector; it turns out that in LLVM3.1, constant vectors of ints/floats are represented with llvM::ConstantDataVector, but constant vectors of bools use llvm::ConstantVector (which is what LLVM 3.0 uses for all constant vectors). Now lGetMask() always does the llvm::ConstantVector path, to cover this case. This improves generated C++ code by eliminating things like select with an all on/off mask, turning movmask calls with constants into constant values, etc.
This commit is contained in:
73
opt.cpp
73
opt.cpp
@@ -586,40 +586,22 @@ IntrinsicsOpt::IntrinsicsOpt()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Given an llvm::Value represinting a vector mask, see if the value is a
|
/** Given a vector of constant values (int, float, or bool) representing an
|
||||||
constant. If so, return the integer mask found by taking the high bits
|
execution mask, convert it to a bitvector where the 0th bit corresponds
|
||||||
of the mask values in turn and concatenating them into a single integer.
|
to the first vector value and so forth.
|
||||||
In other words, given the 4-wide mask: < 0xffffffff, 0, 0, 0xffffffff >,
|
|
||||||
we have 0b1001 = 9.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
lGetMask(llvm::Value *factor) {
|
lConstElementsToMask(const llvm::SmallVector<llvm::Constant *,
|
||||||
/* FIXME: This will break if we ever do 32-wide compilation, in which case
|
ISPC_MAX_NVEC> &elements) {
|
||||||
it don't be possible to distinguish between -1 for "don't know" and
|
Assert(elements.size() <= 32);
|
||||||
"known and all bits on". */
|
|
||||||
Assert(g->target.vectorWidth < 32);
|
|
||||||
|
|
||||||
#ifdef LLVM_3_1svn
|
|
||||||
llvm::ConstantDataVector *cv = llvm::dyn_cast<llvm::ConstantDataVector>(factor);
|
|
||||||
#else
|
|
||||||
llvm::ConstantVector *cv = llvm::dyn_cast<llvm::ConstantVector>(factor);
|
|
||||||
#endif
|
|
||||||
if (cv) {
|
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements;
|
|
||||||
#ifdef LLVM_3_1svn
|
|
||||||
for (int i = 0; i < (int)cv->getNumElements(); ++i)
|
|
||||||
elements.push_back(cv->getElementAsConstant(i));
|
|
||||||
#else
|
|
||||||
cv->getVectorElements(elements);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < elements.size(); ++i) {
|
for (unsigned int i = 0; i < elements.size(); ++i) {
|
||||||
llvm::APInt intMaskValue;
|
llvm::APInt intMaskValue;
|
||||||
// SSE has the "interesting" approach of encoding blending
|
// SSE has the "interesting" approach of encoding blending
|
||||||
// masks as <n x float>.
|
// masks as <n x float>.
|
||||||
llvm::ConstantFP *cf = llvm::dyn_cast<llvm::ConstantFP>(elements[i]);
|
llvm::ConstantFP *cf = llvm::dyn_cast<llvm::ConstantFP>(elements[i]);
|
||||||
if (cf) {
|
if (cf != NULL) {
|
||||||
llvm::APFloat apf = cf->getValueAPF();
|
llvm::APFloat apf = cf->getValueAPF();
|
||||||
intMaskValue = apf.bitcastToAPInt();
|
intMaskValue = apf.bitcastToAPInt();
|
||||||
}
|
}
|
||||||
@@ -636,6 +618,47 @@ lGetMask(llvm::Value *factor) {
|
|||||||
}
|
}
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Given an llvm::Value represinting a vector mask, see if the value is a
|
||||||
|
constant. If so, return the integer mask found by taking the high bits
|
||||||
|
of the mask values in turn and concatenating them into a single integer.
|
||||||
|
In other words, given the 4-wide mask: < 0xffffffff, 0, 0, 0xffffffff >,
|
||||||
|
we have 0b1001 = 9.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
lGetMask(llvm::Value *factor) {
|
||||||
|
/* FIXME: This will break if we ever do 32-wide compilation, in which case
|
||||||
|
it don't be possible to distinguish between -1 for "don't know" and
|
||||||
|
"known and all bits on". */
|
||||||
|
Assert(g->target.vectorWidth < 32);
|
||||||
|
|
||||||
|
#ifdef LLVM_3_1svn
|
||||||
|
llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(factor);
|
||||||
|
if (cdv != NULL) {
|
||||||
|
llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements;
|
||||||
|
for (int i = 0; i < (int)cdv->getNumElements(); ++i)
|
||||||
|
elements.push_back(cdv->getElementAsConstant(i));
|
||||||
|
return lConstElementsToMask(elements);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
llvm::ConstantVector *cv = llvm::dyn_cast<llvm::ConstantVector>(factor);
|
||||||
|
if (cv != NULL) {
|
||||||
|
llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements;
|
||||||
|
#ifdef LLVM_3_1svn
|
||||||
|
for (int i = 0; i < (int)cv->getNumOperands(); ++i) {
|
||||||
|
llvm::Constant *c =
|
||||||
|
llvm::dyn_cast<llvm::Constant>(cv->getOperand(i));
|
||||||
|
if (c == NULL)
|
||||||
|
return NULL;
|
||||||
|
elements.push_back(c);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
cv->getVectorElements(elements);
|
||||||
|
#endif
|
||||||
|
return lConstElementsToMask(elements);
|
||||||
|
}
|
||||||
else if (llvm::isa<llvm::ConstantAggregateZero>(factor))
|
else if (llvm::isa<llvm::ConstantAggregateZero>(factor))
|
||||||
return 0;
|
return 0;
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user