| Index: src/hydrogen-bce.cc
|
| diff --git a/src/hydrogen-bce.cc b/src/hydrogen-bce.cc
|
| index 7c81ec145cbd4e73dc289259c369ed234395a4d5..869db54a2f496576bd01c3eb9d0cdb6f2d721133 100644
|
| --- a/src/hydrogen-bce.cc
|
| +++ b/src/hydrogen-bce.cc
|
| @@ -318,12 +318,54 @@ void BoundsCheckTable::Delete(BoundsCheckKey* key) {
|
| }
|
|
|
|
|
| +class HBoundsCheckEliminationState {
|
| + public:
|
| + HBasicBlock* block_;
|
| + BoundsCheckBbData* bb_data_list_;
|
| + int index_;
|
| +};
|
| +
|
| +
|
| // Eliminates checks in bb and recursively in the dominated blocks.
|
| // Also replace the results of check instructions with the original value, if
|
| // the result is used. This is safe now, since we don't do code motion after
|
| // this point. It enables better register allocation since the value produced
|
| // by check instructions is really a copy of the original value.
|
| void HBoundsCheckEliminationPhase::EliminateRedundantBoundsChecks(
|
| + HBasicBlock* entry) {
|
| + // Allocate the stack.
|
| + HBoundsCheckEliminationState* stack =
|
| + zone()->NewArray<HBoundsCheckEliminationState>(graph()->blocks()->length());
|
| +
|
| + // Explicitly push the entry block.
|
| + stack[0].block_ = entry;
|
| + stack[0].bb_data_list_ = PreProcessBlock(entry);
|
| + stack[0].index_ = 0;
|
| + int stack_depth = 1;
|
| +
|
| + // Implement depth-first traversal with a stack.
|
| + while (stack_depth > 0) {
|
| + int current = stack_depth - 1;
|
| + HBoundsCheckEliminationState* state = &stack[current];
|
| + const ZoneList<HBasicBlock*>* children = state->block_->dominated_blocks();
|
| +
|
| + if (state->index_ < children->length()) {
|
| + // Recursively visit children blocks.
|
| + HBasicBlock* child = children->at(state->index_++);
|
| + int next = stack_depth++;
|
| + stack[next].block_ = child;
|
| + stack[next].bb_data_list_ = PreProcessBlock(child);
|
| + stack[next].index_ = 0;
|
| + } else {
|
| + // Finished with all children; post process the block.
|
| + PostProcessBlock(state->block_, state->bb_data_list_);
|
| + stack_depth--;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +BoundsCheckBbData* HBoundsCheckEliminationPhase::PreProcessBlock(
|
| HBasicBlock* bb) {
|
| BoundsCheckBbData* bb_data_list = NULL;
|
|
|
| @@ -375,19 +417,20 @@ void HBoundsCheckEliminationPhase::EliminateRedundantBoundsChecks(
|
| }
|
| }
|
|
|
| - for (int i = 0; i < bb->dominated_blocks()->length(); ++i) {
|
| - EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i));
|
| - }
|
| + return bb_data_list;
|
| +}
|
| +
|
|
|
| - for (BoundsCheckBbData* data = bb_data_list;
|
| - data != NULL;
|
| - data = data->NextInBasicBlock()) {
|
| +void HBoundsCheckEliminationPhase::PostProcessBlock(
|
| + HBasicBlock* block, BoundsCheckBbData* data) {
|
| + while (data != NULL) {
|
| data->RemoveZeroOperations();
|
| if (data->FatherInDominatorTree()) {
|
| table_.Insert(data->Key(), data->FatherInDominatorTree(), zone());
|
| } else {
|
| table_.Delete(data->Key());
|
| }
|
| + data = data->NextInBasicBlock();
|
| }
|
| }
|
|
|
|
|