diff options
author | Chris Lattner <sabre@nondot.org> | 2007-12-08 23:08:49 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-12-08 23:08:49 +0000 |
commit | 8a42aabcfb14c177e270ef42d7fde657bee6e5b0 (patch) | |
tree | 5a197d0d0f462f7f64ff0ffa8cafebea8e928c76 | |
parent | e089eb80bc47def3d8d3ab0b8c52cf0822588929 (diff) | |
download | external_llvm-8a42aabcfb14c177e270ef42d7fde657bee6e5b0.zip external_llvm-8a42aabcfb14c177e270ef42d7fde657bee6e5b0.tar.gz external_llvm-8a42aabcfb14c177e270ef42d7fde657bee6e5b0.tar.bz2 |
implement vector splitting of load, undef, and binops.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44724 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp | 88 |
2 files changed, 88 insertions, 4 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index ba39cc8..bd7aff5 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -273,6 +273,10 @@ private: // Result Vector Splitting: <128 x ty> -> 2 x <64 x ty>. void SplitResult(SDNode *N, unsigned OpNo); + + void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi); // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>. bool SplitOperand(SDNode *N, unsigned OpNo); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp index 79ef0b4..8be0c7c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp @@ -17,6 +17,24 @@ #include "LegalizeTypes.h" using namespace llvm; +/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector +/// type that needs to be split. This handles non-power of two vectors. +static void GetSplitDestVTs(MVT::ValueType InVT, + MVT::ValueType &Lo, MVT::ValueType &Hi) { + MVT::ValueType NewEltVT = MVT::getVectorElementType(InVT); + unsigned NumElements = MVT::getVectorNumElements(InVT); + if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector. + NumElements >>= 1; + Lo = Hi = MVT::getVectorType(NewEltVT, NumElements); + } else { // Non-power-of-two vectors. + unsigned NewNumElts_Lo = 1 << Log2_32(NumElements-1); + unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; + Lo = MVT::getVectorType(NewEltVT, NewNumElts_Lo); + Hi = MVT::getVectorType(NewEltVT, NewNumElts_Hi); + } +} + + //===----------------------------------------------------------------------===// // Result Vector Splitting //===----------------------------------------------------------------------===// @@ -29,7 +47,6 @@ using namespace llvm; void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n"); SDOperand Lo, Hi; - Lo = Hi = SDOperand(); #if 0 // See if the target wants to custom expand this node. @@ -54,9 +71,24 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { assert(0 && "Do not know how to split the result of this operator!"); abort(); -#if 0 - case ISD::UNDEF: SplitResult_UNDEF(N, Lo, Hi); break; -#endif + case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; + case ISD::LOAD: SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break; + case ISD::ADD: + case ISD::SUB: + case ISD::MUL: + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::FDIV: + case ISD::FPOW: + case ISD::AND: + case ISD::OR: + case ISD::XOR: + case ISD::UREM: + case ISD::SREM: + case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break; } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -64,6 +96,54 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { SetSplitOp(SDOperand(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + + Lo = DAG.getNode(ISD::UNDEF, LoVT); + Hi = DAG.getNode(ISD::UNDEF, HiVT); +} + +void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT); + + SDOperand Ch = LD->getChain(); + SDOperand Ptr = LD->getBasePtr(); + const Value *SV = LD->getSrcValue(); + int SVOffset = LD->getSrcValueOffset(); + unsigned Alignment = LD->getAlignment(); + bool isVolatile = LD->isVolatile(); + + Lo = DAG.getLoad(LoVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); + unsigned IncrementSize = MVT::getSizeInBits(LoVT)/8; + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + SVOffset += IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); + Hi = DAG.getLoad(HiVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); + + // Build a factor node to remember that this load is independent of the + // other one. + SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(LD, 1), TF); +} + +void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + SDOperand LHSLo, LHSHi; + GetSplitOp(N->getOperand(0), LHSLo, LHSHi); + SDOperand RHSLo, RHSHi; + GetSplitOp(N->getOperand(1), RHSLo, RHSHi); + + Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo); + Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi); +} + //===----------------------------------------------------------------------===// // Operand Vector Splitting |