1550 {
1551 if (flow_graph()->
function().ProhibitsInstructionHoisting()) {
1552
1553 return;
1554 }
1555
1556
1558 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers =
1560 loop_hierarchy.ComputeInduction();
1561
1562 ZoneGrowableArray<BitVector*>* loop_invariant_loads =
1564
1565
1566 for (intptr_t
i = 0;
i < loop_headers.length(); ++
i) {
1567 BlockEntryInstr*
header = loop_headers[
i];
1568
1569
1570 BlockEntryInstr* pre_header =
header->ImmediateDominator();
1571 if (pre_header == nullptr) {
1572 continue;
1573 }
1574
1575
1576
1577 bool seen_visible_effect = false;
1578
1579
1580 LoopInfo* loop =
header->loop_info();
1581 for (BitVector::Iterator loop_it(loop->blocks()); !loop_it.Done();
1582 loop_it.Advance()) {
1583 BlockEntryInstr* block = flow_graph()->
preorder()[loop_it.Current()];
1584
1585
1586
1587
1588 if (!seen_visible_effect && !loop->IsAlwaysTaken(block)) {
1589 seen_visible_effect = true;
1590 }
1591
1592 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
1593 Instruction* current = it.Current();
1594
1595
1596
1597
1598 if (LoadStaticFieldInstr*
load = current->AsLoadStaticField()) {
1599 if (
load->AllowsCSE()) {
1600 seen_visible_effect = true;
1601 continue;
1602 }
1603 }
1604
1605
1606
1607
1608 bool is_loop_invariant = false;
1609 if ((current->AllowsCSE() ||
1611 (!seen_visible_effect || !current->MayHaveVisibleEffect())) {
1612 is_loop_invariant = true;
1613 for (intptr_t
i = 0;
i < current->InputCount(); ++
i) {
1614 Definition* input_def = current->InputAt(
i)->definition();
1615 if (!input_def->GetBlock()->Dominates(pre_header)) {
1616 is_loop_invariant = false;
1617 break;
1618 }
1619 }
1620 }
1621
1622
1623
1624
1625 if (is_loop_invariant) {
1626 Hoist(&it, pre_header, current);
1627 } else if (!seen_visible_effect && current->MayHaveVisibleEffect()) {
1628 seen_visible_effect = true;
1629 }
1630 }
1631 }
1632 }
1633}
const GrowableArray< BlockEntryInstr * > & preorder() const
ZoneGrowableArray< BitVector * > * loop_invariant_loads() const
static bool IsLoopInvariantLoad(ZoneGrowableArray< BitVector * > *sets, intptr_t loop_header_index, Instruction *instr)