| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index bb56296a22def95346c2a2379d7cd3811300c7bb..049efc23506edf248086b9fa47ad7a095a26a06e 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -3295,10 +3295,11 @@ void HInferRepresentation::Analyze() {
|
|
|
|
|
| void HGraph::MergeRemovableSimulates() {
|
| + ZoneList<HSimulate*> mergelist(2, zone());
|
| for (int i = 0; i < blocks()->length(); ++i) {
|
| HBasicBlock* block = blocks()->at(i);
|
| // Always reset the folding candidate at the start of a block.
|
| - HSimulate* folding_candidate = NULL;
|
| + mergelist.Clear();
|
| // Nasty heuristic: Never remove the first simulate in a block. This
|
| // just so happens to have a beneficial effect on register allocation.
|
| bool first = true;
|
| @@ -3309,33 +3310,37 @@ void HGraph::MergeRemovableSimulates() {
|
| // in the outer environment.
|
| // (Before each HEnterInlined, there is a non-foldable HSimulate
|
| // anyway, so we get the barrier in the other direction for free.)
|
| - if (folding_candidate != NULL) {
|
| - folding_candidate->DeleteAndReplaceWith(NULL);
|
| + if (!mergelist.is_empty()) {
|
| + // Merge the simulates accumulated so far.
|
| + HSimulate* last = mergelist.RemoveLast();
|
| + last->MergeWith(&mergelist);
|
| }
|
| - folding_candidate = NULL;
|
| continue;
|
| }
|
| - // If we have an HSimulate and a candidate, perform the folding.
|
| + // Skip the non-simulates and the first simulate.
|
| if (!current->IsSimulate()) continue;
|
| if (first) {
|
| first = false;
|
| continue;
|
| }
|
| HSimulate* current_simulate = HSimulate::cast(current);
|
| - if (folding_candidate != NULL) {
|
| - folding_candidate->MergeInto(current_simulate);
|
| - folding_candidate->DeleteAndReplaceWith(NULL);
|
| - folding_candidate = NULL;
|
| - }
|
| - // Check if the current simulate is a candidate for folding.
|
| - if (current_simulate->previous()->HasObservableSideEffects() &&
|
| - !current_simulate->next()->IsSimulate()) {
|
| - continue;
|
| - }
|
| - if (!current_simulate->is_candidate_for_removal()) {
|
| + if ((current_simulate->previous()->HasObservableSideEffects() &&
|
| + !current_simulate->next()->IsSimulate()) ||
|
| + !current_simulate->is_candidate_for_removal()) {
|
| + // This simulate is not suitable for folding.
|
| + // Fold the ones accumulated so far.
|
| + current_simulate->MergeWith(&mergelist);
|
| continue;
|
| + } else {
|
| + // Accumulate this simulate for folding later on.
|
| + mergelist.Add(current_simulate, zone());
|
| }
|
| - folding_candidate = current_simulate;
|
| + }
|
| +
|
| + if (!mergelist.is_empty()) {
|
| + // Merge the accumulated simulates at the end of the block.
|
| + HSimulate* last = mergelist.RemoveLast();
|
| + last->MergeWith(&mergelist);
|
| }
|
| }
|
| }
|
|
|