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

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

Issue 2243843002: [ARM64] Optimize load followed by shift. (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 | « no previous file | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.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.h" 7 #include "src/compiler/node-properties.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 154
155 155
156 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, 156 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
157 ImmediateMode operand_mode) { 157 ImmediateMode operand_mode) {
158 Arm64OperandGenerator g(selector); 158 Arm64OperandGenerator g(selector);
159 selector->Emit(opcode, g.DefineAsRegister(node), 159 selector->Emit(opcode, g.DefineAsRegister(node),
160 g.UseRegister(node->InputAt(0)), 160 g.UseRegister(node->InputAt(0)),
161 g.UseOperand(node->InputAt(1), operand_mode)); 161 g.UseOperand(node->InputAt(1), operand_mode));
162 } 162 }
163 163
164 struct ExtendingLoadMatcher {
165 ExtendingLoadMatcher(Node* node, InstructionSelector* selector)
166 : matches_(false), selector_(selector), base_(nullptr), immediate_(0) {
167 Initialize(node);
168 }
169
170 bool Matches() const { return matches_; }
171
172 Node* base() const {
173 DCHECK(Matches());
174 return base_;
175 }
176 int64_t immediate() const {
177 DCHECK(Matches());
178 return immediate_;
179 }
180 ArchOpcode opcode() const {
181 DCHECK(Matches());
182 return opcode_;
183 }
184
185 private:
186 bool matches_;
187 InstructionSelector* selector_;
188 Node* base_;
189 int64_t immediate_;
190 ArchOpcode opcode_;
191
192 void Initialize(Node* node) {
193 Int64BinopMatcher m(node);
194 // When loading a 64-bit value and shifting by 32, we should
195 // just load and sign-extend the interesting 4 bytes instead.
196 // This happens, for example, when we're loading and untagging SMIs.
197 DCHECK(m.IsWord64Sar());
198 if (m.left().IsLoad() && m.right().Is(32) &&
199 selector_->CanCover(m.node(), m.left().node())) {
200 Arm64OperandGenerator g(selector_);
201 Node* load = m.left().node();
202 Node* offset = load->InputAt(1);
203 base_ = load->InputAt(0);
204 opcode_ = kArm64Ldrsw;
205 if (g.IsIntegerConstant(offset)) {
206 immediate_ = g.GetIntegerConstantValue(offset) + 4;
207 matches_ = g.CanBeImmediate(immediate_, kLoadStoreImm32);
208 }
209 }
210 }
211 };
212
213 bool TryMatchExtendingLoad(InstructionSelector* selector, Node* node) {
214 ExtendingLoadMatcher m(node, selector);
215 return m.Matches();
216 }
217
218 bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node) {
219 ExtendingLoadMatcher m(node, selector);
220 Arm64OperandGenerator g(selector);
221 if (m.Matches()) {
222 InstructionOperand inputs[2];
223 inputs[0] = g.UseRegister(m.base());
224 InstructionCode opcode =
225 m.opcode() | AddressingModeField::encode(kMode_MRI);
226 DCHECK(is_int32(m.immediate()));
227 inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate()));
228 InstructionOperand outputs[] = {g.DefineAsRegister(node)};
229 selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs),
230 inputs);
231 return true;
232 }
233 return false;
234 }
235
164 bool TryMatchAnyShift(InstructionSelector* selector, Node* node, 236 bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
165 Node* input_node, InstructionCode* opcode, bool try_ror) { 237 Node* input_node, InstructionCode* opcode, bool try_ror) {
166 Arm64OperandGenerator g(selector); 238 Arm64OperandGenerator g(selector);
167 239
168 if (!selector->CanCover(node, input_node)) return false; 240 if (!selector->CanCover(node, input_node)) return false;
169 if (input_node->InputCount() != 2) return false; 241 if (input_node->InputCount() != 2) return false;
170 if (!g.IsIntegerConstant(input_node->InputAt(1))) return false; 242 if (!g.IsIntegerConstant(input_node->InputAt(1))) return false;
171 243
172 switch (input_node->opcode()) { 244 switch (input_node->opcode()) {
173 case IrOpcode::kWord32Shl: 245 case IrOpcode::kWord32Shl:
174 case IrOpcode::kWord64Shl: 246 case IrOpcode::kWord64Shl:
175 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I); 247 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
176 return true; 248 return true;
177 case IrOpcode::kWord32Shr: 249 case IrOpcode::kWord32Shr:
178 case IrOpcode::kWord64Shr: 250 case IrOpcode::kWord64Shr:
179 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); 251 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSR_I);
180 return true; 252 return true;
181 case IrOpcode::kWord32Sar: 253 case IrOpcode::kWord32Sar:
254 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I);
255 return true;
182 case IrOpcode::kWord64Sar: 256 case IrOpcode::kWord64Sar:
257 if (TryMatchExtendingLoad(selector, input_node)) return false;
183 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I); 258 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I);
184 return true; 259 return true;
185 case IrOpcode::kWord32Ror: 260 case IrOpcode::kWord32Ror:
186 case IrOpcode::kWord64Ror: 261 case IrOpcode::kWord64Ror:
187 if (try_ror) { 262 if (try_ror) {
188 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ROR_I); 263 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
189 return true; 264 return true;
190 } 265 }
191 return false; 266 return false;
192 default: 267 default:
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 g.UseImmediate(node->InputAt(1))); 1198 g.UseImmediate(node->InputAt(1)));
1124 return; 1199 return;
1125 } 1200 }
1126 } 1201 }
1127 1202
1128 VisitRRO(this, kArm64Asr32, node, kShift32Imm); 1203 VisitRRO(this, kArm64Asr32, node, kShift32Imm);
1129 } 1204 }
1130 1205
1131 1206
1132 void InstructionSelector::VisitWord64Sar(Node* node) { 1207 void InstructionSelector::VisitWord64Sar(Node* node) {
1208 if (TryEmitExtendingLoad(this, node)) return;
1133 VisitRRO(this, kArm64Asr, node, kShift64Imm); 1209 VisitRRO(this, kArm64Asr, node, kShift64Imm);
1134 } 1210 }
1135 1211
1136 1212
1137 void InstructionSelector::VisitWord32Ror(Node* node) { 1213 void InstructionSelector::VisitWord32Ror(Node* node) {
1138 VisitRRO(this, kArm64Ror32, node, kShift32Imm); 1214 VisitRRO(this, kArm64Ror32, node, kShift32Imm);
1139 } 1215 }
1140 1216
1141 1217
1142 void InstructionSelector::VisitWord64Ror(Node* node) { 1218 void InstructionSelector::VisitWord64Ror(Node* node) {
(...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after
2713 // static 2789 // static
2714 MachineOperatorBuilder::AlignmentRequirements 2790 MachineOperatorBuilder::AlignmentRequirements
2715 InstructionSelector::AlignmentRequirements() { 2791 InstructionSelector::AlignmentRequirements() {
2716 return MachineOperatorBuilder::AlignmentRequirements:: 2792 return MachineOperatorBuilder::AlignmentRequirements::
2717 FullUnalignedAccessSupport(); 2793 FullUnalignedAccessSupport();
2718 } 2794 }
2719 2795
2720 } // namespace compiler 2796 } // namespace compiler
2721 } // namespace internal 2797 } // namespace internal
2722 } // namespace v8 2798 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698