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

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

Issue 1706763002: [turbofan] Emit memory operands for cmp and test on ia32 and x64 when it makes sense. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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 "src/base/adapters.h" 5 #include "src/base/adapters.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 #include "src/compiler/node-properties.h" 8 #include "src/compiler/node-properties.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 } 977 }
978 978
979 979
980 bool InstructionSelector::IsTailCallAddressImmediate() { return true; } 980 bool InstructionSelector::IsTailCallAddressImmediate() { return true; }
981 981
982 982
983 namespace { 983 namespace {
984 984
985 // Shared routine for multiple compare operations. 985 // Shared routine for multiple compare operations.
986 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 986 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
987 size_t left_operands_count, InstructionOperand* left_operands,
988 InstructionOperand right, FlagsContinuation* cont) {
989 DCHECK(left_operands_count > 0 && left_operands_count <= 4);
990 IA32OperandGenerator g(selector);
991 opcode = cont->Encode(opcode);
992 int input_count = 0;
993 InstructionOperand inputs[6];
994 do {
995 inputs[input_count] = left_operands[input_count];
996 } while (++input_count < left_operands_count);
997 inputs[input_count++] = right;
998
999 if (cont->IsBranch()) {
1000 inputs[input_count++] = g.Label(cont->true_block());
1001 inputs[input_count++] = g.Label(cont->false_block());
1002 selector->Emit(opcode, 0, nullptr, input_count, inputs);
1003 } else {
1004 DCHECK(cont->IsSet());
1005 InstructionOperand output = g.DefineAsRegister(cont->result());
1006 selector->Emit(opcode, 1, &output, input_count, inputs);
1007 }
1008 }
1009
1010 // Determines if `input' of `node' can be replaced by a memory operand.
1011 bool CanUseMemOp(InstructionCode opcode, Node* node, Node* input) {
Benedikt Meurer 2016/02/18 05:02:53 Nit: Please use complete workds as in the rest of
epertoso 2016/02/18 10:58:29 Done.
1012 if (input->opcode() == IrOpcode::kLoad && input->OwnedBy(node)) {
Benedikt Meurer 2016/02/18 05:02:53 OwnedBy is not enough here. You need to use CanCov
epertoso 2016/02/18 10:58:29 Done. Also added the effect level check.
1013 if (LoadRepresentationOf(input->op()).representation() ==
1014 MachineRepresentation::kWord32) {
1015 return (opcode == kIA32Cmp || opcode == kIA32Test);
1016 }
1017 }
1018 return false;
1019 }
1020
1021 // Shared routine for multiple compare operations.
1022 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
987 InstructionOperand left, InstructionOperand right, 1023 InstructionOperand left, InstructionOperand right,
988 FlagsContinuation* cont) { 1024 FlagsContinuation* cont) {
989 IA32OperandGenerator g(selector); 1025 VisitCompare(selector, opcode, 1, &left, right, cont);
990 if (cont->IsBranch()) {
991 selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right,
992 g.Label(cont->true_block()), g.Label(cont->false_block()));
993 } else {
994 DCHECK(cont->IsSet());
995 selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()),
996 left, right);
997 }
998 } 1026 }
999 1027
1000 1028
1001 // Shared routine for multiple compare operations. 1029 // Shared routine for multiple compare operations.
1002 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1030 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1003 Node* left, Node* right, FlagsContinuation* cont, 1031 Node* left, Node* right, FlagsContinuation* cont,
1004 bool commutative) { 1032 bool commutative, Node* node = nullptr) {
1005 IA32OperandGenerator g(selector); 1033 IA32OperandGenerator g(selector);
1006 if (commutative && g.CanBeBetterLeftOperand(right)) { 1034 if (commutative && g.CanBeBetterLeftOperand(right)) {
1007 std::swap(left, right); 1035 std::swap(left, right);
1008 } 1036 }
1009 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); 1037 if (node && CanUseMemOp(opcode, node, left)) {
Benedikt Meurer 2016/02/18 05:02:53 This is not safe unless you also know that there's
epertoso 2016/02/18 10:58:29 Done in CanUseMemoryOperand.
1038 size_t input_count = 0;
1039 InstructionOperand inputs[4];
1040 AddressingMode addressing_mode =
1041 g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count);
1042 opcode |= AddressingModeField::encode(addressing_mode);
1043 VisitCompare(selector, opcode, input_count, inputs, g.Use(right), cont);
1044 } else {
1045 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
1046 }
1010 } 1047 }
1011 1048
1012 1049
1013 // Shared routine for multiple float32 compare operations (inputs commuted). 1050 // Shared routine for multiple float32 compare operations (inputs commuted).
1014 void VisitFloat32Compare(InstructionSelector* selector, Node* node, 1051 void VisitFloat32Compare(InstructionSelector* selector, Node* node,
1015 FlagsContinuation* cont) { 1052 FlagsContinuation* cont) {
1016 Node* const left = node->InputAt(0); 1053 Node* const left = node->InputAt(0);
1017 Node* const right = node->InputAt(1); 1054 Node* const right = node->InputAt(1);
1018 VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); 1055 VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false);
1019 } 1056 }
1020 1057
1021 1058
1022 // Shared routine for multiple float64 compare operations (inputs commuted). 1059 // Shared routine for multiple float64 compare operations (inputs commuted).
1023 void VisitFloat64Compare(InstructionSelector* selector, Node* node, 1060 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
1024 FlagsContinuation* cont) { 1061 FlagsContinuation* cont) {
1025 Node* const left = node->InputAt(0); 1062 Node* const left = node->InputAt(0);
1026 Node* const right = node->InputAt(1); 1063 Node* const right = node->InputAt(1);
1027 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); 1064 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false);
1028 } 1065 }
1029 1066
1030 1067
1031 // Shared routine for multiple word compare operations. 1068 // Shared routine for multiple word compare operations.
1032 void VisitWordCompare(InstructionSelector* selector, Node* node, 1069 void VisitWordCompare(InstructionSelector* selector, Node* node,
1033 InstructionCode opcode, FlagsContinuation* cont) { 1070 InstructionCode opcode, FlagsContinuation* cont) {
1034 IA32OperandGenerator g(selector); 1071 IA32OperandGenerator g(selector);
1035 Node* const left = node->InputAt(0); 1072 Node* left = node->InputAt(0);
1036 Node* const right = node->InputAt(1); 1073 Node* right = node->InputAt(1);
1037 1074
1038 // Match immediates on left or right side of comparison. 1075 if (!g.CanBeImmediate(right) && g.CanBeImmediate(left)) {
1076 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
1077 std::swap(left, right);
1078 }
1079
1080 // Match immediates on right side of comparison.
1039 if (g.CanBeImmediate(right)) { 1081 if (g.CanBeImmediate(right)) {
1040 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont); 1082 if (CanUseMemOp(opcode, node, left)) {
1041 } else if (g.CanBeImmediate(left)) { 1083 size_t left_operands_count = 0;
1042 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); 1084 InstructionOperand left_operands[4];
1043 VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont); 1085 AddressingMode addressing_mode = g.GetEffectiveAddressMemoryOperand(
1086 left, left_operands, &left_operands_count);
1087 opcode |= AddressingModeField::encode(addressing_mode);
1088 VisitCompare(selector, opcode, left_operands_count, left_operands,
1089 g.UseImmediate(right), cont);
1090 } else {
1091 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
1092 }
1044 } else { 1093 } else {
1045 VisitCompare(selector, opcode, left, right, cont, 1094 VisitCompare(selector, opcode, left, right, cont,
1046 node->op()->HasProperty(Operator::kCommutative)); 1095 node->op()->HasProperty(Operator::kCommutative), node);
1047 } 1096 }
1048 } 1097 }
1049 1098
1050 1099
1051 void VisitWordCompare(InstructionSelector* selector, Node* node, 1100 void VisitWordCompare(InstructionSelector* selector, Node* node,
1052 FlagsContinuation* cont) { 1101 FlagsContinuation* cont) {
1053 IA32OperandGenerator g(selector); 1102 IA32OperandGenerator g(selector);
1054 Int32BinopMatcher m(node); 1103 Int32BinopMatcher m(node);
1055 if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { 1104 if (m.left().IsLoad() && m.right().IsLoadStackPointer()) {
1056 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); 1105 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node());
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 MachineOperatorBuilder::kFloat64RoundTruncate | 1399 MachineOperatorBuilder::kFloat64RoundTruncate |
1351 MachineOperatorBuilder::kFloat32RoundTiesEven | 1400 MachineOperatorBuilder::kFloat32RoundTiesEven |
1352 MachineOperatorBuilder::kFloat64RoundTiesEven; 1401 MachineOperatorBuilder::kFloat64RoundTiesEven;
1353 } 1402 }
1354 return flags; 1403 return flags;
1355 } 1404 }
1356 1405
1357 } // namespace compiler 1406 } // namespace compiler
1358 } // namespace internal 1407 } // namespace internal
1359 } // namespace v8 1408 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698