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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 2728533003: [turbofan] Enable complex memory operands for binops on ia32/x64 (Closed)
Patch Set: Rebase and Add tests for the 64-bit variants Created 3 years, 9 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
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 <algorithm> 5 #include <algorithm>
6 6
7 #include "src/base/adapters.h" 7 #include "src/base/adapters.h"
8 #include "src/compiler/instruction-selector-impl.h" 8 #include "src/compiler/instruction-selector-impl.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 if (input->opcode() != IrOpcode::kLoad || 51 if (input->opcode() != IrOpcode::kLoad ||
52 !selector()->CanCover(node, input)) { 52 !selector()->CanCover(node, input)) {
53 return false; 53 return false;
54 } 54 }
55 if (effect_level != selector()->GetEffectLevel(input)) { 55 if (effect_level != selector()->GetEffectLevel(input)) {
56 return false; 56 return false;
57 } 57 }
58 MachineRepresentation rep = 58 MachineRepresentation rep =
59 LoadRepresentationOf(input->op()).representation(); 59 LoadRepresentationOf(input->op()).representation();
60 switch (opcode) { 60 switch (opcode) {
61 case kX64And:
62 case kX64Or:
63 case kX64Xor:
64 case kX64Add:
65 case kX64Sub:
61 case kX64Push: 66 case kX64Push:
62 case kX64Cmp: 67 case kX64Cmp:
63 case kX64Test: 68 case kX64Test:
64 return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep); 69 return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep);
70 case kX64And32:
71 case kX64Or32:
72 case kX64Xor32:
73 case kX64Add32:
74 case kX64Sub32:
65 case kX64Cmp32: 75 case kX64Cmp32:
66 case kX64Test32: 76 case kX64Test32:
67 return rep == MachineRepresentation::kWord32; 77 return rep == MachineRepresentation::kWord32;
68 case kX64Cmp16: 78 case kX64Cmp16:
69 case kX64Test16: 79 case kX64Test16:
70 return rep == MachineRepresentation::kWord16; 80 return rep == MachineRepresentation::kWord16;
71 case kX64Cmp8: 81 case kX64Cmp8:
72 case kX64Test8: 82 case kX64Test8:
73 return rep == MachineRepresentation::kWord8; 83 return rep == MachineRepresentation::kWord8;
74 default: 84 default:
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 } 510 }
501 511
502 512
503 // Shared routine for multiple binary operations. 513 // Shared routine for multiple binary operations.
504 static void VisitBinop(InstructionSelector* selector, Node* node, 514 static void VisitBinop(InstructionSelector* selector, Node* node,
505 InstructionCode opcode, FlagsContinuation* cont) { 515 InstructionCode opcode, FlagsContinuation* cont) {
506 X64OperandGenerator g(selector); 516 X64OperandGenerator g(selector);
507 Int32BinopMatcher m(node); 517 Int32BinopMatcher m(node);
508 Node* left = m.left().node(); 518 Node* left = m.left().node();
509 Node* right = m.right().node(); 519 Node* right = m.right().node();
510 InstructionOperand inputs[4]; 520 InstructionOperand inputs[6];
511 size_t input_count = 0; 521 size_t input_count = 0;
512 InstructionOperand outputs[2]; 522 InstructionOperand outputs[2];
513 size_t output_count = 0; 523 size_t output_count = 0;
514 524
515 // TODO(turbofan): match complex addressing modes. 525 // TODO(turbofan): match complex addressing modes.
516 if (left == right) { 526 if (left == right) {
517 // If both inputs refer to the same operand, enforce allocating a register 527 // If both inputs refer to the same operand, enforce allocating a register
518 // for both of them to ensure that we don't end up generating code like 528 // for both of them to ensure that we don't end up generating code like
519 // this: 529 // this:
520 // 530 //
521 // mov rax, [rbp-0x10] 531 // mov rax, [rbp-0x10]
522 // add rax, [rbp-0x10] 532 // add rax, [rbp-0x10]
523 // jo label 533 // jo label
524 InstructionOperand const input = g.UseRegister(left); 534 InstructionOperand const input = g.UseRegister(left);
525 inputs[input_count++] = input; 535 inputs[input_count++] = input;
526 inputs[input_count++] = input; 536 inputs[input_count++] = input;
527 } else if (g.CanBeImmediate(right)) { 537 } else if (g.CanBeImmediate(right)) {
528 inputs[input_count++] = g.UseRegister(left); 538 inputs[input_count++] = g.UseRegister(left);
529 inputs[input_count++] = g.UseImmediate(right); 539 inputs[input_count++] = g.UseImmediate(right);
530 } else { 540 } else {
541 int effect_level = selector->GetEffectLevel(node);
542 if (cont->IsBranch()) {
543 effect_level = selector->GetEffectLevel(
544 cont->true_block()->PredecessorAt(0)->control_input());
545 }
531 if (node->op()->HasProperty(Operator::kCommutative) && 546 if (node->op()->HasProperty(Operator::kCommutative) &&
532 g.CanBeBetterLeftOperand(right)) { 547 g.CanBeBetterLeftOperand(right) &&
548 (!g.CanBeBetterLeftOperand(left) ||
549 !g.CanBeMemoryOperand(opcode, node, right, effect_level))) {
533 std::swap(left, right); 550 std::swap(left, right);
534 } 551 }
535 inputs[input_count++] = g.UseRegister(left); 552 if (g.CanBeMemoryOperand(opcode, node, right, effect_level)) {
536 inputs[input_count++] = g.Use(right); 553 inputs[input_count++] = g.UseRegister(left);
554 AddressingMode addressing_mode =
555 g.GetEffectiveAddressMemoryOperand(right, inputs, &input_count);
556 opcode |= AddressingModeField::encode(addressing_mode);
557 } else {
558 inputs[input_count++] = g.UseRegister(left);
559 inputs[input_count++] = g.Use(right);
560 }
537 } 561 }
538 562
539 if (cont->IsBranch()) { 563 if (cont->IsBranch()) {
540 inputs[input_count++] = g.Label(cont->true_block()); 564 inputs[input_count++] = g.Label(cont->true_block());
541 inputs[input_count++] = g.Label(cont->false_block()); 565 inputs[input_count++] = g.Label(cont->false_block());
542 } 566 }
543 567
544 outputs[output_count++] = g.DefineSameAsFirst(node); 568 outputs[output_count++] = g.DefineSameAsFirst(node);
545 if (cont->IsSet()) { 569 if (cont->IsSet()) {
546 outputs[output_count++] = g.DefineAsRegister(cont->result()); 570 outputs[output_count++] = g.DefineAsRegister(cont->result());
(...skipping 1845 matching lines...) Expand 10 before | Expand all | Expand 10 after
2392 // static 2416 // static
2393 MachineOperatorBuilder::AlignmentRequirements 2417 MachineOperatorBuilder::AlignmentRequirements
2394 InstructionSelector::AlignmentRequirements() { 2418 InstructionSelector::AlignmentRequirements() {
2395 return MachineOperatorBuilder::AlignmentRequirements:: 2419 return MachineOperatorBuilder::AlignmentRequirements::
2396 FullUnalignedAccessSupport(); 2420 FullUnalignedAccessSupport();
2397 } 2421 }
2398 2422
2399 } // namespace compiler 2423 } // namespace compiler
2400 } // namespace internal 2424 } // namespace internal
2401 } // namespace v8 2425 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/x64/code-generator-x64.cc ('k') | test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698