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

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

Issue 651383003: [x86] Several small performance improvements. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/compiler/x64/code-generator-x64.cc » ('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/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-inl.h" 7 #include "src/compiler/node-properties-inl.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 IA32OperandGenerator g(selector); 252 IA32OperandGenerator g(selector);
253 Int32BinopMatcher m(node); 253 Int32BinopMatcher m(node);
254 Node* left = m.left().node(); 254 Node* left = m.left().node();
255 Node* right = m.right().node(); 255 Node* right = m.right().node();
256 InstructionOperand* inputs[4]; 256 InstructionOperand* inputs[4];
257 size_t input_count = 0; 257 size_t input_count = 0;
258 InstructionOperand* outputs[2]; 258 InstructionOperand* outputs[2];
259 size_t output_count = 0; 259 size_t output_count = 0;
260 260
261 // TODO(turbofan): match complex addressing modes. 261 // TODO(turbofan): match complex addressing modes.
262 if (g.CanBeImmediate(right)) { 262 if (left == right) {
263 // If both inputs refer to the same operand, enforce allocating a register
264 // for both of them to ensure that we don't end up generating code like
265 // this:
266 //
267 // mov eax, [ebp-0x10]
268 // add eax, [ebp-0x10]
269 // jo label
270 InstructionOperand* const input = g.UseRegister(left);
271 inputs[input_count++] = input;
272 inputs[input_count++] = input;
273 } else if (g.CanBeImmediate(right)) {
263 inputs[input_count++] = g.UseRegister(left); 274 inputs[input_count++] = g.UseRegister(left);
264 inputs[input_count++] = g.UseImmediate(right); 275 inputs[input_count++] = g.UseImmediate(right);
265 } else { 276 } else {
266 if (node->op()->HasProperty(Operator::kCommutative) && 277 if (node->op()->HasProperty(Operator::kCommutative) &&
267 g.CanBeBetterLeftOperand(right)) { 278 g.CanBeBetterLeftOperand(right)) {
268 std::swap(left, right); 279 std::swap(left, right);
269 } 280 }
270 inputs[input_count++] = g.UseRegister(left); 281 inputs[input_count++] = g.UseRegister(left);
271 inputs[input_count++] = g.Use(right); 282 inputs[input_count++] = g.Use(right);
272 } 283 }
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont); 678 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
668 } else if (g.CanBeImmediate(left)) { 679 } else if (g.CanBeImmediate(left)) {
669 if (!commutative) cont->Commute(); 680 if (!commutative) cont->Commute();
670 VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont); 681 VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
671 } else { 682 } else {
672 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); 683 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
673 } 684 }
674 } 685 }
675 686
676 687
677 static void VisitWordTest(InstructionSelector* selector, Node* node,
678 FlagsContinuation* cont) {
679 IA32OperandGenerator g(selector);
680 VisitCompare(selector, kIA32Test, g.Use(node), g.TempImmediate(-1), cont);
681 }
682
683
684 // Shared routine for multiple float compare operations. 688 // Shared routine for multiple float compare operations.
685 static void VisitFloat64Compare(InstructionSelector* selector, Node* node, 689 static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
686 FlagsContinuation* cont) { 690 FlagsContinuation* cont) {
687 IA32OperandGenerator g(selector); 691 IA32OperandGenerator g(selector);
688 Node* left = node->InputAt(0); 692 Node* left = node->InputAt(0);
689 Node* right = node->InputAt(1); 693 Node* right = node->InputAt(1);
690 VisitCompare(selector, kSSEFloat64Cmp, g.UseRegister(left), g.Use(right), 694 VisitCompare(selector, kSSEFloat64Cmp, g.UseRegister(left), g.Use(right),
691 cont); 695 cont);
692 } 696 }
693 697
694 698
695 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, 699 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
696 BasicBlock* fbranch) { 700 BasicBlock* fbranch) {
697 OperandGenerator g(this); 701 IA32OperandGenerator g(this);
698 Node* user = branch; 702 Node* user = branch;
699 Node* value = branch->InputAt(0); 703 Node* value = branch->InputAt(0);
700 704
701 FlagsContinuation cont(kNotEqual, tbranch, fbranch); 705 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
702 706
703 // If we can fall through to the true block, invert the branch. 707 // If we can fall through to the true block, invert the branch.
704 if (IsNextInAssemblyOrder(tbranch)) { 708 if (IsNextInAssemblyOrder(tbranch)) {
705 cont.Negate(); 709 cont.Negate();
706 cont.SwapBlocks(); 710 cont.SwapBlocks();
707 } 711 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 case IrOpcode::kInt32Sub: 777 case IrOpcode::kInt32Sub:
774 return VisitWordCompare(this, value, kIA32Cmp, &cont, false); 778 return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
775 case IrOpcode::kWord32And: 779 case IrOpcode::kWord32And:
776 return VisitWordCompare(this, value, kIA32Test, &cont, true); 780 return VisitWordCompare(this, value, kIA32Test, &cont, true);
777 default: 781 default:
778 break; 782 break;
779 } 783 }
780 } 784 }
781 785
782 // Branch could not be combined with a compare, emit compare against 0. 786 // Branch could not be combined with a compare, emit compare against 0.
783 VisitWordTest(this, value, &cont); 787 VisitCompare(this, kIA32Cmp, g.Use(value), g.TempImmediate(0), &cont);
784 } 788 }
785 789
786 790
787 void InstructionSelector::VisitWord32Equal(Node* const node) { 791 void InstructionSelector::VisitWord32Equal(Node* const node) {
788 Node* const user = node; 792 Node* const user = node;
789 FlagsContinuation cont(kEqual, node); 793 FlagsContinuation cont(kEqual, node);
790 Int32BinopMatcher m(user); 794 Int32BinopMatcher m(user);
791 if (m.right().Is(0)) { 795 if (m.right().Is(0)) {
792 Node* const value = m.left().node(); 796 Node* const value = m.left().node();
793 if (CanCover(user, value)) { 797 if (CanCover(user, value)) {
794 switch (value->opcode()) { 798 switch (value->opcode()) {
795 case IrOpcode::kInt32Sub: 799 case IrOpcode::kInt32Sub:
796 return VisitWordCompare(this, value, kIA32Cmp, &cont, false); 800 return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
797 case IrOpcode::kWord32And: 801 case IrOpcode::kWord32And:
798 return VisitWordCompare(this, value, kIA32Test, &cont, true); 802 return VisitWordCompare(this, value, kIA32Test, &cont, true);
799 default: 803 default:
800 break; 804 break;
801 } 805 }
802 return VisitWordTest(this, value, &cont);
803 } 806 }
804 } 807 }
805 return VisitWordCompare(this, node, kIA32Cmp, &cont, false); 808 return VisitWordCompare(this, node, kIA32Cmp, &cont, false);
806 } 809 }
807 810
808 811
809 void InstructionSelector::VisitInt32LessThan(Node* node) { 812 void InstructionSelector::VisitInt32LessThan(Node* node) {
810 FlagsContinuation cont(kSignedLessThan, node); 813 FlagsContinuation cont(kSignedLessThan, node);
811 return VisitWordCompare(this, node, kIA32Cmp, &cont, false); 814 return VisitWordCompare(this, node, kIA32Cmp, &cont, false);
812 } 815 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 866
864 867
865 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 868 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
866 FlagsContinuation cont(kUnorderedLessThanOrEqual, node); 869 FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
867 VisitFloat64Compare(this, node, &cont); 870 VisitFloat64Compare(this, node, &cont);
868 } 871 }
869 872
870 } // namespace compiler 873 } // namespace compiler
871 } // namespace internal 874 } // namespace internal
872 } // namespace v8 875 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/x64/code-generator-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698