-/**
- * Returns a equivalent block for another block.
- * If the block has only one predecessor, this is
- * the equivalent one. If the only predecessor of a block is
- * the block itself, this is a dead block.
- *
- * If both predecessors of a block are the branches of a binary
- * Cond, the equivalent block is Cond's block.
- *
- * If all predecessors of a block are bad or lies in a dead
- * block, the current block is dead as well.
- *
- * Note, that blocks are NEVER turned into Bad's, instead
- * the dead_block flag is set. So, never test for is_Bad(block),
- * always use is_dead_Block(block).
- */
-static ir_node *equivalent_node_Block(ir_node *n)
-{
- ir_node *oldn = n;
- int n_preds;
- ir_graph *irg;
-
- /* don't optimize dead or labeled blocks */
- if (is_Block_dead(n) || has_Block_entity(n))
- return n;
-
- n_preds = get_Block_n_cfgpreds(n);
-
- /* The Block constructor does not call optimize, but mature_immBlock()
- calls the optimization. */
- assert(get_Block_matured(n));
-
- irg = get_irn_irg(n);
-
- /* Straightening: a single entry Block following a single exit Block
- can be merged, if it is not the Start block. */
- /* !!! Beware, all Phi-nodes of n must have been optimized away.
- This should be true, as the block is matured before optimize is called.
- But what about Phi-cycles with the Phi0/Id that could not be resolved?
- Remaining Phi nodes are just Ids. */
- if (n_preds == 1) {
- ir_node *pred = skip_Proj(get_Block_cfgpred(n, 0));
-
- if (is_Jmp(pred)) {
- ir_node *predblock = get_nodes_block(pred);
- if (predblock == oldn) {
- /* Jmp jumps into the block it is in -- deal self cycle. */
- n = set_Block_dead(n);
- DBG_OPT_DEAD_BLOCK(oldn, n);
- } else {
- n = predblock;
- DBG_OPT_STG(oldn, n);
- }
- } else if (is_Cond(pred)) {
- ir_node *predblock = get_nodes_block(pred);
- if (predblock == oldn) {
- /* Jmp jumps into the block it is in -- deal self cycle. */
- n = set_Block_dead(n);
- DBG_OPT_DEAD_BLOCK(oldn, n);
- }
- }
- } else if (n_preds == 2) {
- /* Test whether Cond jumps twice to this block
- * The more general case which more than 2 predecessors is handles
- * in optimize_cf(), we handle only this special case for speed here.
- */
- ir_node *a = get_Block_cfgpred(n, 0);
- ir_node *b = get_Block_cfgpred(n, 1);
-
- if (is_Proj(a) && is_Proj(b)) {
- ir_node *cond = get_Proj_pred(a);
-
- if (cond == get_Proj_pred(b) && is_Cond(cond) &&
- get_irn_mode(get_Cond_selector(cond)) == mode_b) {
- /* Also a single entry Block following a single exit Block. Phis have
- twice the same operand and will be optimized away. */
- n = get_nodes_block(cond);
- DBG_OPT_IFSIM1(oldn, a, b, n);
- }
- }
- } else if (get_opt_unreachable_code() &&
- (n != get_irg_start_block(irg)) &&
- (n != get_irg_end_block(irg))) {
- int i;
-
- /* If all inputs are dead, this block is dead too, except if it is
- the start or end block. This is one step of unreachable code
- elimination */
- for (i = get_Block_n_cfgpreds(n) - 1; i >= 0; --i) {
- ir_node *pred = get_Block_cfgpred(n, i);
- ir_node *pred_blk;
-
- if (is_Bad(pred)) continue;
- pred_blk = get_nodes_block(skip_Proj(pred));
-
- if (is_Block_dead(pred_blk)) continue;
-
- if (pred_blk != n) {
- /* really found a living input */
- break;
- }
- }
- if (i < 0) {
- n = set_Block_dead(n);
- DBG_OPT_DEAD_BLOCK(oldn, n);
- }
- }
-
- return n;
-} /* equivalent_node_Block */
-
-/**
- * Returns a equivalent node for a Jmp, a Bad :-)
- * Of course this only happens if the Block of the Jmp is dead.
- */
-static ir_node *equivalent_node_Jmp(ir_node *n)
-{
- ir_node *oldn = n;
-
- /* unreachable code elimination */
- if (is_Block_dead(get_nodes_block(n))) {
- ir_graph *irg = get_irn_irg(n);
- n = get_irg_bad(irg);
- DBG_OPT_DEAD_BLOCK(oldn, n);
- }
- return n;
-} /* equivalent_node_Jmp */
-
-/** Raise is handled in the same way as Jmp. */
-#define equivalent_node_Raise equivalent_node_Jmp
-
-
-/* We do not evaluate Cond here as we replace it by a new node, a Jmp.
- See transform_node_Proj_Cond(). */
-