Hello all, In the gcc 4.1.2 port i am working on, i get an ICE in insert_save, at caller-save.c:725 And following is the assert that assert failure.
/* A common failure mode if register status is not correct in the RTL is for this routine to be called with a REGNO we didn't expect to save. That will cause us to write an insn with a (nil) SET_DEST or SET_SRC. Instead of doing so and causing a crash later, check for this common case here. This will remove one step in debugging such problems. */ gcc_assert (regno_save_mem[regno][1]); insert_save function is called by save_call_clobbered_regs() in the same file.The below is the relevant portion of the dump after local register allocation. (insn 210 213 211 1 (set (reg:HI 0 R0 [ d.104 ]) (subreg:HI (reg/v:SF 207 [ d.104 ]) 0)) 4 {movhi_regmove} (insn_list:REG_DEP_TRUE 208 (nil)) (insn_list:REG_LIBCALL 215 (nil))) (insn 211 210 215 1 (set (reg:HI 1 R1 [+2 ]) (subreg:HI (reg/v:SF 207 [ d.104 ]) 2)) 4 {movhi_regmove} (insn_list:REG_DEP_TRUE 208 (nil)) (nil)) (call_insn/u 215 211 217 1 (set (reg:HI 0 R0) (call:HI (mem:HI (reg/f:HI 234) [0 S2 A16]) (const_int 0 [0x0]))) 25 {*call_value_internal_long} (insn_list:REG_DEP_ANTI 207 (insn_list:REG_DEP_ANTI 209 (insn_list:REG_DEP_TRUE 213 (insn_list:REG_DEP_TRUE 212 (insn_list:REG_DEP_TRUE 211 (insn_list:REG_DEP_TRUE 210 (insn_list:REG_DEP_ANTI 208 (nil)))))))) (expr_list:REG_DEAD (reg:SF 2 R2) (insn_list:REG_RETVAL 210 (expr_list:REG_EH_REGION (const_int -1 [0xffffffff]) (nil)))) (expr_list:REG_DEP_TRUE (use (reg:SF 2 R2)) (expr_list:REG_DEP_TRUE (use (reg:SF 0 R0)) (nil)))) (jump_insn 217 215 222 1 (set (pc) (if_then_else (le:CC (reg:HI 0 R0) (const_int 0 [0x0])) (label_ref:HI 226) (pc))) 48 {cmpbrhi_le} (insn_list:REG_DEP_TRUE 215 (nil)) (expr_list:REG_DEAD (reg:HI 0 R0) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil)))) ;; End of basic block 1, registers live: 1 [R1] 12 [R12] 14 [R14] 16 [AP] 206 207 208 209 215 218 234 Things go wrong in "call_insn/u 215". Target has R0 and R1 are the parameter registers. So while building the reload chain for the call instructions the registers that are live during the call are R0, R1 among other registers. This information is stored in live_throughout member of the reload chain. In the function save_call_clobbered_regs() register life information in CHAIN is used to compute which regs are live during the call. And this is stored in hard_regs_to_save. After doing the following operations /* Compute which hard regs must be saved before this call. */ AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set); hard_regs_to_save will still contain R1 in it.(Parameter registers are part of call used register set.) And hence insert_save is called for saving reg R1. >From the time of reload chain generation to save_call_clobbered_regs() function call things are proper, even though, as the comment says the registers status is not proper when save_call_clobbered_regs() is called. Looking at the dumps i think the only thing that is going wrong is the live information of the registers. For a call instructions all the parameter registers used by the call instructions will be live at the time of the call. But if these registers are used in the successor blocks only to pass the parameters, i.e their value is not used again, shouldn't these registers be marked as dead in the call instruction?. After some lengthy debugging this is the only conclusion that i can come to. But i am not sure if this is way live information is handled. Can some one give any thoughts on this? Regards, Shafi