Hello, This patch extends the implementation to support instructions with REG_INC notes. It addresses the comments from the previous submission: http://gcc.gnu.org/ml/gcc-patches/2011-08/msg01299.html.
btw, regarding your previous question about the usage of the address register been auto inc, apparently it can be used as follows: insn 1) def1 = MEM [ pre_dec (addr) ] out edges: [1 -(T,2,1)-> 1] [1 -(T,2,0)-> 2] in edges: [1 -(T,2,1)-> 1] [2 -(T,2,1)-> 1] [2 -(A,0,1)->1] insn 2) MEM [ addr + 3 ] = def1 out edges: [2 -(T,2,1)-> 1] [2 -(A,0,1)->1] in edges: [1 -(T,2,0)-> 2] Reg-moves were not created for the address when testing on ppc. Tested and bootstrap with patch 1 on ppc64-redhat-linux enabling SMS on loops with SC 1. On arm-linux-gnueabi bootstrap c on top of the set of patches that support do-loop pattern (http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01807.html) which solves the bootstrap failure on ARM with SMS flags. OK for mainline? Thanks, Revital * ddg.c (autoinc_var_is_used_p): New function. (create_ddg_dep_from_intra_loop_link, add_cross_iteration_register_deps): Call it. * modulo-sched.c (sms_schedule): Handle instructions with REG_INC.
Index: ddg.c =================================================================== --- ddg.c (revision 179138) +++ ddg.c (working copy) @@ -145,6 +145,23 @@ mem_access_insn_p (rtx insn) return rtx_mem_access_p (PATTERN (insn)); } +/* Return true if DEF_INSN contains address been auto-inc or auto-dec + which is used in USE_INSN. Otherwise return false. The result is + been used to decide whether to remove the edge between def_insn and + use_insn when -fmodulo-sched-allow-regmoves is set. */ +static bool +autoinc_var_is_used_p (rtx def_insn, rtx use_insn) +{ + rtx note; + + for (note = REG_NOTES (def_insn); note; note = XEXP (note, 1)) + if (REG_NOTE_KIND (note) == REG_INC + && reg_referenced_p (XEXP (note, 0), PATTERN (use_insn))) + return true; + + return false; +} + /* Computes the dependence parameters (latency, distance etc.), creates a ddg_edge and adds it to the given DDG. */ static void @@ -173,10 +190,15 @@ create_ddg_dep_from_intra_loop_link (ddg compensate for that by generating reg-moves based on the life-range analysis. The anti-deps that will be deleted are the ones which have true-deps edges in the opposite direction (in other words - the kernel has only one def of the relevant register). TODO: - support the removal of all anti-deps edges, i.e. including those + the kernel has only one def of the relevant register). + If the address that is been auto-inc or auto-dec in DEST_NODE + is used in SRC_NODE then do not remove the edge to make sure + reg-moves will not be created for this address. + TODO: support the removal of all anti-deps edges, i.e. including those whose register has multiple defs in the loop. */ - if (flag_modulo_sched_allow_regmoves && (t == ANTI_DEP && dt == REG_DEP)) + if (flag_modulo_sched_allow_regmoves + && (t == ANTI_DEP && dt == REG_DEP) + && !autoinc_var_is_used_p (dest_node->insn, src_node->insn)) { rtx set; @@ -302,10 +324,14 @@ add_cross_iteration_register_deps (ddg_p gcc_assert (first_def_node); /* Always create the edge if the use node is a branch in - order to prevent the creation of reg-moves. */ + order to prevent the creation of reg-moves. + If the address that is been auto-inc or auto-dec in LAST_DEF + is used in USE_INSN then do not remove the edge to make sure + reg-moves will not be created for that address. */ if (DF_REF_ID (last_def) != DF_REF_ID (first_def) || !flag_modulo_sched_allow_regmoves - || JUMP_P (use_node->insn)) + || JUMP_P (use_node->insn) + || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn)) create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP, REG_DEP, 1); Index: modulo-sched.c =================================================================== --- modulo-sched.c (revision 179138) +++ modulo-sched.c (working copy) @@ -1266,12 +1271,10 @@ sms_schedule (void) continue; } - /* Don't handle BBs with calls or barriers or auto-increment insns - (to avoid creating invalid reg-moves for the auto-increment insns), + /* Don't handle BBs with calls or barriers or !single_set with the exception of instructions that include count_reg---these instructions are part of the control part that do-loop recognizes. - ??? Should handle auto-increment insns. ??? Should handle insns defining subregs. */ for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn)) { @@ -1282,7 +1285,6 @@ sms_schedule (void) || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn) && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE && !reg_mentioned_p (count_reg, insn)) - || (FIND_REG_INC_NOTE (insn, NULL_RTX) != 0) || (INSN_P (insn) && (set = single_set (insn)) && GET_CODE (SET_DEST (set)) == SUBREG)) break; @@ -1296,8 +1298,6 @@ sms_schedule (void) fprintf (dump_file, "SMS loop-with-call\n"); else if (BARRIER_P (insn)) fprintf (dump_file, "SMS loop-with-barrier\n"); - else if (FIND_REG_INC_NOTE (insn, NULL_RTX) != 0) - fprintf (dump_file, "SMS reg inc\n"); else if ((NONDEBUG_INSN_P (insn) && !JUMP_P (insn) && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE)) fprintf (dump_file, "SMS loop-with-not-single-set\n");