diff options
author | Duncan Sands <baldrick@free.fr> | 2008-06-15 20:00:14 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-06-15 20:00:14 +0000 |
commit | 7d0d8460646d1a06ff561775d40123a4cf65bf4d (patch) | |
tree | 5808f02d1bfc436c66c36f4397f4c28869c9a94c | |
parent | 8a08769bad43a22fae2845bb0ba0fd1266cd55c8 (diff) |
LegalizeTypes support for INSERT_VECTOR_ELT with
a non-constant index.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52292 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.h | 10 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp | 58 |
3 files changed, 59 insertions, 26 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 16c86936a6..5b37c75f1f 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -577,6 +577,23 @@ SDOperand DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT, return CallInfo.first; } +SDOperand DAGTypeLegalizer::GetVectorElementPointer(SDOperand VecPtr, MVT EltVT, + SDOperand Index) { + // Make sure the index type is big enough to compute in. + if (Index.getValueType().bitsGT(TLI.getPointerTy())) + Index = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Index); + else + Index = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Index); + + // Calculate the element offset and add it to the pointer. + unsigned EltSize = EltVT.getSizeInBits() / 8; // FIXME: should be ABI size. + + Index = DAG.getNode(ISD::MUL, Index.getValueType(), Index, + DAG.getConstant(EltSize, Index.getValueType())); + return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr); +} + + //===----------------------------------------------------------------------===// // Entry Point //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 09ccfe9938..ba8f106935 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -169,14 +169,18 @@ private: void ExpungeNode(SDOperand N); // Common routines. - SDOperand BitConvertToInteger(SDOperand Op); SDOperand CreateStackStoreLoad(SDOperand Op, MVT DestVT); + SDOperand MakeLibCall(RTLIB::Libcall LC, MVT RetVT, + const SDOperand *Ops, unsigned NumOps, bool isSigned); + + SDOperand BitConvertToInteger(SDOperand Op); SDOperand JoinIntegers(SDOperand Lo, SDOperand Hi); void SplitInteger(SDOperand Op, SDOperand &Lo, SDOperand &Hi); void SplitInteger(SDOperand Op, MVT LoVT, MVT HiVT, SDOperand &Lo, SDOperand &Hi); - SDOperand MakeLibCall(RTLIB::Libcall LC, MVT RetVT, - const SDOperand *Ops, unsigned NumOps, bool isSigned); + + SDOperand GetVectorElementPointer(SDOperand VecPtr, MVT EltVT, + SDOperand Index); //===--------------------------------------------------------------------===// // Promotion Support: LegalizeTypesPromote.cpp diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp index 0e3c00dd60..74aae7f4c8 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp @@ -162,16 +162,37 @@ void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - GetSplitOp(N->getOperand(0), Lo, Hi); - unsigned Index = cast<ConstantSDNode>(N->getOperand(2))->getValue(); - SDOperand ScalarOp = N->getOperand(1); - unsigned LoNumElts = Lo.getValueType().getVectorNumElements(); - if (Index < LoNumElts) - Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, ScalarOp, - N->getOperand(2)); - else - Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, ScalarOp, - DAG.getIntPtrConstant(Index - LoNumElts)); + SDOperand Vec = N->getOperand(0); + SDOperand Elt = N->getOperand(1); + SDOperand Idx = N->getOperand(2); + GetSplitOp(Vec, Lo, Hi); + + if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) { + unsigned IdxVal = CIdx->getValue(); + unsigned LoNumElts = Lo.getValueType().getVectorNumElements(); + if (IdxVal < LoNumElts) + Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, Elt, Idx); + else + Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, Elt, + DAG.getIntPtrConstant(IdxVal - LoNumElts)); + return; + } + + // Spill the vector to the stack. + MVT VecVT = Vec.getValueType(); + SDOperand StackPtr = DAG.CreateStackTemporary(VecVT); + SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0); + + // Store the new element. + SDOperand EltPtr = GetVectorElementPointer(StackPtr, + VecVT.getVectorElementType(), Idx); + Store = DAG.getStore(Store, Elt, EltPtr, NULL, 0); + + // Reload the vector from the stack. + SDOperand Load = DAG.getLoad(VecVT, Store, StackPtr, NULL, 0); + + // Split it. + SplitRes_LOAD(cast<LoadSDNode>(Load.Val), Lo, Hi); } void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N, @@ -473,22 +494,13 @@ SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) { Idx.getValueType())); } - // Store the vector to the stack and load back the required element. + // Store the vector to the stack. + MVT EltVT = VecVT.getVectorElementType(); SDOperand StackPtr = DAG.CreateStackTemporary(VecVT); SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0); - // Add the offset to the index. - MVT EltVT = VecVT.getVectorElementType(); - unsigned EltSize = EltVT.getSizeInBits()/8; // FIXME: should be ABI size. - Idx = DAG.getNode(ISD::MUL, Idx.getValueType(), Idx, - DAG.getConstant(EltSize, Idx.getValueType())); - - if (Idx.getValueType().bitsGT(TLI.getPointerTy())) - Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx); - else - Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx); - - StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr); + // Load back the required element. + StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0); } |