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); }
int main (int argc, char **argv) { rtx desc; int pattern_lineno; int code; /* not used */ progname = "genmddump"; if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); /* Read the machine description. */ while (1) { desc = read_md_rtx (&pattern_lineno, &code); if (desc == NULL) break; printf (";; %s: %d\n", read_md_filename, pattern_lineno); print_inline_rtx (stdout, desc, 0); printf ("\n\n"); } fflush (stdout); return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); }
static bool interesting_second_load (rtx set, struct load ***load, rtx insn) { rtx mem, reg; if (!set) return false; mem = SET_SRC (set); reg = SET_DEST (set); if (!MEM_P (mem) || MEM_VOLATILE_P (mem) || !REG_P (reg)) return false; *load = (struct load **) htab_find_slot_with_hash (htab_load, mem, load_rtx_hash (mem), NO_INSERT); if (!*load) return false; /* Don't work on cases that never happen: if there is no kill, we would have inherited the reload; if the store and load regs are the same we would need to find an available register. If the kill insn was already replaced by a move this information is stale, disregard it. */ if (rtx_equal_p (reg, (**load)->reg) || !(**load)->reg_kill || INSN_DELETED_P ((**load)->reg_kill) || reg_used_between_p (reg, PREV_INSN ((**load)->reg_kill), NEXT_INSN (insn)) || reg_set_between_p (reg, PREV_INSN ((**load)->reg_kill), insn)) { if (dump_file) { fputs ("\nCan't insert the move before the kill for this load:\n ", dump_file); print_inline_rtx (dump_file, insn, 2); fputs ("\n\n", dump_file); } return false; } return true; }
int main (int argc, char **argv) { progname = "genmddump"; if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); /* Read the machine description. */ md_rtx_info info; while (read_md_rtx (&info)) { printf (";; %s: %d\n", info.loc.filename, info.loc.lineno); print_inline_rtx (stdout, info.def, 0); printf ("\n\n"); } fflush (stdout); return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); }