diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e52ef562553..17dc8cae1cb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-10-06 Maxim Kuvyrkov + + PR rtl-optimization/29128 + * sched-int.h (IS_SPECULATION_BRANCHY_CHECK_P): New macro. + * sched-ebb.c (advance_target_bb): Use it to fix condition to + allow interblock movement of speculation checks. + 2006-10-06 Zdenek Dvorak PR middle-end/29256 diff --git a/gcc/sched-ebb.c b/gcc/sched-ebb.c index b220348da7b..599241a47c8 100644 --- a/gcc/sched-ebb.c +++ b/gcc/sched-ebb.c @@ -719,9 +719,13 @@ advance_target_bb (basic_block bb, rtx insn) { if (BLOCK_FOR_INSN (insn) != bb && control_flow_insn_p (insn) - && !RECOVERY_BLOCK (insn) - && !RECOVERY_BLOCK (BB_END (bb))) + /* We handle interblock movement of the speculation check + or over a speculation check in + haifa-sched.c: move_block_after_check (). */ + && !IS_SPECULATION_BRANCHY_CHECK_P (insn) + && !IS_SPECULATION_BRANCHY_CHECK_P (BB_END (bb))) { + /* Assert that we don't move jumps across blocks. */ gcc_assert (!control_flow_insn_p (BB_END (bb)) && NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb))); return bb; diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 3ce0379ce43..3865013b9df 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -359,6 +359,13 @@ extern regset *glat_start, *glat_end; #define RECOVERY_BLOCK(INSN) (h_i_d[INSN_UID (INSN)].recovery_block) #define ORIG_PAT(INSN) (h_i_d[INSN_UID (INSN)].orig_pat) +/* INSN is a speculation check that will branch to RECOVERY_BLOCK if the + speculation fail. Insns in that block will reexecute the speculatively + scheduled code and then will return immediatelly after INSN thus preserving + semantics of the program. */ +#define IS_SPECULATION_BRANCHY_CHECK_P(INSN) \ + (RECOVERY_BLOCK (INSN) != NULL && RECOVERY_BLOCK (INSN) != EXIT_BLOCK_PTR) + /* DEP_STATUS of the link encapsulates information, that is needed for speculative scheduling. Namely, it is 4 integers in the range [0, MAX_DEP_WEAK] and 3 bits. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 86b892cfc34..e09494bc37b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-10-06 Maxim Kuvyrkov + + PR rtl-optimization/29128 + * gcc.c-torture/compile/pr29128.c: New test. + 2006-10-06 Tobias Schlueter * gfortran.dg/actual_array_constructor_2.f90: Remove '\r's from diff --git a/gcc/testsuite/gcc.c-torture/compile/pr29128.c b/gcc/testsuite/gcc.c-torture/compile/pr29128.c new file mode 100644 index 00000000000..2afeae3ce22 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr29128.c @@ -0,0 +1,28 @@ +typedef unsigned long Eterm; +process_main (void) +{ + register Eterm x0; + register Eterm *reg = ((void *) 0); + register Eterm *I = ((void *) 0); + static void *opcodes[] = { + &&lb_allocate_heap_zero_III, + &&lb_allocate_init_tIy, &&lb_allocate_zero_tt + }; +lb_allocate_heap_III:{ + Eterm *next; + goto *(next); + } +lb_allocate_heap_zero_III:{ + } +lb_allocate_init_tIy:{ + } +lb_allocate_zero_tt:{ + Eterm *next; + { + Eterm *tmp_ptr = ((Eterm *) (((x0)) - 0x1)); + (*(Eterm *) (((unsigned char *) reg) + (I[(0) + 1]))) = ((tmp_ptr)[0]); + x0 = ((tmp_ptr)[1]); + } + goto *(next); + } +}