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

Unified Diff: src/interpreter/bytecode-register-optimizer.cc

Issue 2033013002: [interpreter] Faster and fewer flushes in register optimizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@oth-0061-tweaks
Patch Set: Rebase Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
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 =
« no previous file with comments | « src/interpreter/bytecode-register-optimizer.h ('k') | test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698