Commit 4f976328 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Eliminate a few redundant bounds checks.

Usually loops run from 0 to some array length l, which means the
induction variable i will probably have type Unsigned32, just like
the length l. The CheckBounds operation lowers to an Uint32LessThan
comparison, so if we also lower the user level i < l comparison to
Uint32LessThan (whenever possible), we get some bounds check elimination
for free (via value numbering plus branch condition elimination).

This merges the branch condition elimination phase with the late
optimization phase to make this magic happen.

R=jarin@chromium.org
BUG=v8:4930,v8:5141

Review-Url: https://codereview.chromium.org/2135123002
Cr-Commit-Position: refs/heads/master@{#37629}
parent 7dbc2239
......@@ -92,8 +92,7 @@ Reduction BranchElimination::ReduceDeoptimizeConditional(Node* node) {
// yet because we will have to recompute anyway once we compute the
// predecessor.
if (conditions == nullptr) {
DCHECK_NULL(node_conditions_.Get(node));
return NoChange();
return UpdateConditions(node, conditions);
}
Maybe<bool> condition_value = conditions->LookupCondition(condition);
if (condition_value.IsJust()) {
......@@ -123,8 +122,7 @@ Reduction BranchElimination::ReduceIf(Node* node, bool is_true_branch) {
// yet because we will have to recompute anyway once we compute the
// predecessor.
if (from_branch == nullptr) {
DCHECK(node_conditions_.Get(node) == nullptr);
return NoChange();
return UpdateConditions(node, nullptr);
}
Node* condition = branch->InputAt(0);
return UpdateConditions(
......@@ -145,8 +143,7 @@ Reduction BranchElimination::ReduceMerge(Node* node) {
// input.
for (int i = 0; i < node->InputCount(); i++) {
if (node_conditions_.Get(node->InputAt(i)) == nullptr) {
DCHECK(node_conditions_.Get(node) == nullptr);
return NoChange();
return UpdateConditions(node, nullptr);
}
}
......@@ -209,7 +206,8 @@ Reduction BranchElimination::UpdateConditions(
// Only signal that the node has Changed if the condition information has
// changed.
if (conditions != original) {
if (original == nullptr || *conditions != *original) {
if (conditions == nullptr || original == nullptr ||
*conditions != *original) {
node_conditions_.Set(node, conditions);
return Changed(node);
}
......
......@@ -919,22 +919,6 @@ struct TypedLoweringPhase {
};
struct BranchEliminationPhase {
static const char* phase_name() { return "branch condition elimination"; }
void Run(PipelineData* data, Zone* temp_zone) {
JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
BranchElimination branch_condition_elimination(&graph_reducer,
data->jsgraph(), temp_zone);
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
data->common());
AddReducer(data, &graph_reducer, &branch_condition_elimination);
AddReducer(data, &graph_reducer, &dead_code_elimination);
graph_reducer.ReduceGraph();
}
};
struct EscapeAnalysisPhase {
static const char* phase_name() { return "escape analysis"; }
......@@ -1077,6 +1061,8 @@ struct LateOptimizationPhase {
void Run(PipelineData* data, Zone* temp_zone) {
JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
BranchElimination branch_condition_elimination(&graph_reducer,
data->jsgraph(), temp_zone);
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
data->common());
ValueNumberingReducer value_numbering(temp_zone);
......@@ -1086,6 +1072,7 @@ struct LateOptimizationPhase {
SelectLowering select_lowering(data->jsgraph()->graph(),
data->jsgraph()->common());
TailCallOptimization tco(data->common(), data->graph());
AddReducer(data, &graph_reducer, &branch_condition_elimination);
AddReducer(data, &graph_reducer, &dead_code_elimination);
AddReducer(data, &graph_reducer, &value_numbering);
AddReducer(data, &graph_reducer, &machine_reducer);
......@@ -1511,9 +1498,6 @@ bool PipelineImpl::OptimizeGraph(Linkage* linkage) {
RunPrintAndVerify("Store-store elimination", true);
}
Run<BranchEliminationPhase>();
RunPrintAndVerify("Branch conditions eliminated", true);
// Optimize control flow.
if (FLAG_turbo_cf_optimization) {
Run<ControlFlowOptimizationPhase>();
......
......@@ -1270,16 +1270,16 @@ class RepresentationSelector {
case IrOpcode::kNumberLessThan:
case IrOpcode::kNumberLessThanOrEqual: {
// Number comparisons reduce to integer comparisons for integer inputs.
if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
// => signed Int32Cmp
VisitInt32Cmp(node);
if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
} else if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
// => unsigned Int32Cmp
VisitUint32Cmp(node);
if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
} else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
// => signed Int32Cmp
VisitInt32Cmp(node);
if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
} else {
// => Float64Cmp
VisitFloat64Cmp(node);
......@@ -1296,18 +1296,18 @@ class RepresentationSelector {
case IrOpcode::kSpeculativeNumberLessThanOrEqual:
case IrOpcode::kSpeculativeNumberEqual: {
// Number comparisons reduce to integer comparisons for integer inputs.
if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
// => signed Int32Cmp
VisitInt32Cmp(node);
if (lower()) ChangeToPureOp(node, Int32Op(node));
return;
} else if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
// => unsigned Int32Cmp
VisitUint32Cmp(node);
if (lower()) ChangeToPureOp(node, Uint32Op(node));
return;
} else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
// => signed Int32Cmp
VisitInt32Cmp(node);
if (lower()) ChangeToPureOp(node, Int32Op(node));
return;
}
// Try to use type feedback.
CompareOperationHints::Hint hint = CompareOperationHintOf(node->op());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment