// 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;
}
}
}
+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;
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);
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;
}
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);