void free_aux_for_blocks (void) { gcc_assert (first_block_aux_obj); obstack_free (&block_aux_obstack, first_block_aux_obj); first_block_aux_obj = NULL; clear_aux_for_blocks (); }
static void compute_antinout_edge (sbitmap *antloc, sbitmap *transp, sbitmap *antin, sbitmap *antout) { basic_block bb; edge e; basic_block *worklist, *qin, *qout, *qend; unsigned int qlen; edge_iterator ei; /* Allocate a worklist array/queue. Entries are only added to the list if they were not already on the list. So the size is bounded by the number of basic blocks. */ qin = qout = worklist = XNEWVEC (basic_block, n_basic_blocks); /* We want a maximal solution, so make an optimistic initialization of ANTIN. */ sbitmap_vector_ones (antin, last_basic_block); /* Put every block on the worklist; this is necessary because of the optimistic initialization of ANTIN above. */ FOR_EACH_BB_REVERSE (bb) { *qin++ = bb; bb->aux = bb; } qin = worklist; qend = &worklist[n_basic_blocks - NUM_FIXED_BLOCKS]; qlen = n_basic_blocks - NUM_FIXED_BLOCKS; /* Mark blocks which are predecessors of the exit block so that we can easily identify them below. */ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) e->src->aux = EXIT_BLOCK_PTR; /* Iterate until the worklist is empty. */ while (qlen) { /* Take the first entry off the worklist. */ bb = *qout++; qlen--; if (qout >= qend) qout = worklist; if (bb->aux == EXIT_BLOCK_PTR) /* Do not clear the aux field for blocks which are predecessors of the EXIT block. That way we never add then to the worklist again. */ sbitmap_zero (antout[bb->index]); else { /* Clear the aux field of this block so that it can be added to the worklist again if necessary. */ bb->aux = NULL; sbitmap_intersection_of_succs (antout[bb->index], antin, bb->index); } if (sbitmap_a_or_b_and_c_cg (antin[bb->index], antloc[bb->index], transp[bb->index], antout[bb->index])) /* If the in state of this block changed, then we need to add the predecessors of this block to the worklist if they are not already on the worklist. */ FOR_EACH_EDGE (e, ei, bb->preds) if (!e->src->aux && e->src != ENTRY_BLOCK_PTR) { *qin++ = e->src; e->src->aux = e; qlen++; if (qin >= qend) qin = worklist; } } clear_aux_for_edges (); clear_aux_for_blocks (); free (worklist); }
void compute_available (sbitmap *avloc, sbitmap *kill, sbitmap *avout, sbitmap *avin) { edge e; basic_block *worklist, *qin, *qout, *qend, bb; unsigned int qlen; edge_iterator ei; /* Allocate a worklist array/queue. Entries are only added to the list if they were not already on the list. So the size is bounded by the number of basic blocks. */ qin = qout = worklist = XNEWVEC (basic_block, n_basic_blocks - NUM_FIXED_BLOCKS); /* We want a maximal solution. */ sbitmap_vector_ones (avout, last_basic_block); /* Put every block on the worklist; this is necessary because of the optimistic initialization of AVOUT above. */ FOR_EACH_BB (bb) { *qin++ = bb; bb->aux = bb; } qin = worklist; qend = &worklist[n_basic_blocks - NUM_FIXED_BLOCKS]; qlen = n_basic_blocks - NUM_FIXED_BLOCKS; /* Mark blocks which are successors of the entry block so that we can easily identify them below. */ FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) e->dest->aux = ENTRY_BLOCK_PTR; /* Iterate until the worklist is empty. */ while (qlen) { /* Take the first entry off the worklist. */ bb = *qout++; qlen--; if (qout >= qend) qout = worklist; /* If one of the predecessor blocks is the ENTRY block, then the intersection of avouts is the null set. We can identify such blocks by the special value in the AUX field in the block structure. */ if (bb->aux == ENTRY_BLOCK_PTR) /* Do not clear the aux field for blocks which are successors of the ENTRY block. That way we never add then to the worklist again. */ sbitmap_zero (avin[bb->index]); else { /* Clear the aux field of this block so that it can be added to the worklist again if necessary. */ bb->aux = NULL; sbitmap_intersection_of_preds (avin[bb->index], avout, bb->index); } if (sbitmap_union_of_diff_cg (avout[bb->index], avloc[bb->index], avin[bb->index], kill[bb->index])) /* If the out state of this block changed, then we need to add the successors of this block to the worklist if they are not already on the worklist. */ FOR_EACH_EDGE (e, ei, bb->succs) if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR) { *qin++ = e->dest; e->dest->aux = e; qlen++; if (qin >= qend) qin = worklist; } } clear_aux_for_edges (); clear_aux_for_blocks (); free (worklist); }
void compute_available (sbitmap *avloc, sbitmap *kill, sbitmap *avout, sbitmap *avin) { edge e; basic_block *worklist, *qin, *qout, *qend, bb; unsigned int qlen; edge_iterator ei; /* Allocate a worklist array/queue. Entries are only added to the list if they were not already on the list. So the size is bounded by the number of basic blocks. */ qin = qout = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS); /* We want a maximal solution. */ bitmap_vector_ones (avout, last_basic_block_for_fn (cfun)); /* Put every block on the worklist; this is necessary because of the optimistic initialization of AVOUT above. Use inverted postorder to make the dataflow problem require less iterations. */ int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun)); int postorder_num = inverted_post_order_compute (postorder); for (int i = 0; i < postorder_num; ++i) { bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]); if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)) continue; *qin++ = bb; bb->aux = bb; } free (postorder); qin = worklist; qend = &worklist[n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS]; qlen = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; /* Mark blocks which are successors of the entry block so that we can easily identify them below. */ FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs) e->dest->aux = ENTRY_BLOCK_PTR_FOR_FN (cfun); /* Iterate until the worklist is empty. */ while (qlen) { /* Take the first entry off the worklist. */ bb = *qout++; qlen--; if (qout >= qend) qout = worklist; /* If one of the predecessor blocks is the ENTRY block, then the intersection of avouts is the null set. We can identify such blocks by the special value in the AUX field in the block structure. */ if (bb->aux == ENTRY_BLOCK_PTR_FOR_FN (cfun)) /* Do not clear the aux field for blocks which are successors of the ENTRY block. That way we never add then to the worklist again. */ bitmap_clear (avin[bb->index]); else { /* Clear the aux field of this block so that it can be added to the worklist again if necessary. */ bb->aux = NULL; bitmap_intersection_of_preds (avin[bb->index], avout, bb); } if (bitmap_ior_and_compl (avout[bb->index], avloc[bb->index], avin[bb->index], kill[bb->index])) /* If the out state of this block changed, then we need to add the successors of this block to the worklist if they are not already on the worklist. */ FOR_EACH_EDGE (e, ei, bb->succs) if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) { *qin++ = e->dest; e->dest->aux = e; qlen++; if (qin >= qend) qin = worklist; } } clear_aux_for_edges (); clear_aux_for_blocks (); free (worklist); }