Improved handling of splatted constant vectors in C++ backend.
Now, when we're printing out a constant vector value, we check to see if it's a splat and call out to one of the __splat_* functions in the generated code if to.
This commit is contained in:
92
cbackend.cpp
92
cbackend.cpp
@@ -1096,6 +1096,26 @@ bool CWriter::printCast(unsigned opc, Type *SrcTy, Type *DstTy) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: generalize this/make it not so hard-coded?
|
||||||
|
static const char *lGetSmearFunc(Type *matchType) {
|
||||||
|
switch (matchType->getTypeID()) {
|
||||||
|
case Type::FloatTyID: return "__smear_float";
|
||||||
|
case Type::DoubleTyID: return "__smear_double";
|
||||||
|
case Type::IntegerTyID: {
|
||||||
|
switch (cast<IntegerType>(matchType)->getBitWidth()) {
|
||||||
|
case 1: return "__smear_i1";
|
||||||
|
case 8: return "__smear_i8";
|
||||||
|
case 16: return "__smear_i16";
|
||||||
|
case 32: return "__smear_i32";
|
||||||
|
case 64: return "__smear_i64";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// printConstant - The LLVM Constant to C Constant converter.
|
// printConstant - The LLVM Constant to C Constant converter.
|
||||||
void CWriter::printConstant(Constant *CPV, bool Static) {
|
void CWriter::printConstant(Constant *CPV, bool Static) {
|
||||||
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
||||||
@@ -1435,30 +1455,61 @@ void CWriter::printConstant(Constant *CPV, bool Static) {
|
|||||||
Out << ")";
|
Out << ")";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Type::VectorTyID:
|
case Type::VectorTyID: {
|
||||||
printType(Out, CPV->getType());
|
VectorType *VT = dyn_cast<VectorType>(CPV->getType());
|
||||||
Out << "(";
|
const char *smearFunc = lGetSmearFunc(VT->getElementType());
|
||||||
|
|
||||||
if (ConstantVector *CV = dyn_cast<ConstantVector>(CPV)) {
|
if (isa<ConstantAggregateZero>(CPV)) {
|
||||||
printConstantVector(CV, Static);
|
assert(smearFunc != NULL);
|
||||||
|
|
||||||
|
Constant *CZ = Constant::getNullValue(VT->getElementType());
|
||||||
|
Out << smearFunc << "(";
|
||||||
|
printConstant(CZ, Static);
|
||||||
|
Out << ")";
|
||||||
|
}
|
||||||
|
else if (ConstantVector *CV = dyn_cast<ConstantVector>(CPV)) {
|
||||||
|
llvm::Constant *splatValue = CV->getSplatValue();
|
||||||
|
if (splatValue != NULL && smearFunc != NULL) {
|
||||||
|
Out << smearFunc << "(";
|
||||||
|
printConstant(splatValue, Static);
|
||||||
|
Out << ")";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printType(Out, CPV->getType());
|
||||||
|
Out << "(";
|
||||||
|
printConstantVector(CV, Static);
|
||||||
|
Out << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef LLVM_3_1svn
|
#ifdef LLVM_3_1svn
|
||||||
} else if (ConstantDataSequential *CDS =
|
else if (ConstantDataVector *CDV = dyn_cast<ConstantDataVector>(CPV)) {
|
||||||
dyn_cast<ConstantDataSequential>(CPV)) {
|
llvm::Constant *splatValue = CDV->getSplatValue();
|
||||||
printConstantDataSequential(CDS, Static);
|
if (splatValue != NULL && smearFunc != NULL) {
|
||||||
|
Out << smearFunc << "(";
|
||||||
|
printConstant(splatValue, Static);
|
||||||
|
Out << ")";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printType(Out, CPV->getType());
|
||||||
|
Out << "(";
|
||||||
|
printConstantDataSequential(CDV, Static);
|
||||||
|
Out << ")";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
assert(isa<ConstantAggregateZero>(CPV) || isa<UndefValue>(CPV));
|
assert(isa<UndefValue>(CPV));
|
||||||
VectorType *VT = cast<VectorType>(CPV->getType());
|
|
||||||
Constant *CZ = Constant::getNullValue(VT->getElementType());
|
Constant *CZ = Constant::getNullValue(VT->getElementType());
|
||||||
|
printType(Out, CPV->getType());
|
||||||
|
Out << "(";
|
||||||
printConstant(CZ, Static);
|
printConstant(CZ, Static);
|
||||||
for (unsigned i = 1, e = VT->getNumElements(); i != e; ++i) {
|
for (unsigned i = 1, e = VT->getNumElements(); i != e; ++i) {
|
||||||
Out << ", ";
|
Out << ", ";
|
||||||
printConstant(CZ, Static);
|
printConstant(CZ, Static);
|
||||||
}
|
}
|
||||||
|
Out << ")";
|
||||||
}
|
}
|
||||||
Out << ")";
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Type::StructTyID:
|
case Type::StructTyID:
|
||||||
if (!Static) {
|
if (!Static) {
|
||||||
// call init func...
|
// call init func...
|
||||||
@@ -4327,23 +4378,8 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
assert(toMatch != NULL);
|
assert(toMatch != NULL);
|
||||||
|
|
||||||
{
|
{
|
||||||
// FIXME: generalize this/make it not so hard-coded?
|
|
||||||
Type *matchType = toMatch->getType();
|
Type *matchType = toMatch->getType();
|
||||||
const char *smearFuncName = NULL;
|
const char *smearFuncName = lGetSmearFunc(matchType);
|
||||||
|
|
||||||
switch (matchType->getTypeID()) {
|
|
||||||
case Type::FloatTyID: smearFuncName = "__smear_float"; break;
|
|
||||||
case Type::DoubleTyID: smearFuncName = "__smear_double"; break;
|
|
||||||
case Type::IntegerTyID: {
|
|
||||||
switch (cast<IntegerType>(matchType)->getBitWidth()) {
|
|
||||||
case 8: smearFuncName = "__smear_i8"; break;
|
|
||||||
case 16: smearFuncName = "__smear_i16"; break;
|
|
||||||
case 32: smearFuncName = "__smear_i32"; break;
|
|
||||||
case 64: smearFuncName = "__smear_i64"; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smearFuncName != NULL) {
|
if (smearFuncName != NULL) {
|
||||||
Function *smearFunc = module->getFunction(smearFuncName);
|
Function *smearFunc = module->getFunction(smearFuncName);
|
||||||
|
|||||||
@@ -374,6 +374,11 @@ static FORCEINLINE void __store(__vec16_i1 *p, __vec16_i1 v, int align) {
|
|||||||
*ptr = v.v;
|
*ptr = v.v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FORCEINLINE __vec16_i1 __smear_i1(int v) {
|
||||||
|
return __vec16_i1(v, v, v, v, v, v, v, v,
|
||||||
|
v, v, v, v, v, v, v, v);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// int8
|
// int8
|
||||||
|
|
||||||
|
|||||||
@@ -266,6 +266,10 @@ static FORCEINLINE void __store(__vec4_i1 *p, __vec4_i1 value, int align) {
|
|||||||
_mm_storeu_ps((float *)(&p->v), value.v);
|
_mm_storeu_ps((float *)(&p->v), value.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FORCEINLINE __vec4_i1 __smear_i1(int v) {
|
||||||
|
return __vec4_i1(v, v, v, v);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// int8
|
// int8
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user