From 3d613421f196b8dd127bedf7e68a323994016d38 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Thu, 27 Mar 2008 20:23:40 +0000 Subject: [PATCH] Implement LegalizeTypes support for softfloat LOAD. 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. llvm-svn: 48894 --- include/llvm/CodeGen/SelectionDAG.h | 5 + lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 + .../SelectionDAG/LegalizeTypesFloatToInt.cpp | 11 ++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 138 +++++++----------- 4 files changed, 73 insertions(+), 82 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 5434fb632b4..d0e03d4d245 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -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. /// diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 48d4b391fb5..7d245abed59 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -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); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp index 53f3143fca0..3c988989152 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp @@ -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(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.. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b01b5251a24..d39773ea8fe 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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,69 +2461,38 @@ SDOperand SelectionDAG::getLoad(MVT::ValueType VT, const PointerType *PT = dyn_cast(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(ISD::NON_EXTLOAD); - ID.AddInteger((unsigned int)VT); - 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); - CSEMap.InsertNode(N, IP); - AllNodes.push_back(N); - return SDOperand(N, 0); -} -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(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); + 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!"); } - SDVTList VTs = getVTList(VT, MVT::Other); - SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType()); - SDOperand Ops[] = { Chain, Ptr, Undef }; + + 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(AM); ID.AddInteger(ExtType); ID.AddInteger((unsigned int)EVT); ID.AddInteger(Alignment); @@ -2529,39 +2500,42 @@ SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT, 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); + 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) { + SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType()); + return getAnyLoad(ISD::UNINDEXED, ExtType, VT, Chain, Ptr, Undef, + SV, SVOffset, EVT, isVolatile, Alignment); +} + SDOperand SelectionDAG::getIndexedLoad(SDOperand OrigLoad, SDOperand Base, SDOperand Offset, ISD::MemIndexedMode AM) { LoadSDNode *LD = cast(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,