OSDN Git Service

Implement LegalizeTypes support for softfloat LOAD.
authorDuncan Sands <baldrick@free.fr>
Thu, 27 Mar 2008 20:23:40 +0000 (20:23 +0000)
committerDuncan Sands <baldrick@free.fr>
Thu, 27 Mar 2008 20:23:40 +0000 (20:23 +0000)
In order to handle indexed nodes I had to introduce
a new constructor, and since I was there I factorized
the code in the various load constructors.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48894 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/LegalizeTypes.h
lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 5434fb6..d0e03d4 100644 (file)
@@ -379,6 +379,11 @@ public:
                        unsigned Alignment=0);
   SDOperand getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
                            SDOperand Offset, ISD::MemIndexedMode AM);
+  SDOperand getAnyLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+                       MVT::ValueType VT, SDOperand Chain,
+                       SDOperand Ptr, SDOperand Offset,
+                       const Value *SV, int SVOffset, MVT::ValueType EVT,
+                       bool isVolatile=false, unsigned Alignment=0);
 
   /// getStore - Helper function to build ISD::STORE nodes.
   ///
index 48d4b39..7d245ab 100644 (file)
@@ -310,6 +310,7 @@ private:
   SDOperand FloatToIntRes_BIT_CONVERT(SDNode *N);
   SDOperand FloatToIntRes_BUILD_PAIR(SDNode *N);
   SDOperand FloatToIntRes_FCOPYSIGN(SDNode *N);
+  SDOperand FloatToIntRes_LOAD(SDNode *N);
 
   // Operand Float to Integer Conversion.
   bool FloatToIntOperand(SDNode *N, unsigned OpNo);
index 53f3143..3c98898 100644 (file)
@@ -53,6 +53,7 @@ void DAGTypeLegalizer::FloatToIntResult(SDNode *N, unsigned ResNo) {
     case ISD::BIT_CONVERT: R = FloatToIntRes_BIT_CONVERT(N); break;
     case ISD::BUILD_PAIR:  R = FloatToIntRes_BUILD_PAIR(N); break;
     case ISD::FCOPYSIGN:   R = FloatToIntRes_FCOPYSIGN(N); break;
+    case ISD::LOAD:        R = FloatToIntRes_LOAD(N); break;
   }
 
   // If R is null, the sub-method took care of registering the result.
@@ -111,6 +112,16 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_FCOPYSIGN(SDNode *N) {
   return DAG.getNode(ISD::OR, LVT, LHS, SignBit);
 }
 
+SDOperand DAGTypeLegalizer::FloatToIntRes_LOAD(SDNode *N) {
+  MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  LoadSDNode *L = cast<LoadSDNode>(N);
+
+  return DAG.getAnyLoad(L->getAddressingMode(), L->getExtensionType(),
+                        NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
+                        L->getSrcValue(), L->getSrcValueOffset(),
+                        L->getMemoryVT(), L->isVolatile(), L->getAlignment());
+}
+
 
 //===----------------------------------------------------------------------===//
 //  Operand Float to Integer Conversion..
index b01b525..d39773e 100644 (file)
@@ -2447,10 +2447,12 @@ SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain,
   return SDOperand(N, 0);
 }
 
-SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
-                                SDOperand Chain, SDOperand Ptr,
-                                const Value *SV, int SVOffset,
-                                bool isVolatile, unsigned Alignment) {
+SDOperand
+SelectionDAG::getAnyLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+                         MVT::ValueType VT, SDOperand Chain,
+                         SDOperand Ptr, SDOperand Offset,
+                         const Value *SV, int SVOffset, MVT::ValueType EVT,
+                         bool isVolatile, unsigned Alignment) {
   if (Alignment == 0) { // Ensure that codegen never sees alignment 0
     const Type *Ty = 0;
     if (VT != MVT::iPTR) {
@@ -2459,81 +2461,69 @@ SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
       const PointerType *PT = dyn_cast<PointerType>(SV->getType());
       assert(PT && "Value for load must be a pointer");
       Ty = PT->getElementType();
-    }  
+    }
     assert(Ty && "Could not get type information for load");
     Alignment = TLI.getTargetData()->getABITypeAlignment(Ty);
   }
-  SDVTList VTs = getVTList(VT, MVT::Other);
-  SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
-  SDOperand Ops[] = { Chain, Ptr, Undef };
+
+  if (VT == EVT) {
+    ExtType = ISD::NON_EXTLOAD;
+  } else if (ExtType == ISD::NON_EXTLOAD) {
+    assert(VT == EVT && "Non-extending load from different memory type!");
+  } else {
+    // Extending load.
+    if (MVT::isVector(VT))
+      assert(EVT == MVT::getVectorElementType(VT) && "Invalid vector extload!");
+    else
+      assert(MVT::getSizeInBits(EVT) < MVT::getSizeInBits(VT) &&
+             "Should only be an extending load, not truncating!");
+    assert((ExtType == ISD::EXTLOAD || MVT::isInteger(VT)) &&
+           "Cannot sign/zero extend a FP/Vector load!");
+    assert(MVT::isInteger(VT) == MVT::isInteger(EVT) &&
+           "Cannot convert from FP to Int or Int -> FP!");
+  }
+
+  bool Indexed = AM != ISD::UNINDEXED;
+  assert(Indexed || Offset.getOpcode() == ISD::UNDEF &&
+         "Unindexed load with an offset!");
+
+  SDVTList VTs = Indexed ?
+    getVTList(VT, Ptr.getValueType(), MVT::Other) : getVTList(VT, MVT::Other);
+  SDOperand Ops[] = { Chain, Ptr, Offset };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
-  ID.AddInteger(ISD::UNINDEXED);
-  ID.AddInteger(ISD::NON_EXTLOAD);
-  ID.AddInteger((unsigned int)VT);
+  ID.AddInteger(AM);
+  ID.AddInteger(ExtType);
+  ID.AddInteger((unsigned int)EVT);
   ID.AddInteger(Alignment);
   ID.AddInteger(isVolatile);
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDOperand(E, 0);
-  SDNode *N = new LoadSDNode(Ops, VTs, ISD::UNINDEXED,
-                             ISD::NON_EXTLOAD, VT, SV, SVOffset, Alignment,
-                             isVolatile);
+  SDNode *N = new LoadSDNode(Ops, VTs, AM, ExtType, EVT, SV, SVOffset,
+                             Alignment, isVolatile);
   CSEMap.InsertNode(N, IP);
   AllNodes.push_back(N);
   return SDOperand(N, 0);
 }
 
+SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
+                                SDOperand Chain, SDOperand Ptr,
+                                const Value *SV, int SVOffset,
+                                bool isVolatile, unsigned Alignment) {
+  SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
+  return getAnyLoad(ISD::UNINDEXED, ISD::NON_EXTLOAD, VT, Chain, Ptr, Undef,
+                    SV, SVOffset, VT, isVolatile, Alignment);
+}
+
 SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
                                    SDOperand Chain, SDOperand Ptr,
                                    const Value *SV,
                                    int SVOffset, MVT::ValueType EVT,
                                    bool isVolatile, unsigned Alignment) {
-  // If they are asking for an extending load from/to the same thing, return a
-  // normal load.
-  if (VT == EVT)
-    return getLoad(VT, Chain, Ptr, SV, SVOffset, isVolatile, Alignment);
-
-  if (MVT::isVector(VT))
-    assert(EVT == MVT::getVectorElementType(VT) && "Invalid vector extload!");
-  else
-    assert(MVT::getSizeInBits(EVT) < MVT::getSizeInBits(VT) &&
-           "Should only be an extending load, not truncating!");
-  assert((ExtType == ISD::EXTLOAD || MVT::isInteger(VT)) &&
-         "Cannot sign/zero extend a FP/Vector load!");
-  assert(MVT::isInteger(VT) == MVT::isInteger(EVT) &&
-         "Cannot convert from FP to Int or Int -> FP!");
-
-  if (Alignment == 0) { // Ensure that codegen never sees alignment 0
-    const Type *Ty = 0;
-    if (VT != MVT::iPTR) {
-      Ty = MVT::getTypeForValueType(VT);
-    } else if (SV) {
-      const PointerType *PT = dyn_cast<PointerType>(SV->getType());
-      assert(PT && "Value for load must be a pointer");
-      Ty = PT->getElementType();
-    }  
-    assert(Ty && "Could not get type information for load");
-    Alignment = TLI.getTargetData()->getABITypeAlignment(Ty);
-  }
-  SDVTList VTs = getVTList(VT, MVT::Other);
   SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
-  SDOperand Ops[] = { Chain, Ptr, Undef };
-  FoldingSetNodeID ID;
-  AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
-  ID.AddInteger(ISD::UNINDEXED);
-  ID.AddInteger(ExtType);
-  ID.AddInteger((unsigned int)EVT);
-  ID.AddInteger(Alignment);
-  ID.AddInteger(isVolatile);
-  void *IP = 0;
-  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
-    return SDOperand(E, 0);
-  SDNode *N = new LoadSDNode(Ops, VTs, ISD::UNINDEXED, ExtType, EVT,
-                             SV, SVOffset, Alignment, isVolatile);
-  CSEMap.InsertNode(N, IP);
-  AllNodes.push_back(N);
-  return SDOperand(N, 0);
+  return getAnyLoad(ISD::UNINDEXED, ExtType, VT, Chain, Ptr, Undef,
+                    SV, SVOffset, EVT, isVolatile, Alignment);
 }
 
 SDOperand
@@ -2542,26 +2532,10 @@ SelectionDAG::getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
   LoadSDNode *LD = cast<LoadSDNode>(OrigLoad);
   assert(LD->getOffset().getOpcode() == ISD::UNDEF &&
          "Load is already a indexed load!");
-  MVT::ValueType VT = OrigLoad.getValueType();
-  SDVTList VTs = getVTList(VT, Base.getValueType(), MVT::Other);
-  SDOperand Ops[] = { LD->getChain(), Base, Offset };
-  FoldingSetNodeID ID;
-  AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
-  ID.AddInteger(AM);
-  ID.AddInteger(LD->getExtensionType());
-  ID.AddInteger((unsigned int)(LD->getMemoryVT()));
-  ID.AddInteger(LD->getAlignment());
-  ID.AddInteger(LD->isVolatile());
-  void *IP = 0;
-  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
-    return SDOperand(E, 0);
-  SDNode *N = new LoadSDNode(Ops, VTs, AM,
-                             LD->getExtensionType(), LD->getMemoryVT(),
-                             LD->getSrcValue(), LD->getSrcValueOffset(),
-                             LD->getAlignment(), LD->isVolatile());
-  CSEMap.InsertNode(N, IP);
-  AllNodes.push_back(N);
-  return SDOperand(N, 0);
+  return getAnyLoad(AM, LD->getExtensionType(), OrigLoad.getValueType(),
+                    LD->getChain(), Base, Offset, LD->getSrcValue(),
+                    LD->getSrcValueOffset(), LD->getMemoryVT(),
+                    LD->isVolatile(), LD->getAlignment());
 }
 
 SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val,