Make bounds check elimination iterative instead of recursive.

BUG=289706
R=danno@chromium.org

Review URL: https://codereview.chromium.org/23444083

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16842 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
titzer@chromium.org 2013-09-19 16:26:14 +00:00
parent ad51bf945e
commit 873f02db91
2 changed files with 51 additions and 6 deletions

View File

@ -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();
}
}

View File

@ -60,6 +60,8 @@ class HBoundsCheckEliminationPhase : public HPhase {
private:
void EliminateRedundantBoundsChecks(HBasicBlock* bb);
BoundsCheckBbData* PreProcessBlock(HBasicBlock* bb);
void PostProcessBlock(HBasicBlock* bb, BoundsCheckBbData* data);
BoundsCheckTable table_;