static void insert_bb (struct occurrence *new_occ, basic_block idom, struct occurrence **p_head) { struct occurrence *occ, **p_occ; for (p_occ = p_head; (occ = *p_occ) != NULL; ) { basic_block bb = new_occ->bb, occ_bb = occ->bb; basic_block dom = nearest_common_dominator (CDI_DOMINATORS, occ_bb, bb); if (dom == bb) { /* BB dominates OCC_BB. OCC becomes NEW_OCC's child: remove OCC from its list. */ *p_occ = occ->next; occ->next = new_occ->children; new_occ->children = occ; /* Try the next block (it may as well be dominated by BB). */ } else if (dom == occ_bb) { /* OCC_BB dominates BB. Tail recurse to look deeper. */ insert_bb (new_occ, dom, &occ->children); return; } else if (dom != idom) { gcc_assert (!dom->aux); /* There is a dominator between IDOM and BB, add it and make two children out of NEW_OCC and OCC. First, remove OCC from its list. */ *p_occ = occ->next; new_occ->next = occ; occ->next = NULL; /* None of the previous blocks has DOM as a dominator: if we tail recursed, we would reexamine them uselessly. Just switch BB with DOM, and go on looking for blocks dominated by DOM. */ new_occ = occ_new (dom, new_occ); } else { /* Nothing special, go on with the next element. */ p_occ = &occ->next; } } /* No place was found as a child of IDOM. Make BB a sibling of IDOM. */ new_occ->next = *p_head; *p_head = new_occ; }
else { useblock = gimple_bb (usestmt); } /* Short circuit. Nothing dominates the entry block. */ if (useblock == ENTRY_BLOCK_PTR_FOR_FN (cfun)) { BITMAP_FREE (blocks); return NULL; } bitmap_set_bit (blocks, useblock->index); } commondom = BASIC_BLOCK_FOR_FN (cfun, bitmap_first_set_bit (blocks)); EXECUTE_IF_SET_IN_BITMAP (blocks, 0, j, bi) commondom = nearest_common_dominator (CDI_DOMINATORS, commondom, BASIC_BLOCK_FOR_FN (cfun, j)); BITMAP_FREE (blocks); return commondom; } /* Given EARLY_BB and LATE_BB, two blocks in a path through the dominator tree, return the best basic block between them (inclusive) to place statements. We want the most control dependent block in the shallowest loop nest. If the resulting block is in a shallower loop nest, then use it. Else only use the resulting block if it has significantly lower execution frequency than EARLY_BB to avoid gratutious statement movement. We consider statements with VOPS more desirable to move.