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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.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 | « src/compiler/x64/code-generator-x64.cc ('k') | no next file » | 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/generic-node-inl.h" 5 #include "src/compiler/generic-node-inl.h"
6 #include "src/compiler/instruction-selector-impl.h" 6 #include "src/compiler/instruction-selector-impl.h"
7 #include "src/compiler/node-matchers.h" 7 #include "src/compiler/node-matchers.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 X64OperandGenerator g(selector); 233 X64OperandGenerator g(selector);
234 Int32BinopMatcher m(node); 234 Int32BinopMatcher m(node);
235 Node* left = m.left().node(); 235 Node* left = m.left().node();
236 Node* right = m.right().node(); 236 Node* right = m.right().node();
237 InstructionOperand* inputs[4]; 237 InstructionOperand* inputs[4];
238 size_t input_count = 0; 238 size_t input_count = 0;
239 InstructionOperand* outputs[2]; 239 InstructionOperand* outputs[2];
240 size_t output_count = 0; 240 size_t output_count = 0;
241 241
242 // TODO(turbofan): match complex addressing modes. 242 // TODO(turbofan): match complex addressing modes.
243 if (g.CanBeImmediate(right)) { 243 if (left == right) {
244 // If both inputs refer to the same operand, enforce allocating a register
245 // for both of them to ensure that we don't end up generating code like
246 // this:
247 //
248 // mov rax, [rbp-0x10]
249 // add rax, [rbp-0x10]
250 // jo label
251 InstructionOperand* const input = g.UseRegister(left);
252 inputs[input_count++] = input;
253 inputs[input_count++] = input;
254 } else if (g.CanBeImmediate(right)) {
244 inputs[input_count++] = g.UseRegister(left); 255 inputs[input_count++] = g.UseRegister(left);
245 inputs[input_count++] = g.UseImmediate(right); 256 inputs[input_count++] = g.UseImmediate(right);
246 } else { 257 } else {
247 if (node->op()->HasProperty(Operator::kCommutative) && 258 if (node->op()->HasProperty(Operator::kCommutative) &&
248 g.CanBeBetterLeftOperand(right)) { 259 g.CanBeBetterLeftOperand(right)) {
249 std::swap(left, right); 260 std::swap(left, right);
250 } 261 }
251 inputs[input_count++] = g.UseRegister(left); 262 inputs[input_count++] = g.UseRegister(left);
252 inputs[input_count++] = g.Use(right); 263 inputs[input_count++] = g.Use(right);
253 } 264 }
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont); 800 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
790 } else if (g.CanBeImmediate(left)) { 801 } else if (g.CanBeImmediate(left)) {
791 if (!commutative) cont->Commute(); 802 if (!commutative) cont->Commute();
792 VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont); 803 VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
793 } else { 804 } else {
794 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); 805 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
795 } 806 }
796 } 807 }
797 808
798 809
799 static void VisitWordTest(InstructionSelector* selector, Node* node,
800 InstructionCode opcode, FlagsContinuation* cont) {
801 X64OperandGenerator g(selector);
802 VisitCompare(selector, opcode, g.Use(node), g.TempImmediate(-1), cont);
803 }
804
805
806 static void VisitFloat64Compare(InstructionSelector* selector, Node* node, 810 static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
807 FlagsContinuation* cont) { 811 FlagsContinuation* cont) {
808 X64OperandGenerator g(selector); 812 X64OperandGenerator g(selector);
809 Node* left = node->InputAt(0); 813 Node* left = node->InputAt(0);
810 Node* right = node->InputAt(1); 814 Node* right = node->InputAt(1);
811 VisitCompare(selector, kSSEFloat64Cmp, g.UseRegister(left), g.Use(right), 815 VisitCompare(selector, kSSEFloat64Cmp, g.UseRegister(left), g.Use(right),
812 cont); 816 cont);
813 } 817 }
814 818
815 819
816 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, 820 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
817 BasicBlock* fbranch) { 821 BasicBlock* fbranch) {
818 OperandGenerator g(this); 822 X64OperandGenerator g(this);
819 Node* user = branch; 823 Node* user = branch;
820 Node* value = branch->InputAt(0); 824 Node* value = branch->InputAt(0);
821 825
822 FlagsContinuation cont(kNotEqual, tbranch, fbranch); 826 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
823 827
824 // If we can fall through to the true block, invert the branch. 828 // If we can fall through to the true block, invert the branch.
825 if (IsNextInAssemblyOrder(tbranch)) { 829 if (IsNextInAssemblyOrder(tbranch)) {
826 cont.Negate(); 830 cont.Negate();
827 cont.SwapBlocks(); 831 cont.SwapBlocks();
828 } 832 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 cont.OverwriteAndNegateIfEqual(kOverflow); 915 cont.OverwriteAndNegateIfEqual(kOverflow);
912 return VisitBinop(this, node, kX64Sub32, &cont); 916 return VisitBinop(this, node, kX64Sub32, &cont);
913 default: 917 default:
914 break; 918 break;
915 } 919 }
916 } 920 }
917 } 921 }
918 break; 922 break;
919 case IrOpcode::kInt32Sub: 923 case IrOpcode::kInt32Sub:
920 return VisitWordCompare(this, value, kX64Cmp32, &cont, false); 924 return VisitWordCompare(this, value, kX64Cmp32, &cont, false);
925 case IrOpcode::kInt64Sub:
926 return VisitWordCompare(this, value, kX64Cmp, &cont, false);
921 case IrOpcode::kWord32And: 927 case IrOpcode::kWord32And:
922 return VisitWordCompare(this, value, kX64Test32, &cont, true); 928 return VisitWordCompare(this, value, kX64Test32, &cont, true);
929 case IrOpcode::kWord64And:
930 return VisitWordCompare(this, value, kX64Test, &cont, true);
923 default: 931 default:
924 break; 932 break;
925 } 933 }
926 } 934 }
927 935
928 // Branch could not be combined with a compare, emit compare against 0. 936 // Branch could not be combined with a compare, emit compare against 0.
929 VisitWordTest(this, value, kX64Test32, &cont); 937 VisitCompare(this, kX64Cmp32, g.Use(value), g.TempImmediate(0), &cont);
930 } 938 }
931 939
932 940
933 void InstructionSelector::VisitWord32Equal(Node* const node) { 941 void InstructionSelector::VisitWord32Equal(Node* const node) {
934 Node* const user = node; 942 Node* const user = node;
935 FlagsContinuation cont(kEqual, node); 943 FlagsContinuation cont(kEqual, node);
936 Int32BinopMatcher m(user); 944 Int32BinopMatcher m(user);
937 if (m.right().Is(0)) { 945 if (m.right().Is(0)) {
938 Node* const value = m.left().node(); 946 Node* const value = m.left().node();
939 if (CanCover(user, value)) { 947 if (CanCover(user, value)) {
940 switch (value->opcode()) { 948 switch (value->opcode()) {
941 case IrOpcode::kInt32Sub: 949 case IrOpcode::kInt32Sub:
942 return VisitWordCompare(this, value, kX64Cmp32, &cont, false); 950 return VisitWordCompare(this, value, kX64Cmp32, &cont, false);
943 case IrOpcode::kWord32And: 951 case IrOpcode::kWord32And:
944 return VisitWordCompare(this, value, kX64Test32, &cont, true); 952 return VisitWordCompare(this, value, kX64Test32, &cont, true);
945 default: 953 default:
946 break; 954 break;
947 } 955 }
948 return VisitWordTest(this, value, kX64Test32, &cont);
949 } 956 }
950 } 957 }
951 VisitWordCompare(this, node, kX64Cmp32, &cont, false); 958 VisitWordCompare(this, node, kX64Cmp32, &cont, false);
952 } 959 }
953 960
954 961
955 void InstructionSelector::VisitInt32LessThan(Node* node) { 962 void InstructionSelector::VisitInt32LessThan(Node* node) {
956 FlagsContinuation cont(kSignedLessThan, node); 963 FlagsContinuation cont(kSignedLessThan, node);
957 VisitWordCompare(this, node, kX64Cmp32, &cont, false); 964 VisitWordCompare(this, node, kX64Cmp32, &cont, false);
958 } 965 }
(...skipping 25 matching lines...) Expand all
984 Node* const value = m.left().node(); 991 Node* const value = m.left().node();
985 if (CanCover(user, value)) { 992 if (CanCover(user, value)) {
986 switch (value->opcode()) { 993 switch (value->opcode()) {
987 case IrOpcode::kInt64Sub: 994 case IrOpcode::kInt64Sub:
988 return VisitWordCompare(this, value, kX64Cmp, &cont, false); 995 return VisitWordCompare(this, value, kX64Cmp, &cont, false);
989 case IrOpcode::kWord64And: 996 case IrOpcode::kWord64And:
990 return VisitWordCompare(this, value, kX64Test, &cont, true); 997 return VisitWordCompare(this, value, kX64Test, &cont, true);
991 default: 998 default:
992 break; 999 break;
993 } 1000 }
994 return VisitWordTest(this, value, kX64Test, &cont);
995 } 1001 }
996 } 1002 }
997 VisitWordCompare(this, node, kX64Cmp, &cont, false); 1003 VisitWordCompare(this, node, kX64Cmp, &cont, false);
998 } 1004 }
999 1005
1000 1006
1001 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { 1007 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
1002 if (Node* ovf = node->FindProjection(1)) { 1008 if (Node* ovf = node->FindProjection(1)) {
1003 FlagsContinuation cont(kOverflow, ovf); 1009 FlagsContinuation cont(kOverflow, ovf);
1004 VisitBinop(this, node, kX64Add32, &cont); 1010 VisitBinop(this, node, kX64Add32, &cont);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 1055
1050 1056
1051 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 1057 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
1052 FlagsContinuation cont(kUnorderedLessThanOrEqual, node); 1058 FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
1053 VisitFloat64Compare(this, node, &cont); 1059 VisitFloat64Compare(this, node, &cont);
1054 } 1060 }
1055 1061
1056 } // namespace compiler 1062 } // namespace compiler
1057 } // namespace internal 1063 } // namespace internal
1058 } // namespace v8 1064 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/x64/code-generator-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698