[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp
Nate Begeman
natebegeman at mac.com
Fri Nov 18 16:36:50 PST 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.209 -> 1.210
SelectionDAG.cpp updated: 1.212 -> 1.213
SelectionDAGISel.cpp updated: 1.101 -> 1.102
---
Log message:
Teach LLVM how to scalarize packed types. Currently, this only works on
packed types with an element count of 1, although more generic support is
coming. This allows LLVM to turn the following code:
void %foo(<1 x float> * %a) {
entry:
%tmp1 = load <1 x float> * %a;
%tmp2 = add <1 x float> %tmp1, %tmp1
store <1 x float> %tmp2, <1 x float> *%a
ret void
}
Into:
_foo:
lfs f0, 0(r3)
fadds f0, f0, f0
stfs f0, 0(r3)
blr
---
Diffs of the changes: (+110 -33)
LegalizeDAG.cpp | 53 ++++++++++++++++++++++++++++++++++++++-
SelectionDAG.cpp | 21 +++++++++++++++
SelectionDAGISel.cpp | 69 +++++++++++++++++++++++++++------------------------
3 files changed, 110 insertions(+), 33 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.209 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.210
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.209 Thu Nov 17 00:41:44 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Nov 18 18:36:38 2005
@@ -149,6 +149,15 @@
};
}
+static unsigned scalarizedOpcode(unsigned VecOp, MVT::ValueType VT) {
+ switch (VecOp) {
+ default: assert(0 && "Don't know how to scalarize this opcode!");
+ break;
+ case ISD::VADD: return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD;
+ case ISD::VSUB: return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB;
+ case ISD::VMUL: return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL;
+ }
+}
SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)
: TLI(dag.getTargetLoweringInfo()), DAG(dag),
@@ -914,7 +923,27 @@
AddLegalizedOperand(SDOperand(Node, 0), Result);
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
return Result.getValue(Op.ResNo);
-
+
+ case ISD::VLOAD:
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
+
+ // If we just have one element, scalarize the result. Otherwise, check to
+ // see if we support this operation on this type at this width. If not,
+ // split the vector in half and try again.
+ if (1 == cast<ConstantSDNode>(Node->getOperand(2))->getValue()) {
+ MVT::ValueType SVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
+ Result = LegalizeOp(DAG.getLoad(SVT, Tmp1, Tmp2, Node->getOperand(4)));
+ } else {
+ assert(0 && "Expand case for vectors unimplemented");
+ }
+
+ // Since loads produce two values, make sure to remember that we legalized
+ // both of them.
+ AddLegalizedOperand(SDOperand(Node, 0), Result);
+ AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+ return Result.getValue(Op.ResNo);
+
case ISD::EXTLOAD:
case ISD::SEXTLOAD:
case ISD::ZEXTLOAD: {
@@ -1654,6 +1683,28 @@
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,Tmp2);
break;
+ // Vector binary operators
+ case ISD::VADD:
+ case ISD::VSUB:
+ case ISD::VMUL: {
+ Tmp1 = Node->getOperand(0); // Element Count
+ Tmp2 = Node->getOperand(1); // Element Type
+
+ // If we just have one element, scalarize the result. Otherwise, check to
+ // see if we support this operation on this type at this width. If not,
+ // split the vector in half and try again.
+ if (1 == cast<ConstantSDNode>(Tmp1)->getValue()) {
+ MVT::ValueType SVT = cast<VTSDNode>(Tmp2)->getVT();
+
+ Result = DAG.getNode(scalarizedOpcode(Node->getOpcode(), SVT), SVT,
+ LegalizeOp(Node->getOperand(2)),
+ LegalizeOp(Node->getOperand(3)));
+ } else {
+ assert(0 && "Expand case for vectors unimplemented");
+ }
+ break;
+ }
+
case ISD::BUILD_PAIR: {
MVT::ValueType PairTy = Node->getValueType(0);
// TODO: handle the case where the Lo and Hi operands are not of legal type
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.212 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.213
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.212 Fri Nov 11 10:46:18 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Nov 18 18:36:38 2005
@@ -1092,6 +1092,23 @@
return SDOperand(N, 0);
}
+SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT,
+ SDOperand Chain, SDOperand Ptr,
+ SDOperand SV) {
+ SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, EVT))];
+ if (N) return SDOperand(N, 0);
+ std::vector<SDOperand> Ops;
+ Ops.reserve(5);
+ Ops.push_back(Chain);
+ Ops.push_back(Ptr);
+ Ops.push_back(getConstant(Count, MVT::i32));
+ Ops.push_back(getValueType(EVT));
+ Ops.push_back(SV);
+ std::vector<MVT::ValueType> VTs;
+ VTs.reserve(2);
+ VTs.push_back(EVT); VTs.push_back(MVT::Other); // Add token chain.
+ return getNode(ISD::VLOAD, VTs, Ops);
+}
SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT,
SDOperand Chain, SDOperand Ptr, SDOperand SV,
@@ -1677,6 +1694,9 @@
case ISD::FMUL: return "fmul";
case ISD::FDIV: return "fdiv";
case ISD::FREM: return "frem";
+ case ISD::VADD: return "vadd";
+ case ISD::VSUB: return "vsub";
+ case ISD::VMUL: return "vmul";
case ISD::SETCC: return "setcc";
case ISD::SELECT: return "select";
@@ -1717,6 +1737,7 @@
// Other operators
case ISD::LOAD: return "load";
case ISD::STORE: return "store";
+ case ISD::VLOAD: return "vload";
case ISD::EXTLOAD: return "extload";
case ISD::SEXTLOAD: return "sextload";
case ISD::ZEXTLOAD: return "zextload";
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.101 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.102
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.101 Fri Nov 18 01:42:56 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Nov 18 18:36:38 2005
@@ -347,40 +347,26 @@
void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); }
//
- void visitBinary(User &I, unsigned Opcode);
+ void visitBinary(User &I, unsigned IntOp, unsigned FPOp, unsigned VecOp);
void visitShift(User &I, unsigned Opcode);
- void visitAdd(User &I) {
- visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FADD : ISD::ADD);
+ void visitAdd(User &I) {
+ visitBinary(I, ISD::ADD, ISD::FADD, ISD::VADD);
}
void visitSub(User &I);
- void visitMul(User &I) {
- visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FMUL : ISD::MUL);
+ void visitMul(User &I) {
+ visitBinary(I, ISD::MUL, ISD::FMUL, ISD::VMUL);
}
void visitDiv(User &I) {
- unsigned Opc;
const Type *Ty = I.getType();
- if (Ty->isFloatingPoint())
- Opc = ISD::FDIV;
- else if (Ty->isUnsigned())
- Opc = ISD::UDIV;
- else
- Opc = ISD::SDIV;
- visitBinary(I, Opc);
+ visitBinary(I, Ty->isSigned() ? ISD::SDIV : ISD::UDIV, ISD::FDIV, 0);
}
void visitRem(User &I) {
- unsigned Opc;
const Type *Ty = I.getType();
- if (Ty->isFloatingPoint())
- Opc = ISD::FREM;
- else if (Ty->isUnsigned())
- Opc = ISD::UREM;
- else
- Opc = ISD::SREM;
- visitBinary(I, Opc);
+ visitBinary(I, Ty->isSigned() ? ISD::SREM : ISD::UREM, ISD::FREM, 0);
}
- void visitAnd(User &I) { visitBinary(I, ISD::AND); }
- void visitOr (User &I) { visitBinary(I, ISD::OR); }
- void visitXor(User &I) { visitBinary(I, ISD::XOR); }
+ void visitAnd(User &I) { visitBinary(I, ISD::AND, 0, 0); }
+ void visitOr (User &I) { visitBinary(I, ISD::OR, 0, 0); }
+ void visitXor(User &I) { visitBinary(I, ISD::XOR, 0, 0); }
void visitShl(User &I) { visitShift(I, ISD::SHL); }
void visitShr(User &I) {
visitShift(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA);
@@ -515,17 +501,26 @@
setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
return;
}
- visitBinary(I, ISD::FSUB);
- } else {
- visitBinary(I, ISD::SUB);
}
+ visitBinary(I, ISD::SUB, ISD::FSUB, ISD::VSUB);
}
-void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode) {
+void SelectionDAGLowering::visitBinary(User &I, unsigned IntOp, unsigned FPOp,
+ unsigned VecOp) {
+ const Type *Ty = I.getType();
SDOperand Op1 = getValue(I.getOperand(0));
SDOperand Op2 = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
+ if (Ty->isInteger()) {
+ setValue(&I, DAG.getNode(IntOp, Op1.getValueType(), Op1, Op2));
+ } else if (Ty->isFloatingPoint()) {
+ setValue(&I, DAG.getNode(FPOp, Op1.getValueType(), Op1, Op2));
+ } else {
+ const PackedType *PTy = cast<PackedType>(Ty);
+ SDOperand Num = DAG.getConstant(PTy->getNumElements(), MVT::i32);
+ SDOperand Typ = DAG.getValueType(TLI.getValueType(PTy->getElementType()));
+ setValue(&I, DAG.getNode(VecOp, Op1.getValueType(), Num, Typ, Op1, Op2));
+ }
}
void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
@@ -725,9 +720,19 @@
// Do not serialize non-volatile loads against each other.
Root = DAG.getRoot();
}
-
- SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), Root, Ptr,
- DAG.getSrcValue(I.getOperand(0)));
+
+ const Type *Ty = I.getType();
+ SDOperand L;
+
+ if (Type::PackedTyID == Ty->getTypeID()) {
+ const PackedType *PTy = cast<PackedType>(Ty);
+ L = DAG.getVecLoad(PTy->getNumElements(),
+ TLI.getValueType(PTy->getElementType()), Root, Ptr,
+ DAG.getSrcValue(I.getOperand(0)));
+ } else {
+ L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr,
+ DAG.getSrcValue(I.getOperand(0)));
+ }
setValue(&I, L);
if (I.isVolatile())
More information about the llvm-commits
mailing list