Teach the SelectionDAG ISel how to turn ConstantPacked values into
authorNate Begeman <natebegeman@mac.com>
Tue, 6 Dec 2005 06:18:55 +0000 (06:18 +0000)
committerNate Begeman <natebegeman@mac.com>
Tue, 6 Dec 2005 06:18:55 +0000 (06:18 +0000)
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

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/AsmPrinter.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index b9cfa1930ce77b641eead28373a21dd88aaaef3f..10b9050e268fd6b35fb331e501d0a8b12a741cf0 100644 (file)
@@ -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,
index 0e9802d5c1fc58db146f26455018216dd7b7c4a7..a9bd4ebd1100cff872fd95f9c8365b4dd9e638b5 100644 (file)
@@ -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<ConstantPacked>(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();
index c02fc9ac69ef446ae45193b349f6bcf1f4ab3215..18da8168a946bab798427b01167e3bc520578f36 100644 (file)
@@ -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<Constant*> 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<ConstantFPSDNode>(OpN)->getValue()));
+      else
+        CV.push_back(ConstantUInt::get(OpNTy,
+                                       cast<ConstantSDNode>(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;
index 0605352f9fca7360f1c65350cc77aac973f05a94..f9ea84f3010caefe4d255c2c8cd6a01944b9581d 100644 (file)
@@ -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";
index 0f5743860daf208872a8d5d4a47feaf2e7c96dc4..97597e053f4cd612a878c3aa3e6cf5460d426f53 100644 (file)
@@ -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<Constant*>(dyn_cast<Constant>(V)))
       if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
         visit(CE->getOpcode(), *CE);
@@ -296,6 +297,30 @@ public:
         return N = DAG.getNode(ISD::UNDEF, VT);
       } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
         return N = DAG.getConstantFP(CFP->getValue(), VT);
+      } else if (const PackedType *PTy = dyn_cast<PackedType>(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<SDOperand> Ops;
+        for (unsigned i = 0; i < NumElements; ++i) {
+          const Constant *CEl = C->getOperand(i);
+          if (MVT::isFloatingPoint(PVT))
+            Ops.push_back(DAG.getConstantFP(cast<ConstantFP>(CEl)->getValue(), 
+                          PVT));
+          else
+            Ops.push_back(
+                    DAG.getConstant(cast<ConstantIntegral>(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<ConstantIntegral>(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<PackedType>(Ty);
+  if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
     unsigned NumElements = PTy->getNumElements();
     MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
     MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements);