From 2aa17c6e62bc0ff9758408d639d467cda438d1bf Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Fri, 31 Jan 2014 12:03:32 +0000 Subject: [PATCH] Load elimination fix: load should not be replaced with another load if the former is not dominated by the latter. R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/151333003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18985 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-load-elimination.cc | 5 ++++- src/hydrogen.cc | 6 ++++++ src/hydrogen.h | 1 + test/mjsunit/compiler/load-elimination.js | 21 +++++++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc index ea12df8..634d75d 100644 --- a/src/hydrogen-load-elimination.cc +++ b/src/hydrogen-load-elimination.cc @@ -203,9 +203,12 @@ class HLoadEliminationTable : public ZoneObject { // Load is not redundant. Fill out a new entry. approx->last_value_ = instr; return instr; - } else { + } else if (approx->last_value_->block()->EqualToOrDominates( + instr->block())) { // Eliminate the load. Reuse previously stored value or load instruction. return approx->last_value_; + } else { + return instr; } } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 986f4ee..a4c0df2 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -302,6 +302,12 @@ bool HBasicBlock::Dominates(HBasicBlock* other) const { } +bool HBasicBlock::EqualToOrDominates(HBasicBlock* other) const { + if (this == other) return true; + return Dominates(other); +} + + int HBasicBlock::LoopNestingDepth() const { const HBasicBlock* current = this; int result = (current->IsLoopHeader()) ? 1 : 0; diff --git a/src/hydrogen.h b/src/hydrogen.h index 74b05ee..a7fc0fc 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -112,6 +112,7 @@ class HBasicBlock V8_FINAL : public ZoneObject { void RemovePhi(HPhi* phi); void AddInstruction(HInstruction* instr, int position); bool Dominates(HBasicBlock* other) const; + bool EqualToOrDominates(HBasicBlock* other) const; int LoopNestingDepth() const; void SetInitialEnvironment(HEnvironment* env); diff --git a/test/mjsunit/compiler/load-elimination.js b/test/mjsunit/compiler/load-elimination.js index e6a8245..9bf8564 100644 --- a/test/mjsunit/compiler/load-elimination.js +++ b/test/mjsunit/compiler/load-elimination.js @@ -43,6 +43,26 @@ function test_load() { return a.x + a.x + a.x + a.x; } + +function test_load_from_different_contexts() { + var r = 1; + this.f = function() { + var fr = r; + this.g = function(flag) { + var gr; + if (flag) { + gr = r; + } else { + gr = r; + } + return gr + r + fr; + }; + }; + this.f(); + return this.g(true); +} + + function test_store_load() { var a = new B(1, 2); a.x = 4; @@ -128,6 +148,7 @@ function test(x, f) { } test(4, test_load); +test(3, new test_load_from_different_contexts().g); test(22, test_store_load); test(8, test_nonaliasing_store1); test(5, test_transitioning_store1); -- 2.7.4