-/**
- * Garbage in, garbage out. If a node has a dead input, i.e., the
- * Bad node is input to the node, return the Bad node.
- */
-static ir_node *gigo(ir_node *node)
-{
- int i, irn_arity;
- ir_op *op = get_irn_op(node);
-
- /* remove garbage blocks by looking at control flow that leaves the block
- and replacing the control flow by Bad. */
- if (get_irn_mode(node) == mode_X) {
- ir_node *block = get_nodes_block(skip_Proj(node));
- ir_graph *irg = get_irn_irg(block);
-
- /* Don't optimize nodes in immature blocks. */
- if (!get_Block_matured(block))
- return node;
- /* Don't optimize End, may have Bads. */
- if (op == op_End) return node;
-
- if (is_Block(block)) {
- if (is_Block_dead(block)) {
- /* control flow from dead block is dead */
- return get_irg_bad(irg);
- }
-
- for (i = get_irn_arity(block) - 1; i >= 0; --i) {
- if (!is_Bad(get_irn_n(block, i)))
- break;
- }
- if (i < 0) {
- ir_graph *irg = get_irn_irg(block);
- /* the start block is never dead */
- if (block != get_irg_start_block(irg)
- && block != get_irg_end_block(irg)) {
- /*
- * Do NOT kill control flow without setting
- * the block to dead of bad things can happen:
- * We get a Block that is not reachable be irg_block_walk()
- * but can be found by irg_walk()!
- */
- set_Block_dead(block);
- return get_irg_bad(irg);
- }
- }
- }
- }
-
- /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
- blocks predecessors is dead. */
- if (op != op_Block && op != op_Phi && op != op_Tuple && op != op_Anchor) {
- ir_graph *irg = get_irn_irg(node);
- irn_arity = get_irn_arity(node);
-
- /*
- * Beware: we can only read the block of a non-floating node.
- */
- if (is_irn_pinned_in_irg(node) &&
- is_Block_dead(get_nodes_block(skip_Proj(node))))
- return get_irg_bad(irg);
-
- for (i = 0; i < irn_arity; i++) {
- ir_node *pred = get_irn_n(node, i);
-
- if (is_Bad(pred))
- return get_irg_bad(irg);
-#if 0
- /* Propagating Unknowns here seems to be a bad idea, because
- sometimes we need a node as a input and did not want that
- it kills its user.
- However, it might be useful to move this into a later phase
- (if you think that optimizing such code is useful). */
- if (is_Unknown(pred) && mode_is_data(get_irn_mode(node)))
- return new_r_Unknown(irg, get_irn_mode(node));
-#endif
- }
- }
-#if 0
- /* With this code we violate the agreement that local_optimize
- only leaves Bads in Block, Phi and Tuple nodes. */
- /* If Block has only Bads as predecessors it's garbage. */
- /* If Phi has only Bads as predecessors it's garbage. */
- if ((op == op_Block && get_Block_matured(node)) || op == op_Phi) {
- irn_arity = get_irn_arity(node);
- for (i = 0; i < irn_arity; i++) {
- if (!is_Bad(get_irn_n(node, i))) break;
- }
- if (i == irn_arity) node = get_irg_bad(irg);
- }
-#endif
- return node;
-} /* gigo */
-