| Index: src/interpreter/bytecode-register-optimizer.cc
|
| diff --git a/src/interpreter/bytecode-register-optimizer.cc b/src/interpreter/bytecode-register-optimizer.cc
|
| index 223dbe2c1073e82053ebb677d6f05be7bf371539..1903247f157bed7bf73281e3fee1237e1a34a89f 100644
|
| --- a/src/interpreter/bytecode-register-optimizer.cc
|
| +++ b/src/interpreter/bytecode-register-optimizer.cc
|
| @@ -48,6 +48,9 @@ class BytecodeRegisterOptimizer::RegisterInfo final : public ZoneObject {
|
| // exists.
|
| RegisterInfo* GetEquivalentToMaterialize();
|
|
|
| + // Get an equivalent register. Returns this if none exists.
|
| + RegisterInfo* GetEquivalent();
|
| +
|
| Register register_value() const { return register_; }
|
| bool materialized() const { return materialized_; }
|
| void set_materialized(bool materialized) { materialized_ = materialized; }
|
| @@ -161,6 +164,11 @@ BytecodeRegisterOptimizer::RegisterInfo::GetEquivalentToMaterialize() {
|
| return best_info;
|
| }
|
|
|
| +BytecodeRegisterOptimizer::RegisterInfo*
|
| +BytecodeRegisterOptimizer::RegisterInfo::GetEquivalent() {
|
| + return next_;
|
| +}
|
| +
|
| BytecodeRegisterOptimizer::BytecodeRegisterOptimizer(
|
| Zone* zone, TemporaryRegisterAllocator* register_allocator,
|
| int parameter_count, BytecodePipelineStage* next_stage)
|
| @@ -169,7 +177,7 @@ BytecodeRegisterOptimizer::BytecodeRegisterOptimizer(
|
| register_info_table_(zone),
|
| equivalence_id_(0),
|
| next_stage_(next_stage),
|
| - flushed_(false),
|
| + flush_required_(false),
|
| zone_(zone) {
|
| register_allocator->set_observer(this);
|
|
|
| @@ -209,8 +217,6 @@ Handle<BytecodeArray> BytecodeRegisterOptimizer::ToBytecodeArray(
|
|
|
| // override
|
| void BytecodeRegisterOptimizer::Write(BytecodeNode* node) {
|
| - flushed_ = false;
|
| -
|
| //
|
| // Transfers with observable registers as the destination will be
|
| // immediately materialized so the source position information will
|
| @@ -274,31 +280,29 @@ void BytecodeRegisterOptimizer::BindLabel(const BytecodeLabel& target,
|
| }
|
|
|
| void BytecodeRegisterOptimizer::FlushState() {
|
| - if (flushed_) {
|
| + if (!flush_required_) {
|
| return;
|
| }
|
|
|
| - // Materialize all live registers.
|
| + // Materialize all live registers and break equivalences.
|
| size_t count = register_info_table_.size();
|
| for (size_t i = 0; i < count; ++i) {
|
| RegisterInfo* reg_info = register_info_table_[i];
|
| - if (!reg_info->IsOnlyMemberOfEquivalenceSet() &&
|
| - !reg_info->materialized()) {
|
| - DCHECK(RegisterIsTemporary(reg_info->register_value()) ||
|
| - reg_info->register_value() == accumulator_);
|
| - Materialize(reg_info);
|
| - }
|
| - }
|
| -
|
| - // Break all existing equivalences.
|
| - for (size_t i = 0; i < count; ++i) {
|
| - RegisterInfo* reg_info = register_info_table_[i];
|
| - if (!reg_info->IsOnlyMemberOfEquivalenceSet()) {
|
| - reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true);
|
| + if (reg_info->materialized()) {
|
| + // Walk equivalents of materialized registers, materializing
|
| + // each equivalent register as necessary and placing in their
|
| + // own equivalence set.
|
| + RegisterInfo* equivalent;
|
| + while ((equivalent = reg_info->GetEquivalent()) != reg_info) {
|
| + if (!equivalent->materialized()) {
|
| + OutputRegisterTransfer(reg_info, equivalent);
|
| + }
|
| + equivalent->MoveToNewEquivalenceSet(NextEquivalenceId(), true);
|
| + }
|
| }
|
| }
|
|
|
| - flushed_ = true;
|
| + flush_required_ = false;
|
| }
|
|
|
| void BytecodeRegisterOptimizer::WriteToNextStage(BytecodeNode* node) const {
|
| @@ -376,6 +380,14 @@ void BytecodeRegisterOptimizer::Materialize(RegisterInfo* info) {
|
| }
|
| }
|
|
|
| +void BytecodeRegisterOptimizer::AddToEquivalenceSet(
|
| + RegisterInfo* set_member, RegisterInfo* non_set_member) {
|
| + non_set_member->AddToEquivalenceSetOf(set_member);
|
| + // Flushing is only required when two or more registers are placed
|
| + // in the same equivalence set.
|
| + flush_required_ = true;
|
| +}
|
| +
|
| void BytecodeRegisterOptimizer::RegisterTransfer(
|
| RegisterInfo* input_info, RegisterInfo* output_info,
|
| const BytecodeSourceInfo& source_info) {
|
| @@ -387,7 +399,7 @@ void BytecodeRegisterOptimizer::RegisterTransfer(
|
|
|
| // Add |output_info| to new equivalence set.
|
| if (!output_info->IsInSameEquivalenceSet(input_info)) {
|
| - output_info->AddToEquivalenceSetOf(input_info);
|
| + AddToEquivalenceSet(input_info, output_info);
|
| }
|
|
|
| bool output_is_observable =
|
|
|