From: Nate Begeman Date: Tue, 6 Dec 2005 06:18:55 +0000 (+0000) Subject: Teach the SelectionDAG ISel how to turn ConstantPacked values into X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=8cfa57b1b4eade4e0101195b2f94ab288cd03563;p=oota-llvm.git Teach the SelectionDAG ISel how to turn ConstantPacked values into constant nodes with vector types. Also teach the asm printer how to print ConstantPacked constant pool entries. This allows us to generate altivec code such as the following, which adds a vector constantto a packed float. LCPI1_0: <4 x float> < float 0.0e+0, float 0.0e+0, float 0.0e+0, float 1.0e+0 > .space 4 .space 4 .space 4 .long 1065353216 ; float 1 .text .align 4 .globl _foo _foo: lis r2, ha16(LCPI1_0) la r2, lo16(LCPI1_0)(r2) li r4, 0 lvx v0, r4, r2 lvx v1, r4, r3 vaddfp v0, v1, v0 stvx v0, r4, r3 blr For the llvm code: void %foo(<4 x float> * %a) { entry: %tmp1 = load <4 x float> * %a; %tmp2 = add <4 x float> %tmp1, < float 0.0, float 0.0, float 0.0, float 1.0 > store <4 x float> %tmp2, <4 x float> *%a ret void } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24616 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index b9cfa1930ce..10b9050e268 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -67,6 +67,10 @@ namespace ISD { GlobalAddress, FrameIndex, ConstantPool, BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, Register, + // ConstantVec works like Constant or ConstantFP, except that it is not a + // leaf node. All operands are either Constant or ConstantFP nodes. + ConstantVec, + // TargetConstant - Like Constant, but the DAG does not do any folding or // simplification of the constant. This is used by the DAG->DAG selector. TargetConstant, diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 0e9802d5c1f..a9bd4ebd110 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/DerivedTypes.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Constants.h" #include "llvm/Module.h" @@ -326,6 +327,13 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) { } return; } + } else if (const ConstantPacked *CP = dyn_cast(CV)) { + const PackedType *PTy = CP->getType(); + + for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) + EmitGlobalConstant(CP->getOperand(I)); + + return; } const Type *type = CV->getType(); diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c02fc9ac69e..18da8168a94 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -690,6 +690,32 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } break; } + case ISD::ConstantVec: { + // We assume that vector constants are not legal, and will be immediately + // spilled to the constant pool. + // + // FIXME: revisit this when we have some kind of mechanism by which targets + // can decided legality of vector constants, of which there may be very + // many. + // + // Create a ConstantPacked, and put it in the constant pool. + std::vector CV; + MVT::ValueType VT = Node->getValueType(0); + for (unsigned I = 0, E = Node->getNumOperands(); I < E; ++I) { + SDOperand OpN = Node->getOperand(I); + const Type* OpNTy = MVT::getTypeForValueType(OpN.getValueType()); + if (MVT::isFloatingPoint(VT)) + CV.push_back(ConstantFP::get(OpNTy, + cast(OpN)->getValue())); + else + CV.push_back(ConstantUInt::get(OpNTy, + cast(OpN)->getValue())); + } + Constant *CP = ConstantPacked::get(CV); + SDOperand CPIdx = DAG.getConstantPool(CP, Node->getValueType(0)); + Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL)); + break; + } case ISD::TokenFactor: if (Node->getNumOperands() == 2) { bool Changed = false; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 0605352f9fc..f9ea84f3010 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -501,8 +501,6 @@ SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT) { return SDOperand(N, 0); } - - SDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV, MVT::ValueType VT, int offset) { SDNode *&N = GlobalValues[std::make_pair(GV, offset)]; @@ -1837,6 +1835,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { case ISD::Constant: return "Constant"; case ISD::TargetConstant: return "TargetConstant"; case ISD::ConstantFP: return "ConstantFP"; + case ISD::ConstantVec: return "ConstantVec"; case ISD::GlobalAddress: return "GlobalAddress"; case ISD::TargetGlobalAddress: return "TargetGlobalAddress"; case ISD::FrameIndex: return "FrameIndex"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 0f5743860da..97597e053f4 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -282,7 +282,8 @@ public: SDOperand &N = NodeMap[V]; if (N.Val) return N; - MVT::ValueType VT = TLI.getValueType(V->getType()); + const Type *VTy = V->getType(); + MVT::ValueType VT = TLI.getValueType(VTy); if (Constant *C = const_cast(dyn_cast(V))) if (ConstantExpr *CE = dyn_cast(C)) { visit(CE->getOpcode(), *CE); @@ -296,6 +297,30 @@ public: return N = DAG.getNode(ISD::UNDEF, VT); } else if (ConstantFP *CFP = dyn_cast(C)) { return N = DAG.getConstantFP(CFP->getValue(), VT); + } else if (const PackedType *PTy = dyn_cast(VTy)) { + unsigned NumElements = PTy->getNumElements(); + MVT::ValueType PVT = TLI.getValueType(PTy->getElementType()); + MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements); + + // Now that we know the number and type of the elements, push a + // Constant or ConstantFP node onto the ops list for each element of + // the packed constant. + std::vector Ops; + for (unsigned i = 0; i < NumElements; ++i) { + const Constant *CEl = C->getOperand(i); + if (MVT::isFloatingPoint(PVT)) + Ops.push_back(DAG.getConstantFP(cast(CEl)->getValue(), + PVT)); + else + Ops.push_back( + DAG.getConstant(cast(CEl)->getRawValue(), + PVT)); + } + // Handle the case where we have a 1-element vector, in which + // case we want to immediately turn it into a scalar constant. + if (Ops.size() == 1) + return N = Ops[0]; + return N = DAG.getNode(ISD::ConstantVec, TVT, Ops); } else { // Canonicalize all constant ints to be unsigned. return N = DAG.getConstant(cast(C)->getRawValue(),VT); @@ -784,8 +809,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) { const Type *Ty = I.getType(); SDOperand L; - if (Type::PackedTyID == Ty->getTypeID()) { - const PackedType *PTy = cast(Ty); + if (const PackedType *PTy = dyn_cast(Ty)) { unsigned NumElements = PTy->getNumElements(); MVT::ValueType PVT = TLI.getValueType(PTy->getElementType()); MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements);