OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/change-lowering.h" | 5 #include "src/compiler/change-lowering.h" |
6 | 6 |
7 #include "src/address-map.h" | 7 #include "src/address-map.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 Reduction ChangeLowering::Reduce(Node* node) { | 23 Reduction ChangeLowering::Reduce(Node* node) { |
24 Node* control = graph()->start(); | 24 Node* control = graph()->start(); |
25 switch (node->opcode()) { | 25 switch (node->opcode()) { |
26 case IrOpcode::kChangeBitToBool: | 26 case IrOpcode::kChangeBitToBool: |
27 return ChangeBitToBool(node->InputAt(0), control); | 27 return ChangeBitToBool(node->InputAt(0), control); |
28 case IrOpcode::kChangeBoolToBit: | 28 case IrOpcode::kChangeBoolToBit: |
29 return ChangeBoolToBit(node->InputAt(0)); | 29 return ChangeBoolToBit(node->InputAt(0)); |
30 case IrOpcode::kChangeFloat64ToTagged: | 30 case IrOpcode::kChangeFloat64ToTagged: |
31 return ChangeFloat64ToTagged(node->InputAt(0), control); | 31 return ChangeFloat64ToTagged(node->InputAt(0), control); |
| 32 case IrOpcode::kChangeInt31ToTagged: |
| 33 return ChangeInt31ToTagged(node->InputAt(0), control); |
32 case IrOpcode::kChangeInt32ToTagged: | 34 case IrOpcode::kChangeInt32ToTagged: |
33 return ChangeInt32ToTagged(node->InputAt(0), control); | 35 return ChangeInt32ToTagged(node->InputAt(0), control); |
34 case IrOpcode::kChangeSmiToInt32: | 36 case IrOpcode::kChangeSmiToInt32: |
35 return ChangeSmiToInt32(node->InputAt(0)); | 37 return ChangeSmiToInt32(node->InputAt(0)); |
36 case IrOpcode::kChangeTaggedToFloat64: | 38 case IrOpcode::kChangeTaggedToFloat64: |
37 return ChangeTaggedToFloat64(node->InputAt(0), control); | 39 return ChangeTaggedToFloat64(node->InputAt(0), control); |
38 case IrOpcode::kChangeTaggedToInt32: | 40 case IrOpcode::kChangeTaggedToInt32: |
39 return ChangeTaggedToUI32(node->InputAt(0), control, kSigned); | 41 return ChangeTaggedToUI32(node->InputAt(0), control, kSigned); |
40 case IrOpcode::kChangeTaggedToUint32: | 42 case IrOpcode::kChangeTaggedToUint32: |
41 return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned); | 43 return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 } | 172 } |
171 | 173 |
172 | 174 |
173 Reduction ChangeLowering::ChangeBoolToBit(Node* value) { | 175 Reduction ChangeLowering::ChangeBoolToBit(Node* value) { |
174 return Replace(graph()->NewNode(machine()->WordEqual(), value, | 176 return Replace(graph()->NewNode(machine()->WordEqual(), value, |
175 jsgraph()->TrueConstant())); | 177 jsgraph()->TrueConstant())); |
176 } | 178 } |
177 | 179 |
178 | 180 |
179 Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { | 181 Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { |
180 Type* const value_type = NodeProperties::GetType(value); | 182 Node* value32 = graph()->NewNode( |
181 Node* const value32 = graph()->NewNode( | |
182 machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); | 183 machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); |
183 // TODO(bmeurer): This fast case must be disabled until we kill the asm.js | |
184 // support in the generic JavaScript pipeline, because LoadBuffer is lying | |
185 // about its result. | |
186 // if (value_type->Is(Type::Signed32())) { | |
187 // return ChangeInt32ToTagged(value32, control); | |
188 // } | |
189 Node* check_same = graph()->NewNode( | 184 Node* check_same = graph()->NewNode( |
190 machine()->Float64Equal(), value, | 185 machine()->Float64Equal(), value, |
191 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); | 186 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); |
192 Node* branch_same = graph()->NewNode(common()->Branch(), check_same, control); | 187 Node* branch_same = graph()->NewNode(common()->Branch(), check_same, control); |
193 | 188 |
194 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_same); | 189 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_same); |
195 Node* vsmi; | 190 Node* vsmi; |
196 Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same); | 191 Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same); |
197 Node* vbox; | 192 Node* vbox; |
198 | 193 |
199 // We only need to check for -0 if the {value} can potentially contain -0. | 194 // Check if {value} is -0. |
200 if (value_type->Maybe(Type::MinusZero())) { | 195 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, |
201 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, | 196 jsgraph()->Int32Constant(0)); |
202 jsgraph()->Int32Constant(0)); | 197 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
203 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 198 check_zero, if_smi); |
204 check_zero, if_smi); | |
205 | 199 |
206 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); | 200 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); |
207 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); | 201 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); |
208 | 202 |
209 // In case of 0, we need to check the high bits for the IEEE -0 pattern. | 203 // In case of 0, we need to check the high bits for the IEEE -0 pattern. |
210 Node* check_negative = graph()->NewNode( | 204 Node* check_negative = graph()->NewNode( |
211 machine()->Int32LessThan(), | 205 machine()->Int32LessThan(), |
212 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), | 206 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), |
213 jsgraph()->Int32Constant(0)); | 207 jsgraph()->Int32Constant(0)); |
214 Node* branch_negative = graph()->NewNode( | 208 Node* branch_negative = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
215 common()->Branch(BranchHint::kFalse), check_negative, if_zero); | 209 check_negative, if_zero); |
216 | 210 |
217 Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative); | 211 Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative); |
218 Node* if_notnegative = | 212 Node* if_notnegative = graph()->NewNode(common()->IfFalse(), branch_negative); |
219 graph()->NewNode(common()->IfFalse(), branch_negative); | |
220 | 213 |
221 // We need to create a box for negative 0. | 214 // We need to create a box for negative 0. |
222 if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative); | 215 if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative); |
223 if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative); | 216 if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative); |
224 } | |
225 | 217 |
226 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit | 218 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit |
227 // machines we need to deal with potential overflow and fallback to boxing. | 219 // machines we need to deal with potential overflow and fallback to boxing. |
228 if (machine()->Is64() || value_type->Is(Type::SignedSmall())) { | 220 if (machine()->Is64()) { |
229 vsmi = ChangeInt32ToSmi(value32); | 221 vsmi = ChangeInt32ToSmi(value32); |
230 } else { | 222 } else { |
231 Node* smi_tag = | 223 Node* smi_tag = |
232 graph()->NewNode(machine()->Int32AddWithOverflow(), value32, value32); | 224 graph()->NewNode(machine()->Int32AddWithOverflow(), value32, value32); |
233 | 225 |
234 Node* check_ovf = graph()->NewNode(common()->Projection(1), smi_tag); | 226 Node* check_ovf = graph()->NewNode(common()->Projection(1), smi_tag); |
235 Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 227 Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
236 check_ovf, if_smi); | 228 check_ovf, if_smi); |
237 | 229 |
238 Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf); | 230 Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf); |
239 if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box); | 231 if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box); |
240 | 232 |
241 if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf); | 233 if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf); |
242 vsmi = graph()->NewNode(common()->Projection(0), smi_tag); | 234 vsmi = graph()->NewNode(common()->Projection(0), smi_tag); |
243 } | 235 } |
244 | 236 |
245 // Allocate the box for the {value}. | 237 // Allocate the box for the {value}. |
246 vbox = AllocateHeapNumberWithValue(value, if_box); | 238 vbox = AllocateHeapNumberWithValue(value, if_box); |
247 | 239 |
248 control = graph()->NewNode(common()->Merge(2), if_smi, if_box); | 240 control = graph()->NewNode(common()->Merge(2), if_smi, if_box); |
249 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 241 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
250 vsmi, vbox, control); | 242 vsmi, vbox, control); |
251 return Replace(value); | 243 return Replace(value); |
252 } | 244 } |
253 | 245 |
| 246 Reduction ChangeLowering::ChangeInt31ToTagged(Node* value, Node* control) { |
| 247 return Replace(ChangeInt32ToSmi(value)); |
| 248 } |
254 | 249 |
255 Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { | 250 Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { |
256 if (machine()->Is64() || | 251 if (machine()->Is64()) { |
257 NodeProperties::GetType(value)->Is(Type::SignedSmall())) { | 252 value = ChangeInt32ToSmi(value); |
258 return Replace(ChangeInt32ToSmi(value)); | 253 } else { |
| 254 Node* add = |
| 255 graph()->NewNode(machine()->Int32AddWithOverflow(), value, value); |
| 256 |
| 257 Node* ovf = graph()->NewNode(common()->Projection(1), add); |
| 258 Node* branch = |
| 259 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); |
| 260 |
| 261 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 262 Node* vtrue = |
| 263 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true); |
| 264 |
| 265 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 266 Node* vfalse = graph()->NewNode(common()->Projection(0), add); |
| 267 |
| 268 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 269 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 270 vtrue, vfalse, control); |
259 } | 271 } |
260 | 272 return Replace(value); |
261 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value); | |
262 | |
263 Node* ovf = graph()->NewNode(common()->Projection(1), add); | |
264 Node* branch = | |
265 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); | |
266 | |
267 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
268 Node* vtrue = | |
269 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true); | |
270 | |
271 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
272 Node* vfalse = graph()->NewNode(common()->Projection(0), add); | |
273 | |
274 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
275 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
276 vtrue, vfalse, merge); | |
277 | |
278 return Replace(phi); | |
279 } | 273 } |
280 | 274 |
281 Reduction ChangeLowering::ChangeSmiToInt32(Node* value) { | 275 Reduction ChangeLowering::ChangeSmiToInt32(Node* value) { |
282 return Replace(ChangeSmiToWord32(value)); | 276 return Replace(ChangeSmiToWord32(value)); |
283 } | 277 } |
284 | 278 |
285 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control, | 279 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control, |
286 Signedness signedness) { | 280 Signedness signedness) { |
287 if (NodeProperties::GetType(value)->Is(Type::TaggedSigned())) { | 281 if (NodeProperties::GetType(value)->Is(Type::TaggedSigned())) { |
288 return ChangeSmiToInt32(value); | 282 return ChangeSmiToInt32(value); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 Node* merge = graph()->NewNode(common()->Merge(2), if_not_smi, if_smi); | 369 Node* merge = graph()->NewNode(common()->Merge(2), if_not_smi, if_smi); |
376 Node* phi = | 370 Node* phi = |
377 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 371 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
378 vnot_smi, vfrom_smi, merge); | 372 vnot_smi, vfrom_smi, merge); |
379 | 373 |
380 return Replace(phi); | 374 return Replace(phi); |
381 } | 375 } |
382 | 376 |
383 | 377 |
384 Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) { | 378 Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) { |
385 if (NodeProperties::GetType(value)->Is(Type::UnsignedSmall())) { | |
386 return Replace(ChangeUint32ToSmi(value)); | |
387 } | |
388 | |
389 Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, | 379 Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, |
390 SmiMaxValueConstant()); | 380 SmiMaxValueConstant()); |
391 Node* branch = | 381 Node* branch = |
392 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 382 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
393 | 383 |
394 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 384 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
395 Node* vtrue = ChangeUint32ToSmi(value); | 385 Node* vtrue = ChangeUint32ToSmi(value); |
396 | 386 |
397 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 387 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
398 Node* vfalse = | 388 Node* vfalse = |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 } | 697 } |
708 | 698 |
709 | 699 |
710 MachineOperatorBuilder* ChangeLowering::machine() const { | 700 MachineOperatorBuilder* ChangeLowering::machine() const { |
711 return jsgraph()->machine(); | 701 return jsgraph()->machine(); |
712 } | 702 } |
713 | 703 |
714 } // namespace compiler | 704 } // namespace compiler |
715 } // namespace internal | 705 } // namespace internal |
716 } // namespace v8 | 706 } // namespace v8 |
OLD | NEW |