aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-12-08 23:08:49 +0000
committerChris Lattner <sabre@nondot.org>2007-12-08 23:08:49 +0000
commit8a42aabcfb14c177e270ef42d7fde657bee6e5b0 (patch)
tree5a197d0d0f462f7f64ff0ffa8cafebea8e928c76
parente089eb80bc47def3d8d3ab0b8c52cf0822588929 (diff)
downloadexternal_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.h4
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp88
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