Commit b5a43f48 authored by mmassi@chromium.org's avatar mmassi@chromium.org

New array bounds check elimination pass (focused on induction variables and bitwise operations).

R=titzer@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15866 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a418b36b
......@@ -4243,6 +4243,18 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
if (FLAG_debug_code && check->hydrogen()->skip_check()) {
Label done;
__ b(NegateCondition(cc), &done);
__ stop("eliminated bounds check failed");
__ bind(&done);
} else {
DeoptimizeIf(cc, check->environment());
}
}
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->hydrogen()->skip_check()) return;
......@@ -4258,7 +4270,8 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
} else {
__ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
}
DeoptimizeIf(hs, instr->environment());
Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
ApplyCheckIf(condition, instr);
}
......
......@@ -284,6 +284,7 @@ class LCodeGen BASE_EMBEDDED {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
void ApplyCheckIf(Condition cc, LBoundsCheck* check);
void AddToTranslation(Translation* translation,
LOperand* op,
......
......@@ -266,6 +266,8 @@ DEFINE_bool(use_osr, true, "use on-stack replacement")
DEFINE_bool(idefs, false, "use informative definitions")
DEFINE_bool(array_bounds_checks_elimination, true,
"perform array bounds checks elimination")
DEFINE_bool(array_bounds_checks_hoisting, false,
"perform array bounds checks hoisting")
DEFINE_bool(array_index_dehoisting, true,
"perform array index dehoisting")
DEFINE_bool(analyze_environment_liveness, true,
......
......@@ -189,6 +189,8 @@ class BoundsCheckBbData: public ZoneObject {
}
if (!keep_new_check) {
new_check->block()->graph()->isolate()->counters()->
bounds_checks_eliminated()->Increment();
new_check->DeleteAndReplaceWith(new_check->ActualValue());
}
......@@ -347,6 +349,8 @@ void HBoundsCheckEliminationPhase::EliminateRedundantBoundsChecks(
NULL);
*data_p = bb_data_list;
} else if (data->OffsetIsCovered(offset)) {
bb->graph()->isolate()->counters()->
bounds_checks_eliminated()->Increment();
check->DeleteAndReplaceWith(check->ActualValue());
} else if (data->BasicBlock() != bb ||
!data->CoverCheck(check, offset)) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -34,6 +34,7 @@
#include "full-codegen.h"
#include "hashmap.h"
#include "hydrogen-bce.h"
#include "hydrogen-bch.h"
#include "hydrogen-canonicalize.h"
#include "hydrogen-dce.h"
#include "hydrogen-dehoist.h"
......@@ -3034,6 +3035,9 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) {
Run<HBoundsCheckEliminationPhase>();
}
if (FLAG_array_bounds_checks_hoisting && !FLAG_idefs) {
Run<HBoundsCheckHoistingPhase>();
}
if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
......
......@@ -69,6 +69,11 @@ class HBasicBlock: public ZoneObject {
void set_last(HInstruction* instr) { last_ = instr; }
HControlInstruction* end() const { return end_; }
HLoopInformation* loop_information() const { return loop_information_; }
HLoopInformation* current_loop() const {
return IsLoopHeader() ? loop_information()
: (parent_loop_header() != NULL
? parent_loop_header()->loop_information() : NULL);
}
const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
bool HasPredecessor() const { return predecessors_.length() > 0; }
const ZoneList<HBasicBlock*>* dominated_blocks() const {
......@@ -271,6 +276,20 @@ class HLoopInformation: public ZoneObject {
stack_check_ = stack_check;
}
bool IsNestedInThisLoop(HLoopInformation* other) {
while (other != NULL) {
if (other == this) {
return true;
}
other = other->parent_loop();
}
return false;
}
HLoopInformation* parent_loop() {
HBasicBlock* parent_header = loop_header()->parent_loop_header();
return parent_header != NULL ? parent_header->loop_information() : NULL;
}
private:
void AddBlock(HBasicBlock* block);
......@@ -282,6 +301,7 @@ class HLoopInformation: public ZoneObject {
class BoundsCheckTable;
class InductionVariableBlocksTable;
class HGraph: public ZoneObject {
public:
explicit HGraph(CompilationInfo* info);
......@@ -448,6 +468,7 @@ class HGraph: public ZoneObject {
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
void SetupInformativeDefinitionsInBlock(HBasicBlock* block);
void SetupInformativeDefinitionsRecursively(HBasicBlock* block);
void EliminateRedundantBoundsChecksUsingInductionVariables();
Isolate* isolate_;
int next_block_id_;
......
......@@ -4425,8 +4425,20 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
if (FLAG_debug_code && check->hydrogen()->skip_check()) {
Label done;
__ j(NegateCondition(cc), &done, Label::kNear);
__ int3();
__ bind(&done);
} else {
DeoptimizeIf(cc, check->environment());
}
}
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->hydrogen()->skip_check()) return;
if (instr->hydrogen()->skip_check() && !FLAG_debug_code) return;
if (instr->index()->IsConstantOperand()) {
int constant_index =
......@@ -4437,10 +4449,14 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
} else {
__ cmp(ToOperand(instr->length()), Immediate(constant_index));
}
DeoptimizeIf(below_equal, instr->environment());
Condition condition =
instr->hydrogen()->allow_equality() ? below : below_equal;
ApplyCheckIf(condition, instr);
} else {
__ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
DeoptimizeIf(above_equal, instr->environment());
Condition condition =
instr->hydrogen()->allow_equality() ? above : above_equal;
ApplyCheckIf(condition, instr);
}
}
......
......@@ -283,6 +283,7 @@ class LCodeGen BASE_EMBEDDED {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
void ApplyCheckIf(Condition cc, LBoundsCheck* check);
void AddToTranslation(Translation* translation,
LOperand* op,
......
......@@ -4166,6 +4166,7 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->hydrogen()->skip_check()) return;
Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
if (instr->index()->IsConstantOperand()) {
int constant_index =
ToInteger32(LConstantOperand::cast(instr->index()));
......@@ -4174,12 +4175,12 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
} else {
__ li(at, Operand(constant_index));
}
DeoptimizeIf(hs,
DeoptimizeIf(condition,
instr->environment(),
at,
Operand(ToRegister(instr->length())));
} else {
DeoptimizeIf(hs,
DeoptimizeIf(condition,
instr->environment(),
ToRegister(instr->index()),
Operand(ToRegister(instr->length())));
......
......@@ -225,8 +225,17 @@ class Token {
return op == EQ || op == EQ_STRICT;
}
static bool IsInequalityOp(Value op) {
return op == NE || op == NE_STRICT;
}
static bool IsArithmeticCompareOp(Value op) {
return IsOrderedRelationalCompareOp(op) ||
IsEqualityOp(op) || IsInequalityOp(op);
}
static Value NegateCompareOp(Value op) {
ASSERT(IsCompareOp(op));
ASSERT(IsArithmeticCompareOp(op));
switch (op) {
case EQ: return NE;
case NE: return EQ;
......@@ -243,7 +252,7 @@ class Token {
}
static Value ReverseCompareOp(Value op) {
ASSERT(IsCompareOp(op));
ASSERT(IsArithmeticCompareOp(op));
switch (op) {
case EQ: return EQ;
case NE: return NE;
......
......@@ -238,6 +238,8 @@ namespace internal {
SC(transcendental_cache_miss, V8.TranscendentalCacheMiss) \
SC(stack_interrupts, V8.StackInterrupts) \
SC(runtime_profiler_ticks, V8.RuntimeProfilerTicks) \
SC(bounds_checks_eliminated, V8.BoundsChecksEliminated) \
SC(bounds_checks_hoisted, V8.BoundsChecksHoisted) \
SC(soft_deopts_requested, V8.SoftDeoptsRequested) \
SC(soft_deopts_inserted, V8.SoftDeoptsInserted) \
SC(soft_deopts_executed, V8.SoftDeoptsExecuted) \
......
......@@ -3995,6 +3995,18 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
if (FLAG_debug_code && check->hydrogen()->skip_check()) {
Label done;
__ j(NegateCondition(cc), &done, Label::kNear);
__ int3();
__ bind(&done);
} else {
DeoptimizeIf(cc, check->environment());
}
}
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->hydrogen()->skip_check()) return;
......@@ -4032,7 +4044,9 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
__ cmpq(length, ToRegister(instr->index()));
}
}
DeoptimizeIf(below_equal, instr->environment());
Condition condition =
instr->hydrogen()->allow_equality() ? below : below_equal;
ApplyCheckIf(condition, instr);
}
......
......@@ -245,6 +245,7 @@ class LCodeGen BASE_EMBEDDED {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
void ApplyCheckIf(Condition cc, LBoundsCheck* check);
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
......
......@@ -337,6 +337,8 @@
'../../src/heap.h',
'../../src/hydrogen-bce.cc',
'../../src/hydrogen-bce.h',
'../../src/hydrogen-bch.cc',
'../../src/hydrogen-bch.h',
'../../src/hydrogen-canonicalize.cc',
'../../src/hydrogen-canonicalize.h',
'../../src/hydrogen-dce.cc',
......
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