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

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

Issue 2546113002: [turbofan] Improve memory consumption for state values descriptors. (Closed)
Patch Set: Do not store optimized-out into instructions. Created 4 years 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.h" 5 #include "src/compiler/instruction-selector.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/adapters.h" 9 #include "src/base/adapters.h"
10 #include "src/compiler/compiler-source-position-table.h" 10 #include "src/compiler/compiler-source-position-table.h"
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 UnallocatedOperand unalloc = UnallocatedOperand::cast(op); 407 UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
408 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register()); 408 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
409 } 409 }
410 410
411 411
412 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, 412 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
413 Node* node) { 413 Node* node) {
414 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); 414 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
415 } 415 }
416 416
417
418 namespace { 417 namespace {
419 418
420 enum class FrameStateInputKind { kAny, kStackSlot };
421
422 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, 419 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
423 FrameStateInputKind kind, 420 FrameStateInputKind kind,
424 MachineRepresentation rep) { 421 MachineRepresentation rep) {
425 if (rep == MachineRepresentation::kNone) { 422 if (rep == MachineRepresentation::kNone) {
426 return g->TempImmediate(FrameStateDescriptor::kImpossibleValue); 423 return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
427 } 424 }
428 425
429 switch (input->opcode()) { 426 switch (input->opcode()) {
430 case IrOpcode::kInt32Constant: 427 case IrOpcode::kInt32Constant:
431 case IrOpcode::kInt64Constant: 428 case IrOpcode::kInt64Constant:
(...skipping 13 matching lines...) Expand all
445 case FrameStateInputKind::kAny: 442 case FrameStateInputKind::kAny:
446 // Currently deopts "wrap" other operations, so the deopt's inputs 443 // Currently deopts "wrap" other operations, so the deopt's inputs
447 // are potentially needed untill the end of the deoptimising code. 444 // are potentially needed untill the end of the deoptimising code.
448 return g->UseAnyAtEnd(input); 445 return g->UseAnyAtEnd(input);
449 } 446 }
450 } 447 }
451 UNREACHABLE(); 448 UNREACHABLE();
452 return InstructionOperand(); 449 return InstructionOperand();
453 } 450 }
454 451
452 } // namespace
455 453
456 class StateObjectDeduplicator { 454 class StateObjectDeduplicator {
457 public: 455 public:
458 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {} 456 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
459 static const size_t kNotDuplicated = SIZE_MAX; 457 static const size_t kNotDuplicated = SIZE_MAX;
460 458
461 size_t GetObjectId(Node* node) { 459 size_t GetObjectId(Node* node) {
462 for (size_t i = 0; i < objects_.size(); ++i) { 460 for (size_t i = 0; i < objects_.size(); ++i) {
463 if (objects_[i] == node) { 461 if (objects_[i] == node) {
464 return i; 462 return i;
465 } 463 }
466 } 464 }
467 return kNotDuplicated; 465 return kNotDuplicated;
468 } 466 }
469 467
470 size_t InsertObject(Node* node) { 468 size_t InsertObject(Node* node) {
471 size_t id = objects_.size(); 469 size_t id = objects_.size();
472 objects_.push_back(node); 470 objects_.push_back(node);
473 return id; 471 return id;
474 } 472 }
475 473
476 private: 474 private:
477 ZoneVector<Node*> objects_; 475 ZoneVector<Node*> objects_;
478 }; 476 };
479 477
480
481 // Returns the number of instruction operands added to inputs. 478 // Returns the number of instruction operands added to inputs.
482 size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor, 479 size_t InstructionSelector::AddOperandToStateValueDescriptor(
483 InstructionOperandVector* inputs, 480 StateValueList* values, InstructionOperandVector* inputs,
484 OperandGenerator* g, 481 OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* input,
485 StateObjectDeduplicator* deduplicator, 482 MachineType type, FrameStateInputKind kind, Zone* zone) {
486 Node* input, MachineType type,
487 FrameStateInputKind kind, Zone* zone) {
488 switch (input->opcode()) { 483 switch (input->opcode()) {
489 case IrOpcode::kObjectState: { 484 case IrOpcode::kObjectState: {
490 UNREACHABLE(); 485 UNREACHABLE();
491 return 0; 486 return 0;
492 } 487 }
493 case IrOpcode::kTypedObjectState: { 488 case IrOpcode::kTypedObjectState: {
494 size_t id = deduplicator->GetObjectId(input); 489 size_t id = deduplicator->GetObjectId(input);
495 if (id == StateObjectDeduplicator::kNotDuplicated) { 490 if (id == StateObjectDeduplicator::kNotDuplicated) {
496 size_t entries = 0; 491 size_t entries = 0;
497 id = deduplicator->InsertObject(input); 492 id = deduplicator->InsertObject(input);
498 descriptor->fields().push_back( 493 StateValueList* nested = values->PushRecursiveField(zone, id);
499 StateValueDescriptor::Recursive(zone, id));
500 StateValueDescriptor* new_desc = &descriptor->fields().back();
501 int const input_count = input->op()->ValueInputCount(); 494 int const input_count = input->op()->ValueInputCount();
502 ZoneVector<MachineType> const* types = MachineTypesOf(input->op()); 495 ZoneVector<MachineType> const* types = MachineTypesOf(input->op());
503 for (int i = 0; i < input_count; ++i) { 496 for (int i = 0; i < input_count; ++i) {
504 entries += AddOperandToStateValueDescriptor( 497 entries += AddOperandToStateValueDescriptor(
505 new_desc, inputs, g, deduplicator, input->InputAt(i), 498 nested, inputs, g, deduplicator, input->InputAt(i), types->at(i),
506 types->at(i), kind, zone); 499 kind, zone);
507 } 500 }
508 return entries; 501 return entries;
509 } else { 502 } else {
510 // Crankshaft counts duplicate objects for the running id, so we have 503 // Crankshaft counts duplicate objects for the running id, so we have
511 // to push the input again. 504 // to push the input again.
512 deduplicator->InsertObject(input); 505 deduplicator->InsertObject(input);
513 descriptor->fields().push_back( 506 values->PushDuplicate(id);
514 StateValueDescriptor::Duplicate(zone, id));
515 return 0; 507 return 0;
516 } 508 }
517 } 509 }
518 default: { 510 default: {
511 Heap* const heap = isolate()->heap();
512 if (input->opcode() == IrOpcode::kHeapConstant) {
513 Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input);
514 Heap::RootListIndex root_index;
515 if (heap->IsRootHandle(constant, &root_index) &&
516 root_index == Heap::kOptimizedOutRootIndex) {
517 values->PushOptimizedOut();
518 return 0;
519 }
520 }
519 inputs->push_back(OperandForDeopt(g, input, kind, type.representation())); 521 inputs->push_back(OperandForDeopt(g, input, kind, type.representation()));
520 descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type)); 522 values->PushPlain(type);
521 return 1; 523 return 1;
522 } 524 }
523 } 525 }
524 } 526 }
525 527
526 528
527 // Returns the number of instruction operands added to inputs. 529 // Returns the number of instruction operands added to inputs.
528 size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor, 530 size_t InstructionSelector::AddInputsToFrameStateDescriptor(
529 Node* state, OperandGenerator* g, 531 FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g,
530 StateObjectDeduplicator* deduplicator, 532 StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs,
531 InstructionOperandVector* inputs, 533 FrameStateInputKind kind, Zone* zone) {
532 FrameStateInputKind kind, Zone* zone) {
533 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode()); 534 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
534 535
535 size_t entries = 0; 536 size_t entries = 0;
536 size_t initial_size = inputs->size(); 537 size_t initial_size = inputs->size();
537 USE(initial_size); // initial_size is only used for debug. 538 USE(initial_size); // initial_size is only used for debug.
538 539
539 if (descriptor->outer_state()) { 540 if (descriptor->outer_state()) {
540 entries += AddInputsToFrameStateDescriptor( 541 entries += AddInputsToFrameStateDescriptor(
541 descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput), 542 descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput),
542 g, deduplicator, inputs, kind, zone); 543 g, deduplicator, inputs, kind, zone);
543 } 544 }
544 545
545 Node* parameters = state->InputAt(kFrameStateParametersInput); 546 Node* parameters = state->InputAt(kFrameStateParametersInput);
546 Node* locals = state->InputAt(kFrameStateLocalsInput); 547 Node* locals = state->InputAt(kFrameStateLocalsInput);
547 Node* stack = state->InputAt(kFrameStateStackInput); 548 Node* stack = state->InputAt(kFrameStateStackInput);
548 Node* context = state->InputAt(kFrameStateContextInput); 549 Node* context = state->InputAt(kFrameStateContextInput);
549 Node* function = state->InputAt(kFrameStateFunctionInput); 550 Node* function = state->InputAt(kFrameStateFunctionInput);
550 551
551 DCHECK_EQ(descriptor->parameters_count(), 552 DCHECK_EQ(descriptor->parameters_count(),
552 StateValuesAccess(parameters).size()); 553 StateValuesAccess(parameters).size());
553 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); 554 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
554 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); 555 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
555 556
556 StateValueDescriptor* values_descriptor = 557 StateValueList* values_descriptor = descriptor->GetStateValueDescriptors();
557 descriptor->GetStateValueDescriptor();
558 entries += AddOperandToStateValueDescriptor( 558 entries += AddOperandToStateValueDescriptor(
559 values_descriptor, inputs, g, deduplicator, function, 559 values_descriptor, inputs, g, deduplicator, function,
560 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone); 560 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
561 for (StateValuesAccess::TypedNode input_node : 561 for (StateValuesAccess::TypedNode input_node :
562 StateValuesAccess(parameters)) { 562 StateValuesAccess(parameters)) {
563 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 563 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
564 deduplicator, input_node.node, 564 deduplicator, input_node.node,
565 input_node.type, kind, zone); 565 input_node.type, kind, zone);
566 } 566 }
567 if (descriptor->HasContext()) { 567 if (descriptor->HasContext()) {
568 entries += AddOperandToStateValueDescriptor( 568 entries += AddOperandToStateValueDescriptor(
569 values_descriptor, inputs, g, deduplicator, context, 569 values_descriptor, inputs, g, deduplicator, context,
570 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone); 570 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
571 } 571 }
572 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) { 572 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
573 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 573 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
574 deduplicator, input_node.node, 574 deduplicator, input_node.node,
575 input_node.type, kind, zone); 575 input_node.type, kind, zone);
576 } 576 }
577 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) { 577 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
578 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 578 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
579 deduplicator, input_node.node, 579 deduplicator, input_node.node,
580 input_node.type, kind, zone); 580 input_node.type, kind, zone);
581 } 581 }
582 DCHECK_EQ(initial_size + entries, inputs->size()); 582 DCHECK_EQ(initial_size + entries, inputs->size());
583 return entries; 583 return entries;
584 } 584 }
585 585
586 } // namespace
587
588 586
589 // An internal helper class for generating the operands to calls. 587 // An internal helper class for generating the operands to calls.
590 // TODO(bmeurer): Get rid of the CallBuffer business and make 588 // TODO(bmeurer): Get rid of the CallBuffer business and make
591 // InstructionSelector::VisitCall platform independent instead. 589 // InstructionSelector::VisitCall platform independent instead.
592 struct CallBuffer { 590 struct CallBuffer {
593 CallBuffer(Zone* zone, const CallDescriptor* descriptor, 591 CallBuffer(Zone* zone, const CallDescriptor* descriptor,
594 FrameStateDescriptor* frame_state) 592 FrameStateDescriptor* frame_state)
595 : descriptor(descriptor), 593 : descriptor(descriptor),
596 frame_state_descriptor(frame_state), 594 frame_state_descriptor(frame_state),
597 output_nodes(zone), 595 output_nodes(zone),
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 return new (instruction_zone()) FrameStateDescriptor( 2110 return new (instruction_zone()) FrameStateDescriptor(
2113 instruction_zone(), state_info.type(), state_info.bailout_id(), 2111 instruction_zone(), state_info.type(), state_info.bailout_id(),
2114 state_info.state_combine(), parameters, locals, stack, 2112 state_info.state_combine(), parameters, locals, stack,
2115 state_info.shared_info(), outer_state); 2113 state_info.shared_info(), outer_state);
2116 } 2114 }
2117 2115
2118 2116
2119 } // namespace compiler 2117 } // namespace compiler
2120 } // namespace internal 2118 } // namespace internal
2121 } // namespace v8 2119 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | test/unittests/compiler/instruction-selector-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698