Re: rtl_loop_init vs try_redirect_by_replacing_jump vs simple jumps
On 5/23/06, DJ Delorie [EMAIL PROTECTED] wrote: What seems to happen is, we delete the simple jump even if we can't fallthru, and thus the blocks get rearranged in an incorrect order. Is there a bug here, or am I misunderstanding how this code works? You're misunderstanding how this code works. In cfglayout mode, there is no order in the basic blocks such that BLOCK_FOR_INSN(NEXT_INSN(BB_END(BB)) ) == BB-next_bb. This means that you can fall through to other blocks than next_bb. cfg_layout_finalize should fix this up where necessary when you go back into cfgrtl mode. Perhaps http://gcc.gnu.org/wiki/cfglayout%20mode can help explain this a bit more. Gr. Steven
Re: rtl_loop_init vs try_redirect_by_replacing_jump vs simple jumps
On 5/23/06, Steven Bosscher [EMAIL PROTECTED] wrote: On 5/23/06, DJ Delorie [EMAIL PROTECTED] wrote: What seems to happen is, we delete the simple jump even if we can't fallthru, and thus the blocks get rearranged in an incorrect order. Is there a bug here, or am I misunderstanding how this code works? You're misunderstanding how this code works. And, I forgot to say, one of the reasons that this keeps confusing people is because the rtl dumps in cfglayout mode tend to look confusing because there is almost no CFG information in them. I intend to fix that after finishing fwprop. In the mean time you can use brief_dump_cfg and/or hack print_rtl_with_bb to print predecessors/successors at the start/end of each basic block. Gr. Steven
Re: rtl_loop_init vs try_redirect_by_replacing_jump vs simple jumps
You're misunderstanding how this code works. In cfglayout mode, there is no order in the basic blocks such that BLOCK_FOR_INSN(NEXT_INSN(BB_END(BB)) ) == BB-next_bb. This means that you can fall through to other blocks than next_bb. Thanks for the tip, I figured out what was really happening. Which leads to the next question: What's the right way to keep an asm() from being loop invariant? I've got a case where an inline asm() is passed a pointer (the pointer is invariant) but internally dereferences it (the pointed-at memory is *not* invariant). However, loop-invariant.c is pulling it out of the loop anyway. Making the whole asm() volatile works, but that seems like overkill to me.
Re: rtl_loop_init vs try_redirect_by_replacing_jump vs simple jumps
On 5/23/06, DJ Delorie [EMAIL PROTECTED] wrote: You're misunderstanding how this code works. In cfglayout mode, there is no order in the basic blocks such that BLOCK_FOR_INSN(NEXT_INSN(BB_END(BB)) ) == BB-next_bb. This means that you can fall through to other blocks than next_bb. Thanks for the tip, I figured out what was really happening. Which leads to the next question: What's the right way to keep an asm() from being loop invariant? I've got a case where an inline asm() is passed a pointer (the pointer is invariant) but internally dereferences it (the pointed-at memory is *not* invariant). However, loop-invariant.c is pulling it out of the loop anyway. Sounds like you need a memory clobber constraint on the asm... ? Gr. Steven
Re: rtl_loop_init vs try_redirect_by_replacing_jump vs simple jumps
Sounds like you need a memory clobber constraint on the asm... ? Yup, that looks like it would do the trick. Thanks!
Re: rtl_loop_init vs try_redirect_by_replacing_jump vs simple jumps
On 5/23/06, DJ Delorie [EMAIL PROTECTED] wrote: You're misunderstanding how this code works. In cfglayout mode, there is no order in the basic blocks such that BLOCK_FOR_INSN(NEXT_INSN(BB_END(BB)) ) == BB-next_bb. This means that you can fall through to other blocks than next_bb. Thanks for the tip, I figured out what was really happening. Which leads to the next question: What's the right way to keep an asm() from being loop invariant? I've got a case where an inline asm() is passed a pointer (the pointer is invariant) but internally dereferences it (the pointed-at memory is *not* invariant). However, loop-invariant.c is pulling it out of the loop anyway. Sounds like you need a memory clobber constraint on the asm... ? Or mark the memory as read like so: asm ( . : : ... , m (*pointer) ); -- Pinski
rtl_loop_init vs try_redirect_by_replacing_jump vs simple jumps
I've got a case where an unconditional simple jump is being removed, yet it doesn't jump to the next insn. The code in question seems suspect... Here we force CLEANUP_CFGLAYOUT true: void cfg_layout_initialize (unsigned int flags) { . . . cleanup_cfg (CLEANUP_CFGLAYOUT | flags); } in cleanup_cfg we have this logic: /* If B has a single outgoing edge, but uses a non-trivial jump instruction without side-effects, we can either delete the jump entirely, or replace it with a simple unconditional jump. */ if (single_succ_p (b) single_succ (b) != EXIT_BLOCK_PTR onlyjump_p (BB_END (b)) !find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX) try_redirect_by_replacing_jump (single_succ_edge (b), single_succ (b), (mode CLEANUP_CFGLAYOUT) != 0)) It says non-trivial but the insn is a simple jump: (jump_insn 45 44 46 5 (set (pc) (label_ref:DI 754))) Note that mode of course has CLEANUP_CFGLAYOUT set. Thus, here in try_redirect_by_replacing_jump (note that in_cfglayout is set, from mode above): /* See if we can create the fallthru edge. */ if (in_cfglayout || can_fallthru (src, target)) { if (dump_file) fprintf (dump_file, Removing jump %i.\n, INSN_UID (insn)); fallthru = 1; /* Selectively unlink whole insn chain. */ if (in_cfglayout) { rtx insn = src-il.rtl-footer; delete_insn_chain (kill_from, BB_END (src)); What seems to happen is, we delete the simple jump even if we can't fallthru, and thus the blocks get rearranged in an incorrect order. Is there a bug here, or am I misunderstanding how this code works?