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

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.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/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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 386 }
387 387
388 388
389 void InstructionSelector::VisitStore(Node* node) { 389 void InstructionSelector::VisitStore(Node* node) {
390 Arm64OperandGenerator g(this); 390 Arm64OperandGenerator g(this);
391 Node* base = node->InputAt(0); 391 Node* base = node->InputAt(0);
392 Node* index = node->InputAt(1); 392 Node* index = node->InputAt(1);
393 Node* value = node->InputAt(2); 393 Node* value = node->InputAt(2);
394 394
395 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 395 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
396 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
396 MachineType rep = RepresentationOf(store_rep.machine_type()); 397 MachineType rep = RepresentationOf(store_rep.machine_type());
397 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { 398
398 DCHECK(rep == kRepTagged); 399 // TODO(arm64): I guess this could be done in a better way.
399 // TODO(dcarney): refactor RecordWrite function to take temp registers 400 if (write_barrier_kind != kNoWriteBarrier) {
400 // and pass them here instead of using fixed regs 401 DCHECK_EQ(kRepTagged, rep);
401 // TODO(dcarney): handle immediate indices. 402 InstructionOperand inputs[3];
402 InstructionOperand temps[] = {g.TempRegister(x11), g.TempRegister(x12)}; 403 size_t input_count = 0;
403 Emit(kArm64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, x10), 404 inputs[input_count++] = g.UseUniqueRegister(base);
404 g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps), 405 inputs[input_count++] = g.UseUniqueRegister(index);
405 temps); 406 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
406 return; 407 ? g.UseRegister(value)
407 } 408 : g.UseUniqueRegister(value);
408 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); 409 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
409 ArchOpcode opcode; 410 switch (write_barrier_kind) {
410 ImmediateMode immediate_mode = kNoImmediate; 411 case kNoWriteBarrier:
411 switch (rep) { 412 UNREACHABLE();
412 case kRepFloat32: 413 break;
413 opcode = kArm64StrS; 414 case kMapWriteBarrier:
414 immediate_mode = kLoadStoreImm32; 415 record_write_mode = RecordWriteMode::kValueIsMap;
415 break; 416 break;
416 case kRepFloat64: 417 case kPointerWriteBarrier:
417 opcode = kArm64StrD; 418 record_write_mode = RecordWriteMode::kValueIsPointer;
418 immediate_mode = kLoadStoreImm64; 419 break;
419 break; 420 case kFullWriteBarrier:
420 case kRepBit: // Fall through. 421 record_write_mode = RecordWriteMode::kValueIsAny;
421 case kRepWord8: 422 break;
422 opcode = kArm64Strb; 423 }
423 immediate_mode = kLoadStoreImm8; 424 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
424 break; 425 size_t const temp_count = arraysize(temps);
425 case kRepWord16: 426 InstructionCode code = kArchStoreWithWriteBarrier;
426 opcode = kArm64Strh; 427 code |= MiscField::encode(static_cast<int>(record_write_mode));
427 immediate_mode = kLoadStoreImm16; 428 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
428 break;
429 case kRepWord32:
430 opcode = kArm64StrW;
431 immediate_mode = kLoadStoreImm32;
432 break;
433 case kRepTagged: // Fall through.
434 case kRepWord64:
435 opcode = kArm64Str;
436 immediate_mode = kLoadStoreImm64;
437 break;
438 default:
439 UNREACHABLE();
440 return;
441 }
442 if (g.CanBeImmediate(index, immediate_mode)) {
443 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
444 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
445 } else { 429 } else {
446 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), 430 ArchOpcode opcode;
447 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); 431 ImmediateMode immediate_mode = kNoImmediate;
432 switch (rep) {
433 case kRepFloat32:
434 opcode = kArm64StrS;
435 immediate_mode = kLoadStoreImm32;
436 break;
437 case kRepFloat64:
438 opcode = kArm64StrD;
439 immediate_mode = kLoadStoreImm64;
440 break;
441 case kRepBit: // Fall through.
442 case kRepWord8:
443 opcode = kArm64Strb;
444 immediate_mode = kLoadStoreImm8;
445 break;
446 case kRepWord16:
447 opcode = kArm64Strh;
448 immediate_mode = kLoadStoreImm16;
449 break;
450 case kRepWord32:
451 opcode = kArm64StrW;
452 immediate_mode = kLoadStoreImm32;
453 break;
454 case kRepTagged: // Fall through.
455 case kRepWord64:
456 opcode = kArm64Str;
457 immediate_mode = kLoadStoreImm64;
458 break;
459 default:
460 UNREACHABLE();
461 return;
462 }
463 if (g.CanBeImmediate(index, immediate_mode)) {
464 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
465 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
466 } else {
467 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(),
468 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
469 }
448 } 470 }
449 } 471 }
450 472
451 473
452 void InstructionSelector::VisitCheckedLoad(Node* node) { 474 void InstructionSelector::VisitCheckedLoad(Node* node) {
453 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 475 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
454 MachineType typ = TypeOf(OpParameter<MachineType>(node)); 476 MachineType typ = TypeOf(OpParameter<MachineType>(node));
455 Arm64OperandGenerator g(this); 477 Arm64OperandGenerator g(this);
456 Node* const buffer = node->InputAt(0); 478 Node* const buffer = node->InputAt(0);
457 Node* const offset = node->InputAt(1); 479 Node* const offset = node->InputAt(1);
(...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 MachineOperatorBuilder::kFloat64RoundTruncate | 2028 MachineOperatorBuilder::kFloat64RoundTruncate |
2007 MachineOperatorBuilder::kFloat64RoundTiesAway | 2029 MachineOperatorBuilder::kFloat64RoundTiesAway |
2008 MachineOperatorBuilder::kWord32ShiftIsSafe | 2030 MachineOperatorBuilder::kWord32ShiftIsSafe |
2009 MachineOperatorBuilder::kInt32DivIsSafe | 2031 MachineOperatorBuilder::kInt32DivIsSafe |
2010 MachineOperatorBuilder::kUint32DivIsSafe; 2032 MachineOperatorBuilder::kUint32DivIsSafe;
2011 } 2033 }
2012 2034
2013 } // namespace compiler 2035 } // namespace compiler
2014 } // namespace internal 2036 } // namespace internal
2015 } // namespace v8 2037 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698