static void erase_matching_seqs (void) { seq_block sb; matching_seq mseq; rtx insn; basic_block bb; rtx retlabel, saveinsn, callinsn; int i; for (sb = seq_blocks; sb; sb = sb->next_seq_block) { for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq) { insn = mseq->insn; bb = BLOCK_FOR_INSN (insn); /* Get the label after the sequence. This will be the return address. The label will be referenced using a symbol_ref so protect it from deleting. */ retlabel = block_label_after (insn); LABEL_PRESERVE_P (retlabel) = 1; /* Delete the insns of the sequence. */ for (i = 0; i < sb->length; i++) insn = prev_insn_in_block (insn); delete_basic_block (split_block_and_df_analyze (bb, insn)); /* Emit an insn saving the return address to the link register before the deleted sequence. */ saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg, gen_symbol_ref_rtx_for_label (retlabel)), BB_END (bb)); BLOCK_FOR_INSN (saveinsn) = bb; /* Emit a jump to the appropriate part of the pattern sequence after the save insn. Also update the basic block. */ callinsn = emit_jump_insn_after (gen_jump (sb->label), saveinsn); JUMP_LABEL (callinsn) = sb->label; LABEL_NUSES (sb->label)++; BLOCK_FOR_INSN (callinsn) = bb; BB_END (bb) = callinsn; /* Maintain control flow and liveness information. */ SET_REGNO_REG_SET (df_get_live_out (bb), REGNO (pattern_seqs->link_reg)); emit_barrier_after (BB_END (bb)); make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0); IOR_REG_SET (df_get_live_out (bb), df_get_live_in (BLOCK_FOR_INSN (sb->label))); make_edge (BLOCK_FOR_INSN (seq_blocks->label), BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL); } } }
static unsigned int postreload_load (void) { basic_block bb; init_alias_analysis (); FOR_EACH_BB (bb) { rtx insn; htab_load = htab_create (10, load_htab_hash, load_htab_eq, NULL); FOR_BB_INSNS (bb, insn) { rtx set; struct load **load; /* Set reg_kill, invalidate entries if there is an aliasing store or if the registers making up the address change. */ htab_traverse_noresize (htab_load, find_reg_kill_and_mem_invalidate, insn); set = single_set (insn); if (interesting_second_load (set, &load, insn)) { rtx move; move = gen_move_insn (SET_DEST (set), (*load)->reg); /* Make sure we can generate a move. */ extract_insn (move); if (! constrain_operands (1)) continue; move = emit_insn_before (move, (*load)->reg_kill); delete_insn (insn); if (dump_file) { fputs ("Replaced this load:\n ", dump_file); print_inline_rtx (dump_file, insn, 2); fputs ("\n with this move:\n ", dump_file); print_inline_rtx (dump_file, move, 2); fputs ("\n\n", dump_file); } } else if (interesting_load (set)) alloc_load (set); else if (CALL_P (insn)) htab_empty (htab_load); } htab_empty (htab_load); }
static void split_pattern_seq (void) { rtx insn; basic_block bb; rtx retlabel, retjmp, saveinsn; int i; seq_block sb; insn = pattern_seqs->insn; bb = BLOCK_FOR_INSN (insn); /* Get the label after the sequence. This will be the return address. The label will be referenced using a symbol_ref so protect it from deleting. */ retlabel = block_label_after (insn); LABEL_PRESERVE_P (retlabel) = 1; /* Emit an indirect jump via the link register after the sequence acting as the return insn. Also emit a barrier and update the basic block. */ if (!find_reg_note (BB_END (bb), REG_NORETURN, NULL)) retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg), BB_END (bb)); emit_barrier_after (BB_END (bb)); /* Replace all outgoing edges with a new one to the block of RETLABEL. */ while (EDGE_COUNT (bb->succs) != 0) remove_edge (EDGE_SUCC (bb, 0)); make_edge (bb, BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL); /* Split the sequence according to SEQ_BLOCKS and cache the label of the resulting basic blocks. */ i = 0; for (sb = seq_blocks; sb; sb = sb->next_seq_block) { for (; i < sb->length; i++) insn = prev_insn_in_block (insn); sb->label = block_label (split_block_and_df_analyze (bb, insn)); } /* Emit an insn saving the return address to the link register before the sequence. */ saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg, gen_symbol_ref_rtx_for_label (retlabel)), BB_END (bb)); /* Update liveness info. */ SET_REGNO_REG_SET (df_get_live_out (bb), REGNO (pattern_seqs->link_reg)); }