aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-19 01:17:20 +0000
committerChris Lattner <sabre@nondot.org>2006-03-19 01:17:20 +0000
commit2332b9f16fe17d1886566729b2241b8cd90f9916 (patch)
tree3413206ffae4a306b7dd7fa32942d5a8c75b1fa2 /lib/CodeGen
parenta064d28843b425905ed981e693b7730a183ee31b (diff)
implement basic support for INSERT_VECTOR_ELT.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26849 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp144
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp26
2 files changed, 97 insertions, 73 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 6ccd159c5c..52c43af811 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -729,62 +729,92 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case ISD::BUILD_VECTOR:
switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) {
- default: assert(0 && "This action is not supported yet!");
- case TargetLowering::Custom:
- Tmp3 = TLI.LowerOperation(Result, DAG);
- if (Tmp3.Val) {
- Result = Tmp3;
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Custom:
+ Tmp3 = TLI.LowerOperation(Result, DAG);
+ if (Tmp3.Val) {
+ Result = Tmp3;
+ break;
+ }
+ // FALLTHROUGH
+ case TargetLowering::Expand: {
+ // We assume that built vectors are not legal, and will be immediately
+ // spilled to memory. If the values are all constants, turn this into a
+ // load from the constant pool.
+ bool isConstant = true;
+ for (SDNode::op_iterator I = Node->op_begin(), E = Node->op_end();
+ I != E; ++I) {
+ if (!isa<ConstantFPSDNode>(I) && !isa<ConstantSDNode>(I) &&
+ I->getOpcode() != ISD::UNDEF) {
+ isConstant = false;
break;
}
- // FALLTHROUGH
- case TargetLowering::Expand: {
- // We assume that built vectors are not legal, and will be immediately
- // spilled to memory. If the values are all constants, turn this into a
- // load from the constant pool.
- bool isConstant = true;
- for (SDNode::op_iterator I = Node->op_begin(), E = Node->op_end();
- I != E; ++I) {
- if (!isa<ConstantFPSDNode>(I) && !isa<ConstantSDNode>(I) &&
- I->getOpcode() != ISD::UNDEF) {
- isConstant = false;
- break;
- }
- }
-
- // Create a ConstantPacked, and put it in the constant pool.
- if (isConstant) {
- MVT::ValueType VT = Node->getValueType(0);
- const Type *OpNTy =
- MVT::getTypeForValueType(Node->getOperand(0).getValueType());
- std::vector<Constant*> CV;
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
- if (ConstantFPSDNode *V =
- dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
- CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
- } else if (ConstantSDNode *V =
- dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
- CV.push_back(ConstantUInt::get(OpNTy, V->getValue()));
- } else {
- assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
- CV.push_back(UndefValue::get(OpNTy));
- }
- }
- Constant *CP = ConstantPacked::get(CV);
- SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
- Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
- DAG.getSrcValue(NULL));
- break;
+ }
+
+ // Create a ConstantPacked, and put it in the constant pool.
+ if (isConstant) {
+ MVT::ValueType VT = Node->getValueType(0);
+ const Type *OpNTy =
+ MVT::getTypeForValueType(Node->getOperand(0).getValueType());
+ std::vector<Constant*> CV;
+ for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
+ if (ConstantFPSDNode *V =
+ dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
+ CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
+ } else if (ConstantSDNode *V =
+ dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
+ CV.push_back(ConstantUInt::get(OpNTy, V->getValue()));
+ } else {
+ assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
+ CV.push_back(UndefValue::get(OpNTy));
}
-
- // Otherwise, this isn't a constant entry. Allocate a sufficiently
- // aligned object on the stack, store each element into it, then load
- // the result as a vector.
- assert(0 && "Cannot lower variable BUILD_VECTOR yet!");
- abort();
- break;
}
+ Constant *CP = ConstantPacked::get(CV);
+ SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
+ Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+ DAG.getSrcValue(NULL));
+ break;
}
+
+ // Otherwise, this isn't a constant entry. Allocate a sufficiently
+ // aligned object on the stack, store each element into it, then load
+ // the result as a vector.
+ assert(0 && "Cannot lower variable BUILD_VECTOR yet!");
+ abort();
break;
+ }
+ }
+ break;
+ case ISD::INSERT_VECTOR_ELT:
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // InVec
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // InVal
+ Tmp3 = LegalizeOp(Node->getOperand(2)); // InEltNo
+ Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
+
+ switch (TLI.getOperationAction(ISD::INSERT_VECTOR_ELT,
+ Node->getValueType(0))) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Legal:
+ break;
+ case TargetLowering::Custom:
+ Tmp3 = TLI.LowerOperation(Result, DAG);
+ if (Tmp3.Val) {
+ Result = Tmp3;
+ break;
+ }
+ // FALLTHROUGH
+ case TargetLowering::Expand: {
+ // If the target doesn't support this, we have to spill the input vector
+ // to a temporary stack slot, update the element, then reload it. This is
+ // badness. We could also load the value into a vector register (either
+ // with a "move to register" or "extload into register" instruction, then
+ // permute it into place, if the idx is a constant and if the idx is
+ // supported by the target.
+ assert(0 && "INSERT_VECTOR_ELT expand not supported yet!");
+ break;
+ }
+ }
+ break;
case ISD::CALLSEQ_START: {
SDNode *CallEnd = FindCallEndFromCallStart(Node);
@@ -4104,7 +4134,9 @@ SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op,
SDOperand Result;
switch (Node->getOpcode()) {
- default: assert(0 && "Unknown vector operation!");
+ default:
+ Node->dump(); std::cerr << "\n";
+ assert(0 && "Unknown vector operation in PackVectorOp!");
case ISD::VADD:
case ISD::VSUB:
case ISD::VMUL:
@@ -4138,6 +4170,16 @@ SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op,
Result = DAG.getNode(ISD::BUILD_VECTOR, NewVT, Ops);
}
break;
+ case ISD::VINSERT_VECTOR_ELT:
+ if (!MVT::isVector(NewVT)) {
+ // Returning a scalar? Must be the inserted element.
+ Result = Node->getOperand(1);
+ } else {
+ Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT,
+ PackVectorOp(Node->getOperand(0), NewVT),
+ Node->getOperand(1), Node->getOperand(2));
+ }
+ break;
}
if (TLI.isTypeLegal(NewVT))
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 960247298b..4107479bb5 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -842,33 +842,15 @@ void SelectionDAGLowering::visitCast(User &I) {
}
void SelectionDAGLowering::visitInsertElement(InsertElementInst &I) {
- const PackedType *Ty = cast<PackedType>(I.getType());
- unsigned NumElements = Ty->getNumElements();
- MVT::ValueType PVT = TLI.getValueType(Ty->getElementType());
- MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements);
-
SDOperand InVec = getValue(I.getOperand(0));
SDOperand InVal = getValue(I.getOperand(1));
SDOperand InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
getValue(I.getOperand(2)));
- // Immediately scalarize packed types containing only one element, so that
- // the Legalize pass does not have to deal with them. Similarly, if the
- // abstract vector is going to turn into one that the target natively
- // supports, generate that type now so that Legalize doesn't have to deal
- // with that either. These steps ensure that Legalize only has to handle
- // vector types in its Expand case.
- if (NumElements == 1) {
- setValue(&I, InVal); // Must be insertelt(Vec, InVal, 0) -> InVal
- } else if (TVT != MVT::Other && TLI.isTypeLegal(TVT) &&
- TLI.isOperationLegal(ISD::INSERT_VECTOR_ELT, TVT)) {
- setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, TVT, InVec, InVal, InIdx));
- } else {
- SDOperand Num = DAG.getConstant(NumElements, MVT::i32);
- SDOperand Typ = DAG.getValueType(PVT);
- setValue(&I, DAG.getNode(ISD::VINSERT_VECTOR_ELT, MVT::Vector,
- InVec, InVal, InIdx, Num, Typ));
- }
+ SDOperand Num = *(InVec.Val->op_end()-2);
+ SDOperand Typ = *(InVec.Val->op_end()-1);
+ setValue(&I, DAG.getNode(ISD::VINSERT_VECTOR_ELT, MVT::Vector,
+ InVec, InVal, InIdx, Num, Typ));
}