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:
parent
ad51bf945e
commit
873f02db91
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user