c9bf70a3bca6eb75952b5207d1fbd7bf0823bca0
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeTypesSplit.cpp
1 //===-- LegalizeTypesSplit.cpp - Vector Splitting for LegalizeTypes -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Chris Lattner and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements vector splitting support for LegalizeTypes.  Vector
11 // splitting is the act of changing a computation in an invalid vector type to
12 // be a computation in multiple vectors of a smaller type.  For example,
13 // implementing <128 x f32> operations in terms of two <64 x f32> operations.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "LegalizeTypes.h"
18 using namespace llvm;
19
20 /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector
21 /// type that needs to be split.  This handles non-power of two vectors.
22 static void GetSplitDestVTs(MVT::ValueType InVT,
23                             MVT::ValueType &Lo, MVT::ValueType &Hi) {
24   MVT::ValueType NewEltVT = MVT::getVectorElementType(InVT);
25   unsigned NumElements = MVT::getVectorNumElements(InVT);
26   if ((NumElements & (NumElements-1)) == 0) {  // Simple power of two vector.
27     NumElements >>= 1;
28     Lo = Hi =  MVT::getVectorType(NewEltVT, NumElements);
29   } else {                                     // Non-power-of-two vectors.
30     unsigned NewNumElts_Lo = 1 << Log2_32(NumElements-1);
31     unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo;
32     Lo = MVT::getVectorType(NewEltVT, NewNumElts_Lo);
33     Hi = MVT::getVectorType(NewEltVT, NewNumElts_Hi);
34   }
35 }
36
37
38 //===----------------------------------------------------------------------===//
39 //  Result Vector Splitting
40 //===----------------------------------------------------------------------===//
41
42 /// SplitResult - This method is called when the specified result of the
43 /// specified node is found to need vector splitting.  At this point, the node
44 /// may also have invalid operands or may have other results that need
45 /// legalization, we just know that (at least) one result needs vector
46 /// splitting.
47 void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
48   DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n");
49   SDOperand Lo, Hi;
50   
51 #if 0
52   // See if the target wants to custom expand this node.
53   if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
54       TargetLowering::Custom) {
55     // If the target wants to, allow it to lower this itself.
56     if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
57       // Everything that once used N now uses P.  We are guaranteed that the
58       // result value types of N and the result value types of P match.
59       ReplaceNodeWith(N, P);
60       return;
61     }
62   }
63 #endif
64   
65   switch (N->getOpcode()) {
66   default:
67 #ifndef NDEBUG
68     cerr << "SplitResult #" << ResNo << ": ";
69     N->dump(&DAG); cerr << "\n";
70 #endif
71     assert(0 && "Do not know how to split the result of this operator!");
72     abort();
73     
74   case ISD::UNDEF:       SplitRes_UNDEF(N, Lo, Hi); break;
75   case ISD::LOAD:        SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
76   case ISD::ADD:
77   case ISD::SUB:
78   case ISD::MUL:
79   case ISD::FADD:
80   case ISD::FSUB:
81   case ISD::FMUL:
82   case ISD::SDIV:
83   case ISD::UDIV:
84   case ISD::FDIV:
85   case ISD::FPOW:
86   case ISD::AND:
87   case ISD::OR:
88   case ISD::XOR:
89   case ISD::UREM:
90   case ISD::SREM:
91   case ISD::FREM:        SplitRes_BinOp(N, Lo, Hi); break;
92   }
93   
94   // If Lo/Hi is null, the sub-method took care of registering results etc.
95   if (Lo.Val)
96     SetSplitOp(SDOperand(N, ResNo), Lo, Hi);
97 }
98
99 void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
100   MVT::ValueType LoVT, HiVT;
101   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
102
103   Lo = DAG.getNode(ISD::UNDEF, LoVT);
104   Hi = DAG.getNode(ISD::UNDEF, HiVT);
105 }
106
107 void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD, 
108                                      SDOperand &Lo, SDOperand &Hi) {
109   MVT::ValueType LoVT, HiVT;
110   GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
111   
112   SDOperand Ch = LD->getChain();
113   SDOperand Ptr = LD->getBasePtr();
114   const Value *SV = LD->getSrcValue();
115   int SVOffset = LD->getSrcValueOffset();
116   unsigned Alignment = LD->getAlignment();
117   bool isVolatile = LD->isVolatile();
118   
119   Lo = DAG.getLoad(LoVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
120   unsigned IncrementSize = MVT::getSizeInBits(LoVT)/8;
121   Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
122                     getIntPtrConstant(IncrementSize));
123   SVOffset += IncrementSize;
124   Alignment = MinAlign(Alignment, IncrementSize);
125   Hi = DAG.getLoad(HiVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
126   
127   // Build a factor node to remember that this load is independent of the
128   // other one.
129   SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
130                              Hi.getValue(1));
131   
132   // Legalized the chain result - switch anything that used the old chain to
133   // use the new one.
134   ReplaceValueWith(SDOperand(LD, 1), TF);
135 }
136
137 void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
138   SDOperand LHSLo, LHSHi;
139   GetSplitOp(N->getOperand(0), LHSLo, LHSHi);
140   SDOperand RHSLo, RHSHi;
141   GetSplitOp(N->getOperand(1), RHSLo, RHSHi);
142   
143   Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo);
144   Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
145 }
146
147
148 //===----------------------------------------------------------------------===//
149 //  Operand Vector Splitting
150 //===----------------------------------------------------------------------===//
151
152 /// SplitOperand - This method is called when the specified operand of the
153 /// specified node is found to need vector splitting.  At this point, all of the
154 /// result types of the node are known to be legal, but other operands of the
155 /// node may need legalization as well as the specified one.
156 bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
157   DEBUG(cerr << "Split node operand: "; N->dump(&DAG); cerr << "\n");
158   SDOperand Res(0, 0);
159   
160 #if 0
161   if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
162       TargetLowering::Custom)
163     Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
164 #endif
165   
166   if (Res.Val == 0) {
167     switch (N->getOpcode()) {
168     default:
169 #ifndef NDEBUG
170       cerr << "SplitOperand Op #" << OpNo << ": ";
171       N->dump(&DAG); cerr << "\n";
172 #endif
173       assert(0 && "Do not know how to split this operator's operand!");
174       abort();
175     case ISD::STORE:
176       Res = SplitOperand_STORE(cast<StoreSDNode>(N), OpNo);
177       break;
178     }
179   }
180   
181   // If the result is null, the sub-method took care of registering results etc.
182   if (!Res.Val) return false;
183   
184   // If the result is N, the sub-method updated N in place.  Check to see if any
185   // operands are new, and if so, mark them.
186   if (Res.Val == N) {
187     // Mark N as new and remark N and its operands.  This allows us to correctly
188     // revisit N if it needs another step of promotion and allows us to visit
189     // any new operands to N.
190     N->setNodeId(NewNode);
191     MarkNewNodes(N);
192     return true;
193   }
194   
195   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
196          "Invalid operand expansion");
197   
198   ReplaceValueWith(SDOperand(N, 0), Res);
199   return false;
200 }
201
202 SDOperand DAGTypeLegalizer::SplitOperand_STORE(StoreSDNode *N, unsigned OpNo) {
203   assert(OpNo == 1 && "Can only split the stored value");
204   
205   SDOperand Ch  = N->getChain();
206   SDOperand Ptr = N->getBasePtr();
207   int SVOffset = N->getSrcValueOffset();
208   unsigned Alignment = N->getAlignment();
209   bool isVol = N->isVolatile();
210   SDOperand Lo, Hi;
211   GetSplitOp(N->getOperand(1), Lo, Hi);
212
213   unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
214
215   Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, isVol, Alignment);
216   
217   // Increment the pointer to the other half.
218   Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
219                     getIntPtrConstant(IncrementSize));
220   
221   Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
222                     isVol, MinAlign(Alignment, IncrementSize));
223   return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
224 }
225