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/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 &inputs[0], &inputs[1], &opcode)) { | 353 &inputs[0], &inputs[1], &opcode)) { |
354 input_count += 2; | 354 input_count += 2; |
355 } else if (is_add_sub && can_commute && | 355 } else if (is_add_sub && can_commute && |
356 TryMatchAnyExtend(&g, selector, node, right_node, left_node, | 356 TryMatchAnyExtend(&g, selector, node, right_node, left_node, |
357 &inputs[0], &inputs[1], &opcode)) { | 357 &inputs[0], &inputs[1], &opcode)) { |
358 if (must_commute_cond) cont->Commute(); | 358 if (must_commute_cond) cont->Commute(); |
359 input_count += 2; | 359 input_count += 2; |
360 } else if (TryMatchAnyShift(selector, node, right_node, &opcode, | 360 } else if (TryMatchAnyShift(selector, node, right_node, &opcode, |
361 !is_add_sub)) { | 361 !is_add_sub)) { |
362 Matcher m_shift(right_node); | 362 Matcher m_shift(right_node); |
363 inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node); | 363 inputs[input_count++] = cont->IsDeoptimize() |
| 364 ? g.UseRegister(left_node) |
| 365 : g.UseRegisterOrImmediateZero(left_node); |
364 inputs[input_count++] = g.UseRegister(m_shift.left().node()); | 366 inputs[input_count++] = g.UseRegister(m_shift.left().node()); |
365 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); | 367 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); |
366 } else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode, | 368 } else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode, |
367 !is_add_sub)) { | 369 !is_add_sub)) { |
368 if (must_commute_cond) cont->Commute(); | 370 if (must_commute_cond) cont->Commute(); |
369 Matcher m_shift(left_node); | 371 Matcher m_shift(left_node); |
370 inputs[input_count++] = g.UseRegisterOrImmediateZero(right_node); | 372 inputs[input_count++] = cont->IsDeoptimize() |
| 373 ? g.UseRegister(right_node) |
| 374 : g.UseRegisterOrImmediateZero(right_node); |
371 inputs[input_count++] = g.UseRegister(m_shift.left().node()); | 375 inputs[input_count++] = g.UseRegister(m_shift.left().node()); |
372 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); | 376 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); |
373 } else { | 377 } else { |
374 inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node); | 378 inputs[input_count++] = cont->IsDeoptimize() |
| 379 ? g.UseRegister(left_node) |
| 380 : g.UseRegisterOrImmediateZero(left_node); |
375 inputs[input_count++] = g.UseRegister(right_node); | 381 inputs[input_count++] = g.UseRegister(right_node); |
376 } | 382 } |
377 | 383 |
378 if (cont->IsBranch()) { | 384 if (cont->IsBranch()) { |
379 inputs[input_count++] = g.Label(cont->true_block()); | 385 inputs[input_count++] = g.Label(cont->true_block()); |
380 inputs[input_count++] = g.Label(cont->false_block()); | 386 inputs[input_count++] = g.Label(cont->false_block()); |
381 } | 387 } |
382 | 388 |
383 if (!IsComparisonField::decode(properties)) { | 389 if (!IsComparisonField::decode(properties)) { |
384 outputs[output_count++] = g.DefineAsRegister(node); | 390 if (cont->IsDeoptimize()) { |
| 391 // If we can deoptimize as a result of the binop, we need to make sure |
| 392 // that the deopt inputs are not overwritten by the binop result. One way |
| 393 // to achieve that is to declare the output register as same-as-first. |
| 394 outputs[output_count++] = g.DefineSameAsFirst(node); |
| 395 } else { |
| 396 outputs[output_count++] = g.DefineAsRegister(node); |
| 397 } |
385 } | 398 } |
386 | 399 |
387 if (cont->IsSet()) { | 400 if (cont->IsSet()) { |
388 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 401 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
389 } | 402 } |
390 | 403 |
391 DCHECK_NE(0u, input_count); | 404 DCHECK_NE(0u, input_count); |
392 DCHECK((output_count != 0) || IsComparisonField::decode(properties)); | 405 DCHECK((output_count != 0) || IsComparisonField::decode(properties)); |
393 DCHECK_GE(arraysize(inputs), input_count); | 406 DCHECK_GE(arraysize(inputs), input_count); |
394 DCHECK_GE(arraysize(outputs), output_count); | 407 DCHECK_GE(arraysize(outputs), output_count); |
(...skipping 2154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2549 // static | 2562 // static |
2550 MachineOperatorBuilder::AlignmentRequirements | 2563 MachineOperatorBuilder::AlignmentRequirements |
2551 InstructionSelector::AlignmentRequirements() { | 2564 InstructionSelector::AlignmentRequirements() { |
2552 return MachineOperatorBuilder::AlignmentRequirements:: | 2565 return MachineOperatorBuilder::AlignmentRequirements:: |
2553 FullUnalignedAccessSupport(); | 2566 FullUnalignedAccessSupport(); |
2554 } | 2567 } |
2555 | 2568 |
2556 } // namespace compiler | 2569 } // namespace compiler |
2557 } // namespace internal | 2570 } // namespace internal |
2558 } // namespace v8 | 2571 } // namespace v8 |
OLD | NEW |