29 static const int kNoBlock = -1;
31 HBasicBlock*
block() {
return block_; }
32 void set_block(HBasicBlock* block) { block_ = block; }
39 return &additional_limit_;
48 HLoopInformation* loop = data->phi()->block()->current_loop();
49 is_start_ = (block() == loop->loop_header());
50 is_proper_exit_ = (block() == data->induction_exit_target());
51 is_in_loop_ = loop->IsNestedInThisLoop(block()->current_loop());
58 DCHECK(current_dominated_block_ != kNoBlock);
59 return current_dominated_block_ < block()->dominated_blocks()->length() ?
60 block()->dominated_blocks()->at(current_dominated_block_) :
NULL;
63 current_dominated_block_++;
64 return CurrentDominatedBlock();
69 has_check_(
false), additional_limit_(),
70 current_dominated_block_(kNoBlock) {}
82 HGraph*
graph()
const {
return graph_; }
85 Element*
at(
int index)
const {
return &(elements_.at(index)); }
86 Element*
at(HBasicBlock* block)
const {
return at(block->block_id()); }
89 at(block->block_id())->set_has_check();
97 for (
int i = 0;
i < graph()->blocks()->length();
i++) {
98 at(
i)->InitializeLoop(data);
100 loop_header_ = data->phi()->block()->current_loop()->loop_header();
122 for (
int i = 0;
i < elements_.length();
i++) {
123 at(
i)->ResetCurrentDominatedBlock();
127 HBasicBlock* current = loop_header();
128 while (current !=
NULL) {
131 if (at(current)->has_check() || !at(current)->is_in_loop()) {
136 for (
int i = 0;
i < current->end()->SuccessorCount();
i ++) {
137 Element* successor = at(current->end()->SuccessorAt(
i));
152 return NOT_HOISTABLE;
156 next = at(current)->NextDominatedBlock();
160 while (next ==
NULL) {
161 current = current->dominator();
162 if (current !=
NULL) {
163 next = at(current)->NextDominatedBlock();
174 return unsafe ? OPTIMISTICALLY_HOISTABLE : HOISTABLE;
178 : graph_(graph), loop_header_(
NULL),
179 elements_(graph->blocks()->length(), graph->zone()) {
180 for (
int i = 0;
i < graph->blocks()->length();
i++) {
183 elements_.Add(element, graph->zone());
184 DCHECK(at(
i)->block()->block_id() ==
i);
190 InductionVariableData::InductionVariableCheck* check,
191 InductionVariableData* data) {
192 HValue* length = check->check()->length();
193 check->set_processed();
194 HBasicBlock* header =
195 data->phi()->
block()->current_loop()->loop_header();
196 HBasicBlock* pre_header = header->predecessors()->at(0);
198 if (!data->limit()->IsInteger32Constant()) {
199 HBasicBlock* limit_block = data->limit()->block();
200 if (limit_block != pre_header &&
201 !limit_block->Dominates(pre_header)) {
206 if (!(data->limit()->representation().Equals(
208 data->limit()->IsInteger32Constant())) {
212 if (check->check()->length()->block() != pre_header &&
213 !check->check()->length()->block()->Dominates(pre_header)) {
218 for (InductionVariableData::InductionVariableCheck* current_check = check;
219 current_check !=
NULL;
220 current_check = current_check->next()) {
221 if (current_check->check()->length() != length)
continue;
223 AddCheckAt(current_check->check()->block());
224 current_check->set_processed();
229 if (hoistability == NOT_HOISTABLE ||
230 (hoistability == OPTIMISTICALLY_HOISTABLE &&
231 !graph()->use_optimistic_licm())) {
238 bool has_upper_constant_limit =
true;
240 check !=
NULL && check->HasUpperLimit() ? check->upper_limit() : 0;
241 for (InductionVariableData::InductionVariableCheck* current_check = check;
242 current_check !=
NULL;
243 current_check = current_check->next()) {
244 has_upper_constant_limit =
245 has_upper_constant_limit &&
246 check->HasUpperLimit() &&
247 check->upper_limit() == upper_constant_limit;
248 counters()->bounds_checks_eliminated()->Increment();
249 current_check->check()->set_skip_check();
253 Zone* zone = graph()->zone();
254 HValue* context = graph()->GetInvalidContext();
255 HValue* limit = data->limit();
256 if (has_upper_constant_limit) {
257 HConstant* new_limit = HConstant::New(zone, context,
258 upper_constant_limit);
259 new_limit->InsertBefore(pre_header->end());
265 limit->
block() != pre_header &&
266 !limit->
block()->Dominates(pre_header)) {
267 HConstant* new_limit = HConstant::New(zone, context,
269 new_limit->InsertBefore(pre_header->end());
274 HBoundsCheck* hoisted_check = HBoundsCheck::New(
275 zone, context, limit, check->check()->length());
276 hoisted_check->InsertBefore(pre_header->end());
277 hoisted_check->set_allow_equality(
true);
278 counters()->bounds_checks_hoisted()->Increment();
282 bool additional_limit =
false;
284 for (
int i = 0;
i < bb->phis()->length();
i++) {
285 HPhi* phi = bb->phis()->at(
i);
286 phi->DetectInductionVariable();
289 additional_limit = InductionVariableData::ComputeInductionVariableLimit(
290 bb, at(bb)->additional_limit());
292 if (additional_limit) {
293 at(bb)->additional_limit()->updated_variable->
294 UpdateAdditionalLimit(at(bb)->additional_limit());
298 if (!
i->IsBoundsCheck())
continue;
299 HBoundsCheck* check = HBoundsCheck::cast(
i);
300 InductionVariableData::BitwiseDecompositionResult decomposition;
301 InductionVariableData::DecomposeBitwise(check->index(), &decomposition);
302 if (!decomposition.base->IsPhi())
continue;
303 HPhi* phi = HPhi::cast(decomposition.base);
305 if (!phi->IsInductionVariable())
continue;
306 InductionVariableData* data = phi->induction_variable_data();
309 if (data->increment() <= 0)
continue;
310 if (!data->LowerLimitIsNonNegativeConstant())
continue;
313 if (check->length() == data->limit() ||
314 check->length() == data->additional_upper_limit()) {
315 counters()->bounds_checks_eliminated()->Increment();
316 check->set_skip_check();
320 if (!phi->IsLimitedInductionVariable())
continue;
322 int32_t limit = data->ComputeUpperLimit(decomposition.and_mask,
323 decomposition.or_mask);
324 phi->induction_variable_data()->AddCheck(check, limit);
327 for (
int i = 0;
i < bb->dominated_blocks()->length();
i++) {
328 CollectInductionVariableData(bb->dominated_blocks()->at(
i));
331 if (additional_limit) {
332 at(bb->block_id())->additional_limit()->updated_variable->
333 UpdateAdditionalLimit(at(bb->block_id())->additional_limit());
338 for (
int i = 0;
i < bb->phis()->length();
i++) {
339 HPhi* phi = bb->phis()->at(
i);
340 if (!phi->IsLimitedInductionVariable())
continue;
342 InductionVariableData* induction_data = phi->induction_variable_data();
343 InductionVariableData::ChecksRelatedToLength* current_length_group =
344 induction_data->checks();
345 while (current_length_group !=
NULL) {
346 current_length_group->CloseCurrentBlock();
347 InductionVariableData::InductionVariableCheck* current_base_check =
348 current_length_group->checks();
349 InitializeLoop(induction_data);
351 while (current_base_check !=
NULL) {
352 ProcessRelatedChecks(current_base_check, induction_data);
353 while (current_base_check !=
NULL &&
354 current_base_check->processed()) {
355 current_base_check = current_base_check->next();
359 current_length_group = current_length_group->next();
372 InductionVariableBlocksTable table(
graph());
373 table.CollectInductionVariableData(
graph()->entry_block());
374 for (
int i = 0;
i <
graph()->blocks()->length();
i++) {
375 table.EliminateRedundantBoundsChecks(
graph()->blocks()->at(
i));
void ResetCurrentDominatedBlock()
void set_block(HBasicBlock *block)
InductionVariableLimitUpdate additional_limit_
HBasicBlock * NextDominatedBlock()
HBasicBlock * CurrentDominatedBlock()
InductionVariableLimitUpdate * additional_limit()
void InitializeLoop(InductionVariableData *data)
int current_dominated_block_
Counters * counters() const
HBasicBlock * loop_header_
ZoneList< Element > elements_
InductionVariableBlocksTable(HGraph *graph)
Element * at(HBasicBlock *block) const
void AddCheckAt(HBasicBlock *block)
Hoistability CheckHoistability()
@ OPTIMISTICALLY_HOISTABLE
Element * at(int index) const
void InitializeLoop(InductionVariableData *data)
void ProcessRelatedChecks(InductionVariableData::InductionVariableCheck *check, InductionVariableData *data)
HBasicBlock * loop_header() const
void CollectInductionVariableData(HBasicBlock *bb)
void EliminateRedundantBoundsChecks(HBasicBlock *bb)
void HoistRedundantBoundsChecks()
HBasicBlock * block() const
int32_t GetInteger32Constant()
bool IsInteger32Constant()
Representation representation() const
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Debugger support for the V8 JavaScript engine.