Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(453)

Side by Side Diff: src/compiler/change-lowering.cc

Issue 1901803002: [turbofan] Remove phase ordering problem in JSToNumber lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comment Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/change-lowering.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
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::kChangeInt32ToTagged: 32 case IrOpcode::kChangeInt32ToTagged:
33 return ChangeInt32ToTagged(node->InputAt(0), control); 33 return ChangeInt32ToTagged(node->InputAt(0), control);
34 case IrOpcode::kChangeSmiToInt32:
35 return ChangeSmiToInt32(node->InputAt(0));
34 case IrOpcode::kChangeTaggedToFloat64: 36 case IrOpcode::kChangeTaggedToFloat64:
35 return ChangeTaggedToFloat64(node->InputAt(0), control); 37 return ChangeTaggedToFloat64(node->InputAt(0), control);
36 case IrOpcode::kChangeTaggedToInt32: 38 case IrOpcode::kChangeTaggedToInt32:
37 return ChangeTaggedToUI32(node->InputAt(0), control, kSigned); 39 return ChangeTaggedToUI32(node->InputAt(0), control, kSigned);
38 case IrOpcode::kChangeTaggedToUint32: 40 case IrOpcode::kChangeTaggedToUint32:
39 return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned); 41 return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned);
40 case IrOpcode::kChangeUint32ToTagged: 42 case IrOpcode::kChangeUint32ToTagged:
41 return ChangeUint32ToTagged(node->InputAt(0), control); 43 return ChangeUint32ToTagged(node->InputAt(0), control);
42 case IrOpcode::kLoadField: 44 case IrOpcode::kLoadField:
43 return LoadField(node); 45 return LoadField(node);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 116
115 Node* ChangeLowering::ChangeInt32ToSmi(Node* value) { 117 Node* ChangeLowering::ChangeInt32ToSmi(Node* value) {
116 if (machine()->Is64()) { 118 if (machine()->Is64()) {
117 value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value); 119 value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value);
118 } 120 }
119 return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()); 121 return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
120 } 122 }
121 123
122 124
123 Node* ChangeLowering::ChangeSmiToFloat64(Node* value) { 125 Node* ChangeLowering::ChangeSmiToFloat64(Node* value) {
124 return ChangeInt32ToFloat64(ChangeSmiToInt32(value)); 126 return ChangeInt32ToFloat64(ChangeSmiToWord32(value));
125 } 127 }
126 128
127 129 Node* ChangeLowering::ChangeSmiToWord32(Node* value) {
128 Node* ChangeLowering::ChangeSmiToInt32(Node* value) {
129 value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant()); 130 value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
130 if (machine()->Is64()) { 131 if (machine()->Is64()) {
131 value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value); 132 value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
132 } 133 }
133 return value; 134 return value;
134 } 135 }
135 136
136 137
137 Node* ChangeLowering::ChangeUint32ToFloat64(Node* value) { 138 Node* ChangeLowering::ChangeUint32ToFloat64(Node* value) {
138 return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value); 139 return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 271 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
271 Node* vfalse = graph()->NewNode(common()->Projection(0), add); 272 Node* vfalse = graph()->NewNode(common()->Projection(0), add);
272 273
273 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); 274 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
274 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 275 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
275 vtrue, vfalse, merge); 276 vtrue, vfalse, merge);
276 277
277 return Replace(phi); 278 return Replace(phi);
278 } 279 }
279 280
281 Reduction ChangeLowering::ChangeSmiToInt32(Node* value) {
282 return Replace(ChangeSmiToWord32(value));
283 }
280 284
281 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control, 285 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control,
282 Signedness signedness) { 286 Signedness signedness) {
283 if (NodeProperties::GetType(value)->Is(Type::TaggedSigned())) { 287 if (NodeProperties::GetType(value)->Is(Type::TaggedSigned())) {
284 return Replace(ChangeSmiToInt32(value)); 288 return ChangeSmiToInt32(value);
285 } 289 }
286 290
287 const Operator* op = (signedness == kSigned) 291 const Operator* op = (signedness == kSigned)
288 ? machine()->ChangeFloat64ToInt32() 292 ? machine()->ChangeFloat64ToInt32()
289 : machine()->ChangeFloat64ToUint32(); 293 : machine()->ChangeFloat64ToUint32();
290 294
291 if (NodeProperties::GetType(value)->Is(Type::TaggedPointer()) && 295 if (NodeProperties::GetType(value)->Is(Type::TaggedPointer()) &&
292 NodeProperties::GetType(value)->Is(Type::Number())) { 296 NodeProperties::GetType(value)->Is(Type::Number())) {
293 return Replace(graph()->NewNode(op, LoadHeapNumberValue(value, control))); 297 return Replace(graph()->NewNode(op, LoadHeapNumberValue(value, control)));
294 } 298 }
(...skipping 22 matching lines...) Expand all
317 if_not_smi = 321 if_not_smi =
318 graph()->NewNode(common()->Merge(2), if_undefined, if_not_undefined); 322 graph()->NewNode(common()->Merge(2), if_undefined, if_not_undefined);
319 vnot_smi = 323 vnot_smi =
320 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), 324 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
321 vundefined, vheap_number, if_not_smi); 325 vundefined, vheap_number, if_not_smi);
322 } else { 326 } else {
323 vnot_smi = graph()->NewNode(op, LoadHeapNumberValue(value, if_not_smi)); 327 vnot_smi = graph()->NewNode(op, LoadHeapNumberValue(value, if_not_smi));
324 } 328 }
325 329
326 Node* if_smi = graph()->NewNode(common()->IfFalse(), branch); 330 Node* if_smi = graph()->NewNode(common()->IfFalse(), branch);
327 Node* vfrom_smi = ChangeSmiToInt32(value); 331 Node* vfrom_smi = ChangeSmiToWord32(value);
328 332
329 Node* merge = graph()->NewNode(common()->Merge(2), if_not_smi, if_smi); 333 Node* merge = graph()->NewNode(common()->Merge(2), if_not_smi, if_smi);
330 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), 334 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
331 vnot_smi, vfrom_smi, merge); 335 vnot_smi, vfrom_smi, merge);
332 336
333 return Replace(phi); 337 return Replace(phi);
334 } 338 }
335 339
336 340
337 namespace {
338
339 bool CanCover(Node* value, IrOpcode::Value opcode) {
340 if (value->opcode() != opcode) return false;
341 bool first = true;
342 for (Edge const edge : value->use_edges()) {
343 if (NodeProperties::IsControlEdge(edge)) continue;
344 if (NodeProperties::IsEffectEdge(edge)) continue;
345 DCHECK(NodeProperties::IsValueEdge(edge));
346 if (!first) return false;
347 first = false;
348 }
349 return true;
350 }
351
352 } // namespace
353
354
355 Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) { 341 Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) {
356 if (CanCover(value, IrOpcode::kJSToNumber)) {
357 // ChangeTaggedToFloat64(JSToNumber(x)) =>
358 // if IsSmi(x) then ChangeSmiToFloat64(x)
359 // else let y = JSToNumber(x) in
360 // if IsSmi(y) then ChangeSmiToFloat64(y)
361 // else LoadHeapNumberValue(y)
362 Node* const object = NodeProperties::GetValueInput(value, 0);
363 Node* const context = NodeProperties::GetContextInput(value);
364 Node* const frame_state = NodeProperties::GetFrameStateInput(value, 0);
365 Node* const effect = NodeProperties::GetEffectInput(value);
366 Node* const control = NodeProperties::GetControlInput(value);
367
368 const Operator* merge_op = common()->Merge(2);
369 const Operator* ephi_op = common()->EffectPhi(2);
370 const Operator* phi_op = common()->Phi(MachineRepresentation::kFloat64, 2);
371
372 Node* check1 = TestNotSmi(object);
373 Node* branch1 =
374 graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control);
375
376 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
377 Node* vtrue1 = graph()->NewNode(value->op(), object, context, frame_state,
378 effect, if_true1);
379 Node* etrue1 = vtrue1;
380
381 Node* check2 = TestNotSmi(vtrue1);
382 Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_true1);
383
384 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
385 Node* vtrue2 = LoadHeapNumberValue(vtrue1, if_true2);
386
387 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
388 Node* vfalse2 = ChangeSmiToFloat64(vtrue1);
389
390 if_true1 = graph()->NewNode(merge_op, if_true2, if_false2);
391 vtrue1 = graph()->NewNode(phi_op, vtrue2, vfalse2, if_true1);
392
393 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
394 Node* vfalse1 = ChangeSmiToFloat64(object);
395 Node* efalse1 = effect;
396
397 Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1);
398 Node* ephi1 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1);
399 Node* phi1 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1);
400
401 // Wire the new diamond into the graph, {JSToNumber} can still throw.
402 NodeProperties::ReplaceUses(value, phi1, ephi1, etrue1, etrue1);
403
404 // TODO(mstarzinger): This iteration cuts out the IfSuccess projection from
405 // the node and places it inside the diamond. Come up with a helper method!
406 for (Node* use : etrue1->uses()) {
407 if (use->opcode() == IrOpcode::kIfSuccess) {
408 use->ReplaceUses(merge1);
409 NodeProperties::ReplaceControlInput(branch2, use);
410 }
411 }
412
413 return Replace(phi1);
414 }
415
416 Node* check = TestNotSmi(value); 342 Node* check = TestNotSmi(value);
417 Node* branch = 343 Node* branch =
418 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); 344 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
419 345
420 Node* if_not_smi = graph()->NewNode(common()->IfTrue(), branch); 346 Node* if_not_smi = graph()->NewNode(common()->IfTrue(), branch);
421 347
422 Node* vnot_smi; 348 Node* vnot_smi;
423 if (NodeProperties::GetType(value)->Maybe(Type::Undefined())) { 349 if (NodeProperties::GetType(value)->Maybe(Type::Undefined())) {
424 Node* check_undefined = graph()->NewNode(machine()->WordEqual(), value, 350 Node* check_undefined = graph()->NewNode(machine()->WordEqual(), value,
425 jsgraph()->UndefinedConstant()); 351 jsgraph()->UndefinedConstant());
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 } 707 }
782 708
783 709
784 MachineOperatorBuilder* ChangeLowering::machine() const { 710 MachineOperatorBuilder* ChangeLowering::machine() const {
785 return jsgraph()->machine(); 711 return jsgraph()->machine();
786 } 712 }
787 713
788 } // namespace compiler 714 } // namespace compiler
789 } // namespace internal 715 } // namespace internal
790 } // namespace v8 716 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/change-lowering.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698