[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat Mar 18 22:31:34 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.323 -> 1.324
SelectionDAG.cpp updated: 1.274 -> 1.275
---
Log message:
Add SCALAR_TO_VECTOR support
---
Diffs of the changes: (+154 -90)
LegalizeDAG.cpp | 227 +++++++++++++++++++++++++++++++++----------------------
SelectionDAG.cpp | 17 +++-
2 files changed, 154 insertions(+), 90 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.323 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.324
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.323 Sat Mar 18 23:46:04 2006
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Mar 19 00:31:19 2006
@@ -160,12 +160,15 @@
void LegalizeSetCCOperands(SDOperand &LHS, SDOperand &RHS, SDOperand &CC);
+ SDOperand CreateStackTemporary(MVT::ValueType VT);
+
SDOperand ExpandLibCall(const char *Name, SDNode *Node,
SDOperand &Hi);
SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
SDOperand Source);
SDOperand ExpandBIT_CONVERT(MVT::ValueType DestVT, SDOperand SrcOp);
+ SDOperand ExpandBUILD_VECTOR(SDNode *Node);
SDOperand ExpandLegalINT_TO_FP(bool isSigned,
SDOperand LegalOp,
MVT::ValueType DestVT);
@@ -737,91 +740,10 @@
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;
- }
-
- // 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.
- MVT::ValueType VT = Node->getValueType(0);
- // Create the stack frame object.
- MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
- unsigned ByteSize = MVT::getSizeInBits(VT)/8;
- int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
- SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
-
- // Emit a store of each element to the stack slot.
- std::vector<SDOperand> Stores;
- bool isLittleEndian = TLI.isLittleEndian();
- unsigned TypeByteSize =
- MVT::getSizeInBits(Node->getOperand(0).getValueType())/8;
- unsigned VectorSize = MVT::getSizeInBits(VT)/8;
- // Store (in the right endianness) the elements to memory.
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
- // Ignore undef elements.
- if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue;
-
- unsigned Offset;
- if (isLittleEndian)
- Offset = TypeByteSize*i;
- else
- Offset = TypeByteSize*(e-i-1);
-
- SDOperand Idx = DAG.getConstant(Offset, FIPtr.getValueType());
- Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
-
- Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
- Node->getOperand(i), Idx,
- DAG.getSrcValue(NULL)));
- }
-
- SDOperand StoreChain;
- if (!Stores.empty()) // Not all undef elements?
- StoreChain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
- else
- StoreChain = DAG.getEntryNode();
-
- // Result is a load from the stack slot.
- Result = DAG.getLoad(VT, StoreChain, FIPtr, DAG.getSrcValue(0));
+ case TargetLowering::Expand:
+ Result = ExpandBUILD_VECTOR(Result.Val);
break;
}
- }
break;
case ISD::INSERT_VECTOR_ELT:
Tmp1 = LegalizeOp(Node->getOperand(0)); // InVec
@@ -853,6 +775,29 @@
}
}
break;
+ case ISD::SCALAR_TO_VECTOR:
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // InVal
+ Result = DAG.UpdateNodeOperands(Result, Tmp1);
+ switch (TLI.getOperationAction(ISD::SCALAR_TO_VECTOR,
+ Node->getValueType(0))) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Legal:
+ break;
+ case TargetLowering::Expand: {
+ // If the target doesn't support this, store the value to a temporary
+ // stack slot, then EXTLOAD the vector back out.
+ SDOperand StackPtr =
+ CreateStackTemporary(Node->getOperand(0).getValueType());
+ SDOperand Ch = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+ Node->getOperand(0), StackPtr,
+ DAG.getSrcValue(NULL));
+ Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), Ch, StackPtr,
+ DAG.getSrcValue(NULL),
+ Node->getOperand(0).getValueType());
+ break;
+ }
+ }
+ break;
case ISD::CALLSEQ_START: {
SDNode *CallEnd = FindCallEndFromCallStart(Node);
@@ -3005,10 +2950,7 @@
SDOperand SelectionDAGLegalize::ExpandBIT_CONVERT(MVT::ValueType DestVT,
SDOperand SrcOp) {
// Create the stack frame object.
- MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
- unsigned ByteSize = MVT::getSizeInBits(DestVT)/8;
- int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
- SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
+ SDOperand FIPtr = CreateStackTemporary(DestVT);
// Emit a store to the stack slot.
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
@@ -3017,6 +2959,117 @@
return DAG.getLoad(DestVT, Store, FIPtr, DAG.getSrcValue(0));
}
+/// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't
+/// support the operation, but do support the resultant packed vector type.
+SDOperand SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
+
+ // If the only non-undef value is the low element, turn this into a
+ // SCALAR_TO_VECTOR node.
+ bool isOnlyLowElement = true;
+ for (SDNode::op_iterator I = Node->op_begin()+1, E = Node->op_end();
+ I != E; ++I) {
+ if (I->getOpcode() != ISD::UNDEF) {
+ isOnlyLowElement = false;
+ break;
+ }
+ }
+
+ if (isOnlyLowElement) {
+ // If the low element is an undef too, then this whole things is an undef.
+ if (Node->getOperand(0).getOpcode() == ISD::UNDEF)
+ return DAG.getNode(ISD::UNDEF, Node->getValueType(0));
+ // Otherwise, turn this into a scalar_to_vector node.
+ return DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0),
+ Node->getOperand(0));
+ }
+
+ // If the elements 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());
+ return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+ DAG.getSrcValue(NULL));
+ }
+
+ // Otherwise, we can't handle this case efficiently. Allocate a sufficiently
+ // aligned object on the stack, store each element into it, then load
+ // the result as a vector.
+ MVT::ValueType VT = Node->getValueType(0);
+ // Create the stack frame object.
+ SDOperand FIPtr = CreateStackTemporary(VT);
+
+ // Emit a store of each element to the stack slot.
+ std::vector<SDOperand> Stores;
+ bool isLittleEndian = TLI.isLittleEndian();
+ unsigned TypeByteSize =
+ MVT::getSizeInBits(Node->getOperand(0).getValueType())/8;
+ unsigned VectorSize = MVT::getSizeInBits(VT)/8;
+ // Store (in the right endianness) the elements to memory.
+ for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
+ // Ignore undef elements.
+ if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue;
+
+ unsigned Offset;
+ if (isLittleEndian)
+ Offset = TypeByteSize*i;
+ else
+ Offset = TypeByteSize*(e-i-1);
+
+ SDOperand Idx = DAG.getConstant(Offset, FIPtr.getValueType());
+ Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
+
+ Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+ Node->getOperand(i), Idx,
+ DAG.getSrcValue(NULL)));
+ }
+
+ SDOperand StoreChain;
+ if (!Stores.empty()) // Not all undef elements?
+ StoreChain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
+ else
+ StoreChain = DAG.getEntryNode();
+
+ // Result is a load from the stack slot.
+ return DAG.getLoad(VT, StoreChain, FIPtr, DAG.getSrcValue(0));
+}
+
+/// CreateStackTemporary - Create a stack temporary, suitable for holding the
+/// specified value type.
+SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
+ MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
+ unsigned ByteSize = MVT::getSizeInBits(VT)/8;
+ int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
+ return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
+}
+
void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
SDOperand Op, SDOperand Amt,
SDOperand &Lo, SDOperand &Hi) {
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.274 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.275
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.274 Sat Mar 18 18:52:58 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Mar 19 00:31:19 2006
@@ -1092,6 +1092,11 @@
if (OpOpcode == ISD::BIT_CONVERT) // bitconv(bitconv(x)) -> bitconv(x)
return getNode(ISD::BIT_CONVERT, VT, Operand.getOperand(0));
break;
+ case ISD::SCALAR_TO_VECTOR:
+ assert(MVT::isVector(VT) && !MVT::isVector(Operand.getValueType()) &&
+ MVT::getVectorBaseType(VT) == Operand.getValueType() &&
+ "Illegal SCALAR_TO_VECTOR node!");
+ break;
case ISD::FNEG:
if (OpOpcode == ISD::FSUB) // -(X-Y) -> (Y-X)
return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1),
@@ -1555,10 +1560,15 @@
// normal load.
if (ResultTys[0] == EVT)
return getLoad(ResultTys[0], Ops[0], Ops[1], Ops[2]);
- assert(EVT < ResultTys[0] &&
- "Should only be an extending load, not truncating!");
+ if (MVT::isVector(ResultTys[0])) {
+ assert(EVT == MVT::getVectorBaseType(ResultTys[0]) &&
+ "Invalid vector extload!");
+ } else {
+ assert(EVT < ResultTys[0] &&
+ "Should only be an extending load, not truncating!");
+ }
assert((Opcode == ISD::EXTLOAD || MVT::isInteger(ResultTys[0])) &&
- "Cannot sign/zero extend a FP load!");
+ "Cannot sign/zero extend a FP/Vector load!");
assert(MVT::isInteger(ResultTys[0]) == MVT::isInteger(EVT) &&
"Cannot convert from FP to Int or Int -> FP!");
break;
@@ -2654,6 +2664,7 @@
case ISD::SELECT_CC: return "select_cc";
case ISD::INSERT_VECTOR_ELT: return "insert_vector_elt";
case ISD::VINSERT_VECTOR_ELT: return "vinsert_vector_elt";
+ case ISD::SCALAR_TO_VECTOR: return "scalar_to_vector";
case ISD::ADDC: return "addc";
case ISD::ADDE: return "adde";
case ISD::SUBC: return "subc";
More information about the llvm-commits
mailing list