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

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

Issue 2265073003: S390: Optimize For Mul in TurboFan codegen (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 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
« no previous file with comments | « src/compiler/s390/code-generator-s390.cc ('k') | src/s390/assembler-s390.h » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 #include "src/s390/frames-s390.h" 9 #include "src/s390/frames-s390.h"
10 10
(...skipping 17 matching lines...) Expand all
28 explicit S390OperandGenerator(InstructionSelector* selector) 28 explicit S390OperandGenerator(InstructionSelector* selector)
29 : OperandGenerator(selector) {} 29 : OperandGenerator(selector) {}
30 30
31 InstructionOperand UseOperand(Node* node, ImmediateMode mode) { 31 InstructionOperand UseOperand(Node* node, ImmediateMode mode) {
32 if (CanBeImmediate(node, mode)) { 32 if (CanBeImmediate(node, mode)) {
33 return UseImmediate(node); 33 return UseImmediate(node);
34 } 34 }
35 return UseRegister(node); 35 return UseRegister(node);
36 } 36 }
37 37
38 int64_t GetImmediate(Node* node) {
39 if (node->opcode() == IrOpcode::kInt32Constant)
40 return OpParameter<int32_t>(node);
41 else if (node->opcode() == IrOpcode::kInt64Constant)
42 return OpParameter<int64_t>(node);
43 else
44 UNIMPLEMENTED();
45 return 0L;
46 }
47
38 bool CanBeImmediate(Node* node, ImmediateMode mode) { 48 bool CanBeImmediate(Node* node, ImmediateMode mode) {
39 int64_t value; 49 int64_t value;
40 if (node->opcode() == IrOpcode::kInt32Constant) 50 if (node->opcode() == IrOpcode::kInt32Constant)
41 value = OpParameter<int32_t>(node); 51 value = OpParameter<int32_t>(node);
42 else if (node->opcode() == IrOpcode::kInt64Constant) 52 else if (node->opcode() == IrOpcode::kInt64Constant)
43 value = OpParameter<int64_t>(node); 53 value = OpParameter<int64_t>(node);
44 else 54 else
45 return false; 55 return false;
46 return CanBeImmediate(value, mode); 56 return CanBeImmediate(value, mode);
47 } 57 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 DCHECK(m.scale() == 0); 135 DCHECK(m.scale() == 0);
126 return GenerateMemoryOperandInputs(m.index(), m.base(), m.displacement(), 136 return GenerateMemoryOperandInputs(m.index(), m.base(), m.displacement(),
127 m.displacement_mode(), inputs, 137 m.displacement_mode(), inputs,
128 input_count); 138 input_count);
129 } else { 139 } else {
130 inputs[(*input_count)++] = UseRegister(operand->InputAt(0)); 140 inputs[(*input_count)++] = UseRegister(operand->InputAt(0));
131 inputs[(*input_count)++] = UseRegister(operand->InputAt(1)); 141 inputs[(*input_count)++] = UseRegister(operand->InputAt(1));
132 return kMode_MRR; 142 return kMode_MRR;
133 } 143 }
134 } 144 }
145
146 bool CanBeBetterLeftOperand(Node* node) const {
147 return !selector()->IsLive(node);
148 }
149
150 MachineRepresentation GetRepresentation(Node* node) {
151 return sequence()->GetRepresentation(selector()->GetVirtualRegister(node));
152 }
153
154 bool Is64BitOperand(Node* node) {
155 return MachineRepresentation::kWord64 == GetRepresentation(node);
156 }
135 }; 157 };
136 158
137 namespace { 159 namespace {
138 160
139 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { 161 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
140 S390OperandGenerator g(selector); 162 S390OperandGenerator g(selector);
141 selector->Emit(opcode, g.DefineAsRegister(node), 163 selector->Emit(opcode, g.DefineAsRegister(node),
142 g.UseRegister(node->InputAt(0))); 164 g.UseRegister(node->InputAt(0)));
143 } 165 }
144 166
(...skipping 30 matching lines...) Expand all
175 } 197 }
176 #endif 198 #endif
177 199
178 // Shared routine for multiple binary operations. 200 // Shared routine for multiple binary operations.
179 template <typename Matcher> 201 template <typename Matcher>
180 void VisitBinop(InstructionSelector* selector, Node* node, 202 void VisitBinop(InstructionSelector* selector, Node* node,
181 InstructionCode opcode, ImmediateMode operand_mode, 203 InstructionCode opcode, ImmediateMode operand_mode,
182 FlagsContinuation* cont) { 204 FlagsContinuation* cont) {
183 S390OperandGenerator g(selector); 205 S390OperandGenerator g(selector);
184 Matcher m(node); 206 Matcher m(node);
207 Node* left = m.left().node();
208 Node* right = m.right().node();
185 InstructionOperand inputs[4]; 209 InstructionOperand inputs[4];
186 size_t input_count = 0; 210 size_t input_count = 0;
187 InstructionOperand outputs[2]; 211 InstructionOperand outputs[2];
188 size_t output_count = 0; 212 size_t output_count = 0;
189 213
190 inputs[input_count++] = g.UseRegister(m.left().node()); 214 // TODO(turbofan): match complex addressing modes.
191 inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode); 215 if (left == right) {
216 // If both inputs refer to the same operand, enforce allocating a register
217 // for both of them to ensure that we don't end up generating code like
218 // this:
219 //
220 // mov rax, [rbp-0x10]
221 // add rax, [rbp-0x10]
222 // jo label
223 InstructionOperand const input = g.UseRegister(left);
224 inputs[input_count++] = input;
225 inputs[input_count++] = input;
226 } else if (g.CanBeImmediate(right, operand_mode)) {
227 inputs[input_count++] = g.UseRegister(left);
228 inputs[input_count++] = g.UseImmediate(right);
229 } else {
230 if (node->op()->HasProperty(Operator::kCommutative) &&
231 g.CanBeBetterLeftOperand(right)) {
232 std::swap(left, right);
233 }
234 inputs[input_count++] = g.UseRegister(left);
235 inputs[input_count++] = g.UseRegister(right);
236 }
192 237
193 if (cont->IsBranch()) { 238 if (cont->IsBranch()) {
194 inputs[input_count++] = g.Label(cont->true_block()); 239 inputs[input_count++] = g.Label(cont->true_block());
195 inputs[input_count++] = g.Label(cont->false_block()); 240 inputs[input_count++] = g.Label(cont->false_block());
196 } 241 }
197 242
198 if (cont->IsDeoptimize()) { 243 if (cont->IsDeoptimize()) {
199 // If we can deoptimize as a result of the binop, we need to make sure that 244 // If we can deoptimize as a result of the binop, we need to make sure that
200 // the deopt inputs are not overwritten by the binop result. One way 245 // the deopt inputs are not overwritten by the binop result. One way
201 // to achieve that is to declare the output register as same-as-first. 246 // to achieve that is to declare the output register as same-as-first.
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 { 1040 {
996 InstructionOperand shift_31 = g.UseImmediate(31); 1041 InstructionOperand shift_31 = g.UseImmediate(31);
997 InstructionOperand outputs[] = {temp_operand}; 1042 InstructionOperand outputs[] = {temp_operand};
998 InstructionOperand inputs[] = {result_operand, shift_31}; 1043 InstructionOperand inputs[] = {result_operand, shift_31};
999 selector->Emit(kS390_ShiftRightArith32, 1, outputs, 2, inputs); 1044 selector->Emit(kS390_ShiftRightArith32, 1, outputs, 2, inputs);
1000 } 1045 }
1001 1046
1002 VisitCompare(selector, kS390_Cmp32, high32_operand, temp_operand, cont); 1047 VisitCompare(selector, kS390_Cmp32, high32_operand, temp_operand, cont);
1003 } 1048 }
1004 1049
1050 void VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
1051 S390OperandGenerator g(selector);
1052 Int32BinopMatcher m(node);
1053 Node* left = m.left().node();
1054 Node* right = m.right().node();
1055 if (g.CanBeImmediate(right, kInt32Imm)) {
1056 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
1057 g.UseImmediate(right));
1058 } else {
1059 if (g.CanBeBetterLeftOperand(right)) {
1060 std::swap(left, right);
1061 }
1062 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
1063 g.Use(right));
1064 }
1065 }
1066
1005 } // namespace 1067 } // namespace
1006 1068
1069 void InstructionSelector::VisitInt32MulWithOverflow(Node* node) {
1070 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1071 FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf);
1072 return EmitInt32MulWithOverflow(this, node, &cont);
1073 }
1074 VisitMul(this, node, kS390_Mul32);
1075 // FlagsContinuation cont;
1076 // EmitInt32MulWithOverflow(this, node, &cont);
1077 }
1078
1007 void InstructionSelector::VisitInt32Mul(Node* node) { 1079 void InstructionSelector::VisitInt32Mul(Node* node) {
1008 VisitRRR(this, kS390_Mul32, node); 1080 S390OperandGenerator g(this);
1081 Int32BinopMatcher m(node);
1082 Node* left = m.left().node();
1083 Node* right = m.right().node();
1084 if (g.CanBeImmediate(right, kInt32Imm) &&
1085 base::bits::IsPowerOfTwo32(g.GetImmediate(right))) {
1086 int power = 31 - base::bits::CountLeadingZeros32(g.GetImmediate(right));
1087 Emit(kS390_ShiftLeft32, g.DefineSameAsFirst(node), g.UseRegister(left),
1088 g.UseImmediate(power));
1089 return;
1090 }
1091 VisitMul(this, node, kS390_Mul32);
1009 } 1092 }
1010 1093
1011 #if V8_TARGET_ARCH_S390X 1094 #if V8_TARGET_ARCH_S390X
1012 void InstructionSelector::VisitInt64Mul(Node* node) { 1095 void InstructionSelector::VisitInt64Mul(Node* node) {
1013 VisitRRR(this, kS390_Mul64, node); 1096 S390OperandGenerator g(this);
1097 Int64BinopMatcher m(node);
1098 Node* left = m.left().node();
1099 Node* right = m.right().node();
1100 if (g.CanBeImmediate(right, kInt32Imm) &&
1101 base::bits::IsPowerOfTwo64(g.GetImmediate(right))) {
1102 int power = 31 - base::bits::CountLeadingZeros64(g.GetImmediate(right));
1103 Emit(kS390_ShiftLeft64, g.DefineSameAsFirst(node), g.UseRegister(left),
1104 g.UseImmediate(power));
1105 return;
1106 }
1107 VisitMul(this, node, kS390_Mul64);
1014 } 1108 }
1015 #endif 1109 #endif
1016 1110
1017 void InstructionSelector::VisitInt32MulHigh(Node* node) { 1111 void InstructionSelector::VisitInt32MulHigh(Node* node) {
1018 S390OperandGenerator g(this); 1112 S390OperandGenerator g(this);
1019 Emit(kS390_MulHigh32, g.DefineAsRegister(node), 1113 Int32BinopMatcher m(node);
1020 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); 1114 Node* left = m.left().node();
1115 Node* right = m.right().node();
1116 if (g.CanBeBetterLeftOperand(right)) {
1117 std::swap(left, right);
1118 }
1119 Emit(kS390_MulHigh32, g.DefineAsRegister(node), g.UseRegister(left),
1120 g.Use(right));
1021 } 1121 }
1022 1122
1023 void InstructionSelector::VisitUint32MulHigh(Node* node) { 1123 void InstructionSelector::VisitUint32MulHigh(Node* node) {
1024 S390OperandGenerator g(this); 1124 S390OperandGenerator g(this);
1025 Emit(kS390_MulHighU32, g.DefineAsRegister(node), 1125 Int32BinopMatcher m(node);
1026 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); 1126 Node* left = m.left().node();
1127 Node* right = m.right().node();
1128 if (g.CanBeBetterLeftOperand(right)) {
1129 std::swap(left, right);
1130 }
1131 Emit(kS390_MulHighU32, g.DefineAsRegister(node), g.UseRegister(left),
1132 g.Use(right));
1027 } 1133 }
1028 1134
1029 void InstructionSelector::VisitInt32Div(Node* node) { 1135 void InstructionSelector::VisitInt32Div(Node* node) {
1030 VisitRRR(this, kS390_Div32, node); 1136 VisitRRR(this, kS390_Div32, node);
1031 } 1137 }
1032 1138
1033 #if V8_TARGET_ARCH_S390X 1139 #if V8_TARGET_ARCH_S390X
1034 void InstructionSelector::VisitInt64Div(Node* node) { 1140 void InstructionSelector::VisitInt64Div(Node* node) {
1035 VisitRRR(this, kS390_Div64, node); 1141 VisitRRR(this, kS390_Div64, node);
1036 } 1142 }
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 VisitWord64Compare(this, node, &cont); 1820 VisitWord64Compare(this, node, &cont);
1715 } 1821 }
1716 1822
1717 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { 1823 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
1718 FlagsContinuation cont = 1824 FlagsContinuation cont =
1719 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); 1825 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1720 VisitWord64Compare(this, node, &cont); 1826 VisitWord64Compare(this, node, &cont);
1721 } 1827 }
1722 #endif 1828 #endif
1723 1829
1724 void InstructionSelector::VisitInt32MulWithOverflow(Node* node) {
1725 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1726 FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf);
1727 return EmitInt32MulWithOverflow(this, node, &cont);
1728 }
1729 FlagsContinuation cont;
1730 EmitInt32MulWithOverflow(this, node, &cont);
1731 }
1732
1733 void InstructionSelector::VisitFloat32Equal(Node* node) { 1830 void InstructionSelector::VisitFloat32Equal(Node* node) {
1734 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); 1831 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1735 VisitFloat32Compare(this, node, &cont); 1832 VisitFloat32Compare(this, node, &cont);
1736 } 1833 }
1737 1834
1738 void InstructionSelector::VisitFloat32LessThan(Node* node) { 1835 void InstructionSelector::VisitFloat32LessThan(Node* node) {
1739 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); 1836 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1740 VisitFloat32Compare(this, node, &cont); 1837 VisitFloat32Compare(this, node, &cont);
1741 } 1838 }
1742 1839
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 // static 2018 // static
1922 MachineOperatorBuilder::AlignmentRequirements 2019 MachineOperatorBuilder::AlignmentRequirements
1923 InstructionSelector::AlignmentRequirements() { 2020 InstructionSelector::AlignmentRequirements() {
1924 return MachineOperatorBuilder::AlignmentRequirements:: 2021 return MachineOperatorBuilder::AlignmentRequirements::
1925 FullUnalignedAccessSupport(); 2022 FullUnalignedAccessSupport();
1926 } 2023 }
1927 2024
1928 } // namespace compiler 2025 } // namespace compiler
1929 } // namespace internal 2026 } // namespace internal
1930 } // namespace v8 2027 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/s390/code-generator-s390.cc ('k') | src/s390/assembler-s390.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698