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

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

Issue 1414183006: [turbofan] Avoid unnecessary write barriers and improve code generation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix typo. Created 5 years, 1 month 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 208 }
209 209
210 210
211 void InstructionSelector::VisitStore(Node* node) { 211 void InstructionSelector::VisitStore(Node* node) {
212 IA32OperandGenerator g(this); 212 IA32OperandGenerator g(this);
213 Node* base = node->InputAt(0); 213 Node* base = node->InputAt(0);
214 Node* index = node->InputAt(1); 214 Node* index = node->InputAt(1);
215 Node* value = node->InputAt(2); 215 Node* value = node->InputAt(2);
216 216
217 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 217 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
218 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
218 MachineType rep = RepresentationOf(store_rep.machine_type()); 219 MachineType rep = RepresentationOf(store_rep.machine_type());
219 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { 220
221 if (write_barrier_kind != kNoWriteBarrier) {
220 DCHECK_EQ(kRepTagged, rep); 222 DCHECK_EQ(kRepTagged, rep);
221 // TODO(dcarney): refactor RecordWrite function to take temp registers 223 AddressingMode addressing_mode;
222 // and pass them here instead of using fixed regs 224 InstructionOperand inputs[3];
225 size_t input_count = 0;
226 inputs[input_count++] = g.UseUniqueRegister(base);
223 if (g.CanBeImmediate(index)) { 227 if (g.CanBeImmediate(index)) {
224 InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister()}; 228 inputs[input_count++] = g.UseImmediate(index);
225 Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), 229 addressing_mode = kMode_MRI;
226 g.UseImmediate(index), g.UseFixed(value, ecx), arraysize(temps),
227 temps);
228 } else { 230 } else {
229 InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; 231 inputs[input_count++] = g.UseUniqueRegister(index);
230 Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), 232 addressing_mode = kMode_MR1;
231 g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps),
232 temps);
233 } 233 }
234 return; 234 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
235 ? g.UseRegister(value)
236 : g.UseUniqueRegister(value);
237 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
238 switch (write_barrier_kind) {
239 case kNoWriteBarrier:
240 UNREACHABLE();
241 break;
242 case kMapWriteBarrier:
243 record_write_mode = RecordWriteMode::kValueIsMap;
244 break;
245 case kPointerWriteBarrier:
246 record_write_mode = RecordWriteMode::kValueIsPointer;
247 break;
248 case kFullWriteBarrier:
249 record_write_mode = RecordWriteMode::kValueIsAny;
250 break;
251 }
252 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
253 size_t const temp_count = arraysize(temps);
254 InstructionCode code = kArchStoreWithWriteBarrier;
255 code |= AddressingModeField::encode(addressing_mode);
256 code |= MiscField::encode(static_cast<int>(record_write_mode));
257 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
258 } else {
259 ArchOpcode opcode;
260 switch (rep) {
261 case kRepFloat32:
262 opcode = kIA32Movss;
263 break;
264 case kRepFloat64:
265 opcode = kIA32Movsd;
266 break;
267 case kRepBit: // Fall through.
268 case kRepWord8:
269 opcode = kIA32Movb;
270 break;
271 case kRepWord16:
272 opcode = kIA32Movw;
273 break;
274 case kRepTagged: // Fall through.
275 case kRepWord32:
276 opcode = kIA32Movl;
277 break;
278 default:
279 UNREACHABLE();
280 return;
281 }
282
283 InstructionOperand val;
284 if (g.CanBeImmediate(value)) {
285 val = g.UseImmediate(value);
286 } else if (rep == kRepWord8 || rep == kRepBit) {
287 val = g.UseByteRegister(value);
288 } else {
289 val = g.UseRegister(value);
290 }
291
292 InstructionOperand inputs[4];
293 size_t input_count = 0;
294 AddressingMode addressing_mode =
295 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
296 InstructionCode code =
297 opcode | AddressingModeField::encode(addressing_mode);
298 inputs[input_count++] = val;
299 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
235 } 300 }
236 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
237
238 ArchOpcode opcode;
239 switch (rep) {
240 case kRepFloat32:
241 opcode = kIA32Movss;
242 break;
243 case kRepFloat64:
244 opcode = kIA32Movsd;
245 break;
246 case kRepBit: // Fall through.
247 case kRepWord8:
248 opcode = kIA32Movb;
249 break;
250 case kRepWord16:
251 opcode = kIA32Movw;
252 break;
253 case kRepTagged: // Fall through.
254 case kRepWord32:
255 opcode = kIA32Movl;
256 break;
257 default:
258 UNREACHABLE();
259 return;
260 }
261
262 InstructionOperand val;
263 if (g.CanBeImmediate(value)) {
264 val = g.UseImmediate(value);
265 } else if (rep == kRepWord8 || rep == kRepBit) {
266 val = g.UseByteRegister(value);
267 } else {
268 val = g.UseRegister(value);
269 }
270
271 InstructionOperand inputs[4];
272 size_t input_count = 0;
273 AddressingMode mode =
274 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
275 InstructionCode code = opcode | AddressingModeField::encode(mode);
276 inputs[input_count++] = val;
277 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
278 } 301 }
279 302
280 303
281 void InstructionSelector::VisitCheckedLoad(Node* node) { 304 void InstructionSelector::VisitCheckedLoad(Node* node) {
282 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 305 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
283 MachineType typ = TypeOf(OpParameter<MachineType>(node)); 306 MachineType typ = TypeOf(OpParameter<MachineType>(node));
284 IA32OperandGenerator g(this); 307 IA32OperandGenerator g(this);
285 Node* const buffer = node->InputAt(0); 308 Node* const buffer = node->InputAt(0);
286 Node* const offset = node->InputAt(1); 309 Node* const offset = node->InputAt(1);
287 Node* const length = node->InputAt(2); 310 Node* const length = node->InputAt(2);
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 if (CpuFeatures::IsSupported(SSE4_1)) { 1276 if (CpuFeatures::IsSupported(SSE4_1)) {
1254 flags |= MachineOperatorBuilder::kFloat64RoundDown | 1277 flags |= MachineOperatorBuilder::kFloat64RoundDown |
1255 MachineOperatorBuilder::kFloat64RoundTruncate; 1278 MachineOperatorBuilder::kFloat64RoundTruncate;
1256 } 1279 }
1257 return flags; 1280 return flags;
1258 } 1281 }
1259 1282
1260 } // namespace compiler 1283 } // namespace compiler
1261 } // namespace internal 1284 } // namespace internal
1262 } // namespace v8 1285 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698