add many new cases to SplitResult. SplitResult now handles all the cases that LegalizeDAG does.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44726 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-12-08 23:58:27 +00:00
parent 50187864c1
commit eeaad40246
2 changed files with 178 additions and 3 deletions

View File

@ -276,7 +276,17 @@ private:
void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
// Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>.
bool SplitOperand(SDNode *N, unsigned OpNo);

View File

@ -71,8 +71,26 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
assert(0 && "Do not know how to split the result of this operator!");
abort();
case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
case ISD::LOAD: SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
case ISD::LOAD: SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
case ISD::BUILD_PAIR: SplitRes_BUILD_PAIR(N, Lo, Hi); break;
case ISD::INSERT_VECTOR_ELT:SplitRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
case ISD::VECTOR_SHUFFLE: SplitRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
case ISD::BUILD_VECTOR: SplitRes_BUILD_VECTOR(N, Lo, Hi); break;
case ISD::CONCAT_VECTORS: SplitRes_CONCAT_VECTORS(N, Lo, Hi); break;
case ISD::BIT_CONVERT: SplitRes_BIT_CONVERT(N, Lo, Hi); break;
case ISD::CTTZ:
case ISD::CTLZ:
case ISD::CTPOP:
case ISD::FNEG:
case ISD::FABS:
case ISD::FSQRT:
case ISD::FSIN:
case ISD::FCOS:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP: SplitRes_UnOp(N, Lo, Hi); break;
case ISD::ADD:
case ISD::SUB:
case ISD::MUL:
@ -88,7 +106,9 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
case ISD::XOR:
case ISD::UREM:
case ISD::SREM:
case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break;
case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break;
case ISD::FPOWI: SplitRes_FPOWI(N, Lo, Hi); break;
case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
}
// If Lo/Hi is null, the sub-method took care of registering results etc.
@ -134,6 +154,124 @@ void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
ReplaceValueWith(SDOperand(LD, 1), TF);
}
void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
SDOperand &Hi) {
Lo = N->getOperand(0);
Hi = N->getOperand(1);
}
void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
SDOperand &Hi) {
GetSplitOp(N->getOperand(0), Lo, Hi);
unsigned Index = cast<ConstantSDNode>(N->getOperand(2))->getValue();
SDOperand ScalarOp = N->getOperand(1);
unsigned LoNumElts = MVT::getVectorNumElements(Lo.getValueType());
if (Index < LoNumElts)
Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, ScalarOp,
N->getOperand(2));
else
Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, ScalarOp,
DAG.getConstant(Index - LoNumElts, TLI.getPointerTy()));
}
void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Build the low part.
SDOperand Mask = N->getOperand(2);
SmallVector<SDOperand, 16> Ops;
MVT::ValueType PtrVT = TLI.getPointerTy();
MVT::ValueType LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
MVT::ValueType EltVT = MVT::getVectorElementType(LoVT);
unsigned LoNumElts = MVT::getVectorNumElements(LoVT);
unsigned NumElements = Mask.getNumOperands();
// Insert all of the elements from the input that are needed. We use
// buildvector of extractelement here because the input vectors will have
// to be legalized, so this makes the code simpler.
for (unsigned i = 0; i != LoNumElts; ++i) {
unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
SDOperand InVec = N->getOperand(0);
if (Idx >= NumElements) {
InVec = N->getOperand(1);
Idx -= NumElements;
}
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
DAG.getConstant(Idx, PtrVT)));
}
Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &Ops[0], Ops.size());
Ops.clear();
for (unsigned i = LoNumElts; i != NumElements; ++i) {
unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
SDOperand InVec = N->getOperand(0);
if (Idx >= NumElements) {
InVec = N->getOperand(1);
Idx -= NumElements;
}
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
DAG.getConstant(Idx, PtrVT)));
}
Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size());
}
void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo,
SDOperand &Hi) {
MVT::ValueType LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
unsigned LoNumElts = MVT::getVectorNumElements(LoVT);
SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size());
SmallVector<SDOperand, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
}
void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// FIXME: Handle non-power-of-two vectors?
unsigned NumSubvectors = N->getNumOperands() / 2;
if (NumSubvectors == 1) {
Lo = N->getOperand(0);
Hi = N->getOperand(1);
return;
}
MVT::ValueType LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size());
SmallVector<SDOperand, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
}
void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// We know the result is a vector. The input may be either a vector or a
// scalar value.
SDOperand InOp = N->getOperand(0);
if (MVT::isVector(InOp.getValueType()) &&
MVT::getVectorNumElements(InOp.getValueType()) != 1) {
// If this is a vector, split the vector and convert each of the pieces now.
GetSplitOp(InOp, Lo, Hi);
MVT::ValueType LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
return;
}
// Lower the bit-convert to a store/load from the stack, then split the load.
SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
SplitRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
}
void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
SDOperand LHSLo, LHSHi;
GetSplitOp(N->getOperand(0), LHSLo, LHSHi);
@ -144,6 +282,33 @@ void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
}
void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
// Get the dest types. This doesn't always match input types, e.g. int_to_fp.
MVT::ValueType LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
GetSplitOp(N->getOperand(0), Lo, Hi);
Lo = DAG.getNode(N->getOpcode(), LoVT, Lo);
Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
}
void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
GetSplitOp(N->getOperand(0), Lo, Hi);
Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1));
}
void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
SDOperand LL, LH, RL, RH;
GetSplitOp(N->getOperand(1), LL, LH);
GetSplitOp(N->getOperand(2), RL, RH);
SDOperand Cond = N->getOperand(0);
Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
}
//===----------------------------------------------------------------------===//
// Operand Vector Splitting