Hello, I'm implementing new RTL pass in GCC. I attached current C source with my RTL pass. I have to use GCC v4.5.1 port for OpenRISC project. Basically I want to discover all "SET" insns which moves constant immediate to register. Then I want to insert additional instruction call right after this move instruction (for now I just want to insert a copy of found "SET" insn). When I compile this pass with commented "add_insn_after(...)" (line 70 in attachment) GCC compiles fine and after installation it discovers SET insn properly. When I uncomment this "add_insn_after(...)" compilation fails with message: (...) ../../gcc-4.5.1/gcc/crtstuff.c: In function ‘__do_global_dtors_aux’: ../../gcc-4.5.1/gcc/crtstuff.c:332:1: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. (...) I run my pass just after "expand" pass. This is first time I'm trying to modify GCC. What am I doing wrong?
#include "config.h" #include "system.h" #include "coretypes.h" #include "tm.h" #include "rtl.h" #include "regs.h" #include "flags.h" #include "insn-config.h" #include "recog.h" #include "hard-reg-set.h" #include "basic-block.h" #include "expr.h" #include "toplev.h" #include "target.h" #include "timevar.h" #include "tree-pass.h" #include "insn-flags.h" static bool gate_handle_rns (void); static unsigned int rest_of_handle_rns (void); struct rtl_opt_pass pass_rtl_rns = { { RTL_PASS, "rtl-rns", /* name */ gate_handle_rns, /* gate */ rest_of_handle_rns, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_DBR_SCHED, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func /* todo_flags_finish */ } }; static bool gate_handle_rns (void) { return true; } static unsigned int rest_of_handle_rns (void) { basic_block block; rtx destination; rtx source; rtx set; rtx instruction; FOR_EACH_BB (block) { FOR_BB_INSNS (block, instruction) { set = single_set (instruction); if (set != NULL_RTX) { destination = SET_DEST (set); source = SET_SRC (set); if (REG_P (destination) && CONST_INT_P (source)) { add_insn_after (copy_rtx (set), set, block); printf ("***** HIT *****\n"); print_rtl (stdout, set); } } } } return 0; }