Convert SimplifyDemandedMask and ShrinkDemandedConstant to use APInt.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeTypesScalarize.cpp
1 //===-- LegalizeTypesScalarize.cpp - Scalarization for LegalizeTypes ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements scalarization support for LegalizeTypes.  Scalarization
11 // is the act of changing a computation in an invalid single-element vector type
12 // to be a computation in its scalar element type.  For example, implementing
13 // <1 x f32> arithmetic in a scalar f32 register.  This is needed as a base case
14 // when scalarizing vector arithmetic like <4 x f32>, which eventually
15 // decomposes to scalars if the target doesn't support v4f32 or v2f32 types.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #include "LegalizeTypes.h"
20 using namespace llvm;
21
22 //===----------------------------------------------------------------------===//
23 //  Result Vector Scalarization: <1 x ty> -> ty.
24 //===----------------------------------------------------------------------===//
25
26 void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) {
27   DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG); 
28         cerr << "\n");
29   SDOperand R = SDOperand();
30   
31   // FIXME: Custom lowering for scalarization?
32 #if 0
33   // See if the target wants to custom expand this node.
34   if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
35       TargetLowering::Custom) {
36     // If the target wants to, allow it to lower this itself.
37     if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
38       // Everything that once used N now uses P.  We are guaranteed that the
39       // result value types of N and the result value types of P match.
40       ReplaceNodeWith(N, P);
41       return;
42     }
43   }
44 #endif
45   
46   switch (N->getOpcode()) {
47   default:
48 #ifndef NDEBUG
49     cerr << "ScalarizeResult #" << ResNo << ": ";
50     N->dump(&DAG); cerr << "\n";
51 #endif
52     assert(0 && "Do not know how to scalarize the result of this operator!");
53     abort();
54     
55   case ISD::UNDEF:       R = ScalarizeRes_UNDEF(N); break;
56   case ISD::LOAD:        R = ScalarizeRes_LOAD(cast<LoadSDNode>(N)); break;
57   case ISD::ADD:
58   case ISD::FADD:
59   case ISD::SUB:
60   case ISD::FSUB:
61   case ISD::MUL:
62   case ISD::FMUL:
63   case ISD::SDIV:
64   case ISD::UDIV:
65   case ISD::FDIV:
66   case ISD::SREM:
67   case ISD::UREM:
68   case ISD::FREM:
69   case ISD::FPOW:
70   case ISD::AND:
71   case ISD::OR:
72   case ISD::XOR:         R = ScalarizeRes_BinOp(N); break;
73   case ISD::FNEG:
74   case ISD::FABS:
75   case ISD::FSQRT:
76   case ISD::FSIN:
77   case ISD::FCOS:              R = ScalarizeRes_UnaryOp(N); break;
78   case ISD::FPOWI:             R = ScalarizeRes_FPOWI(N); break;
79   case ISD::BUILD_VECTOR:      R = N->getOperand(0); break;
80   case ISD::INSERT_VECTOR_ELT: R = N->getOperand(1); break;
81   case ISD::VECTOR_SHUFFLE:    R = ScalarizeRes_VECTOR_SHUFFLE(N); break;
82   case ISD::BIT_CONVERT:       R = ScalarizeRes_BIT_CONVERT(N); break;
83   case ISD::SELECT:            R = ScalarizeRes_SELECT(N); break;
84   }
85   
86   // If R is null, the sub-method took care of registering the resul.
87   if (R.Val)
88     SetScalarizedOp(SDOperand(N, ResNo), R);
89 }
90
91 SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) {
92   return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(N->getValueType(0)));
93 }
94
95 SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) {
96   SDOperand Result = DAG.getLoad(MVT::getVectorElementType(N->getValueType(0)),
97                                  N->getChain(), N->getBasePtr(), 
98                                  N->getSrcValue(), N->getSrcValueOffset(),
99                                  N->isVolatile(), N->getAlignment());
100   
101   // Legalized the chain result - switch anything that used the old chain to
102   // use the new one.
103   ReplaceValueWith(SDOperand(N, 1), Result.getValue(1));
104   return Result;
105 }
106
107 SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) {
108   SDOperand LHS = GetScalarizedOp(N->getOperand(0));
109   SDOperand RHS = GetScalarizedOp(N->getOperand(1));
110   return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
111 }
112
113 SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) {
114   SDOperand Op = GetScalarizedOp(N->getOperand(0));
115   return DAG.getNode(N->getOpcode(), Op.getValueType(), Op);
116 }
117
118 SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) {
119   SDOperand Op = GetScalarizedOp(N->getOperand(0));
120   return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
121 }
122
123 SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) {
124   // Figure out if the scalar is the LHS or RHS and return it.
125   SDOperand EltNum = N->getOperand(2).getOperand(0);
126   unsigned Op = cast<ConstantSDNode>(EltNum)->getValue() != 0;
127   return GetScalarizedOp(N->getOperand(Op));
128 }
129
130 SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) {
131   MVT::ValueType NewVT = MVT::getVectorElementType(N->getValueType(0));
132   return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
133 }
134
135 SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) {
136   SDOperand LHS = GetScalarizedOp(N->getOperand(1));
137   return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS,
138                      GetScalarizedOp(N->getOperand(2)));
139 }
140
141
142 //===----------------------------------------------------------------------===//
143 //  Operand Vector Scalarization <1 x ty> -> ty.
144 //===----------------------------------------------------------------------===//
145
146 bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
147   DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG); 
148         cerr << "\n");
149   SDOperand Res(0, 0);
150   
151   // FIXME: Should we support custom lowering for scalarization?
152 #if 0
153   if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
154       TargetLowering::Custom)
155     Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
156 #endif
157   
158   if (Res.Val == 0) {
159     switch (N->getOpcode()) {
160     default:
161 #ifndef NDEBUG
162       cerr << "ScalarizeOperand Op #" << OpNo << ": ";
163       N->dump(&DAG); cerr << "\n";
164 #endif
165       assert(0 && "Do not know how to scalarize this operator's operand!");
166       abort();
167       
168     case ISD::EXTRACT_VECTOR_ELT:
169       Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
170
171     case ISD::STORE:
172       Res = ScalarizeOp_STORE(cast<StoreSDNode>(N), OpNo); break;
173     }
174   }
175   
176   // If the result is null, the sub-method took care of registering results etc.
177   if (!Res.Val) return false;
178   
179   // If the result is N, the sub-method updated N in place.  Check to see if any
180   // operands are new, and if so, mark them.
181   if (Res.Val == N) {
182     // Mark N as new and remark N and its operands.  This allows us to correctly
183     // revisit N if it needs another step of promotion and allows us to visit
184     // any new operands to N.
185     ReanalyzeNode(N);
186     return true;
187   }
188
189   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
190          "Invalid operand expansion");
191   
192   ReplaceValueWith(SDOperand(N, 0), Res);
193   return false;
194 }
195
196 /// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
197 /// scalarized, it must be <1 x ty>, so just return the element, ignoring the
198 /// index.
199 SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) {
200   return GetScalarizedOp(N->getOperand(0));
201 }
202
203 /// ScalarizeOp_STORE - If the value to store is a vector that needs to be
204 /// scalarized, it must be <1 x ty>.  Just store the element.
205 SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) {
206   assert(OpNo == 1 && "Do not know how to scalarize this operand!");
207   return DAG.getStore(N->getChain(), GetScalarizedOp(N->getOperand(1)),
208                       N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
209                       N->isVolatile(), N->getAlignment());
210 }