aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-31 02:06:56 +0000
committerChris Lattner <sabre@nondot.org>2006-03-31 02:06:56 +0000
commit70c2a61e0a0fb0a7e8b9bddd26bdcc92762772f0 (patch)
tree19cf8952e4cce2d50d3b54e93bd945dbd8f41347
parenta6c9de42938a26aa7edf50f4250cfd5cdca7737d (diff)
Significantly improve handling of vectors that are live across basic blocks,
handling cases where the vector elements need promotion, expansion, and when the vector type itself needs to be decimated. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27278 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp145
3 files changed, 101 insertions, 52 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 29d7a5ebf6..93b0d9b1cc 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -4497,9 +4497,6 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
/// type for the result.
SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op,
MVT::ValueType NewVT) {
- // FIXME: THIS IS A TEMPORARY HACK
- if (Op.getValueType() == NewVT) return Op;
-
assert(Op.getValueType() == MVT::Vector && "Bad PackVectorOp invocation!");
SDNode *Node = Op.Val;
@@ -4536,7 +4533,7 @@ SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op,
break;
}
case ISD::VBUILD_VECTOR:
- if (!MVT::isVector(NewVT)) {
+ if (Node->getOperand(0).getValueType() == NewVT) {
// Returning a scalar?
Result = Node->getOperand(0);
} else {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index a2c423fbcb..dda5cfe772 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1162,8 +1162,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
break;
case ISD::BIT_CONVERT:
// Basic sanity checking.
- assert((Operand.getValueType() == MVT::Vector || // FIXME: This is a hack.
- MVT::getSizeInBits(VT) == MVT::getSizeInBits(Operand.getValueType()))
+ assert(MVT::getSizeInBits(VT) == MVT::getSizeInBits(Operand.getValueType())
&& "Cannot BIT_CONVERT between two different types!");
if (VT == Operand.getValueType()) return Operand; // noop conversion.
if (OpOpcode == ISD::BIT_CONVERT) // bitconv(bitconv(x)) -> bitconv(x)
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 0a694cce1f..0b32352c68 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -264,8 +264,16 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli,
for (BasicBlock::iterator I = BB->begin();
(PN = dyn_cast<PHINode>(I)); ++I)
if (!PN->use_empty()) {
- unsigned NumElements =
- TLI.getNumElements(TLI.getValueType(PN->getType()));
+ MVT::ValueType VT = TLI.getValueType(PN->getType());
+ unsigned NumElements;
+ if (VT != MVT::Vector)
+ NumElements = TLI.getNumElements(VT);
+ else {
+ MVT::ValueType VT1,VT2;
+ NumElements =
+ TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()),
+ VT1, VT2);
+ }
unsigned PHIReg = ValueMap[PN];
assert(PHIReg &&"PHI node does not have an assigned virtual register!");
for (unsigned i = 0; i != NumElements; ++i)
@@ -622,32 +630,61 @@ SDOperand SelectionDAGLowering::getValue(const Value *V) {
unsigned InReg = VMI->second;
// If this type is not legal, make it so now.
- if (VT == MVT::Vector) {
- // FIXME: We only handle legal vectors right now. We need a VBUILD_VECTOR
- const PackedType *PTy = cast<PackedType>(VTy);
- unsigned NumElements = PTy->getNumElements();
- MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
- MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements);
- assert(TLI.isTypeLegal(TVT) &&
- "FIXME: Cannot handle illegal vector types here yet!");
- VT = TVT;
- }
-
- MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
-
- N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
- if (DestVT < VT) {
- // Source must be expanded. This input value is actually coming from the
- // register pair VMI->second and VMI->second+1.
- N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
- DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
- } else {
- if (DestVT > VT) { // Promotion case
+ if (VT != MVT::Vector) {
+ MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
+
+ N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
+ if (DestVT < VT) {
+ // Source must be expanded. This input value is actually coming from the
+ // register pair VMI->second and VMI->second+1.
+ N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
+ DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
+ } else if (DestVT > VT) { // Promotion case
if (MVT::isFloatingPoint(VT))
N = DAG.getNode(ISD::FP_ROUND, VT, N);
else
N = DAG.getNode(ISD::TRUNCATE, VT, N);
}
+ } else {
+ // Otherwise, if this is a vector, make it available as a generic vector
+ // here.
+ MVT::ValueType PTyElementVT, PTyLegalElementVT;
+ unsigned NE = TLI.getPackedTypeBreakdown(cast<PackedType>(VTy),PTyElementVT,
+ PTyLegalElementVT);
+
+ // Build a VBUILD_VECTOR with the input registers.
+ std::vector<SDOperand> Ops;
+ if (PTyElementVT == PTyLegalElementVT) {
+ // If the value types are legal, just VBUILD the CopyFromReg nodes.
+ for (unsigned i = 0; i != NE; ++i)
+ Ops.push_back(DAG.getCopyFromReg(DAG.getEntryNode(), InReg++,
+ PTyElementVT));
+ } else if (PTyElementVT < PTyLegalElementVT) {
+ // If the register was promoted, use TRUNCATE of FP_ROUND as appropriate.
+ for (unsigned i = 0; i != NE; ++i) {
+ SDOperand Op = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++,
+ PTyElementVT);
+ if (MVT::isFloatingPoint(PTyElementVT))
+ Op = DAG.getNode(ISD::FP_ROUND, PTyElementVT, Op);
+ else
+ Op = DAG.getNode(ISD::TRUNCATE, PTyElementVT, Op);
+ Ops.push_back(Op);
+ }
+ } else {
+ // If the register was expanded, use BUILD_PAIR.
+ assert((NE & 1) == 0 && "Must expand into a multiple of 2 elements!");
+ for (unsigned i = 0; i != NE/2; ++i) {
+ SDOperand Op0 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++,
+ PTyElementVT);
+ SDOperand Op1 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++,
+ PTyElementVT);
+ Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, VT, Op0, Op1));
+ }
+ }
+
+ Ops.push_back(DAG.getConstant(NE, MVT::i32));
+ Ops.push_back(DAG.getValueType(PTyLegalElementVT));
+ N = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, Ops);
}
return N;
@@ -2589,31 +2626,47 @@ CopyValueToVirtualRegister(SelectionDAGLowering &SDL, Value *V, unsigned Reg) {
if (SrcVT == DestVT) {
return DAG.getCopyToReg(SDL.getRoot(), Reg, Op);
} else if (SrcVT == MVT::Vector) {
- // FIXME: THIS DOES NOT SUPPORT PROMOTED/EXPANDED ELEMENTS!
-
- // Figure out the right, legal destination reg to copy into.
- const PackedType *PTy = cast<PackedType>(V->getType());
- unsigned NumElts = PTy->getNumElements();
- MVT::ValueType EltTy = TLI.getValueType(PTy->getElementType());
+ // Handle copies from generic vectors to registers.
+ MVT::ValueType PTyElementVT, PTyLegalElementVT;
+ unsigned NE = TLI.getPackedTypeBreakdown(cast<PackedType>(V->getType()),
+ PTyElementVT, PTyLegalElementVT);
- unsigned NumVectorRegs = 1;
-
- // Divide the input until we get to a supported size. This will always
- // end with a scalar if the target doesn't support vectors.
- while (NumElts > 1 && !TLI.isTypeLegal(getVectorType(EltTy, NumElts))) {
- NumElts >>= 1;
- NumVectorRegs <<= 1;
+ // Insert a VBIT_CONVERT of the input vector to a "N x PTyElementVT"
+ // MVT::Vector type.
+ Op = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Op,
+ DAG.getConstant(NE, MVT::i32),
+ DAG.getValueType(PTyElementVT));
+
+ // Loop over all of the elements of the resultant vector,
+ // VEXTRACT_VECTOR_ELT'ing them, converting them to PTyLegalElementVT, then
+ // copying them into output registers.
+ std::vector<SDOperand> OutChains;
+ SDOperand Root = SDL.getRoot();
+ for (unsigned i = 0; i != NE; ++i) {
+ SDOperand Elt = DAG.getNode(ISD::VEXTRACT_VECTOR_ELT, PTyElementVT,
+ Op, DAG.getConstant(i, MVT::i32));
+ if (PTyElementVT == PTyLegalElementVT) {
+ // Elements are legal.
+ OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
+ } else if (PTyLegalElementVT > PTyElementVT) {
+ // Elements are promoted.
+ if (MVT::isFloatingPoint(PTyLegalElementVT))
+ Elt = DAG.getNode(ISD::FP_EXTEND, PTyLegalElementVT, Elt);
+ else
+ Elt = DAG.getNode(ISD::ANY_EXTEND, PTyLegalElementVT, Elt);
+ OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
+ } else {
+ // Elements are expanded.
+ // The src value is expanded into multiple registers.
+ SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, PTyLegalElementVT,
+ Elt, DAG.getConstant(0, MVT::i32));
+ SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, PTyLegalElementVT,
+ Elt, DAG.getConstant(1, MVT::i32));
+ OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Lo));
+ OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Hi));
+ }
}
-
- MVT::ValueType VT;
- if (NumElts == 1)
- VT = EltTy;
- else
- VT = getVectorType(EltTy, NumElts);
-
- // FIXME: THIS ASSUMES THAT THE INPUT VECTOR WILL BE LEGAL!
- Op = DAG.getNode(ISD::BIT_CONVERT, VT, Op);
- return DAG.getCopyToReg(SDL.getRoot(), Reg, Op);
+ return DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains);
} else if (SrcVT < DestVT) {
// The src value is promoted to the register.
if (MVT::isFloatingPoint(SrcVT))