From patchwork Fri Sep 30 07:04:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Revital Eres X-Patchwork-Id: 4449 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id CB4BD23FB8 for ; Fri, 30 Sep 2011 07:04:38 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id B47D2A1840A for ; Fri, 30 Sep 2011 07:04:38 +0000 (UTC) Received: by fxe23 with SMTP id 23so3728839fxe.11 for ; Fri, 30 Sep 2011 00:04:38 -0700 (PDT) Received: by 10.223.55.136 with SMTP id u8mr15031203fag.46.1317366278569; Fri, 30 Sep 2011 00:04:38 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.3.234 with SMTP id f10cs42815laf; Fri, 30 Sep 2011 00:04:37 -0700 (PDT) Received: by 10.100.237.15 with SMTP id k15mr10191013anh.83.1317366276981; Fri, 30 Sep 2011 00:04:36 -0700 (PDT) Received: from mail-yx0-f178.google.com (mail-yx0-f178.google.com [209.85.213.178]) by mx.google.com with ESMTPS id j13si1912955anj.55.2011.09.30.00.04.36 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 30 Sep 2011 00:04:36 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.213.178 is neither permitted nor denied by best guess record for domain of revital.eres@linaro.org) client-ip=209.85.213.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.213.178 is neither permitted nor denied by best guess record for domain of revital.eres@linaro.org) smtp.mail=revital.eres@linaro.org Received: by yxj19 with SMTP id 19so1568261yxj.37 for ; Fri, 30 Sep 2011 00:04:36 -0700 (PDT) MIME-Version: 1.0 Received: by 10.100.254.3 with SMTP id b3mr10533259ani.124.1317366276337; Fri, 30 Sep 2011 00:04:36 -0700 (PDT) Received: by 10.101.58.12 with HTTP; Fri, 30 Sep 2011 00:04:36 -0700 (PDT) In-Reply-To: References: Date: Fri, 30 Sep 2011 10:04:36 +0300 Message-ID: Subject: Re: [PATCH, SMS 2/2] Support instructions with REG_INC_NOTE (second try) From: Revital Eres To: Ayal Zaks Cc: gcc-patches@gcc.gnu.org, Patch Tracking Hello, > OK, with the following comments: > > Make sure reg_moves are generated for the correct (result, not addr) > register, in generate_reg_moves(). > > "been">>"being" (multiple appearances). > > Add a note that autoinc_var_is_used_p (rtx def_insn, rtx use_insn) > doesn't need to consider the specific address register; no reg_moves > will be allowed for any life range defined by def_insn and used by > use_insn, if use_insn uses an address register auto-inc'ed by > def_insn. Attached is the version of the patch which addresses your comments. Currently re-testing on ppc64-redhat-linux (bootstrap and regtest) and arm-linux-gnueabi (bootstrap c). I'll commit it once tesing completes if there if no further changes required. 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. * ddg.h (autoinc_var_is_used_p): Declare. * modulo-sched.c (generate_reg_moves): Call autoinc_var_is_used_p. (sms_schedule): Handle instructions with REG_INC. Index: ddg.c =================================================================== --- ddg.c (revision 179138) +++ ddg.c (working copy) @@ -145,6 +145,27 @@ mem_access_insn_p (rtx insn) return rtx_mem_access_p (PATTERN (insn)); } +/* Return true if DEF_INSN contains address being auto-inc or auto-dec + which is used in USE_INSN. Otherwise return false. The result is + being used to decide whether to remove the edge between def_insn and + use_insn when -fmodulo-sched-allow-regmoves is set. This function + doesn't need to consider the specific address register; no reg_moves + will be allowed for any life range defined by def_insn and used + by use_insn, if use_insn uses an address register auto-inc'ed by + def_insn. */ +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 +194,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 being 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 +328,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 being 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: ddg.h =================================================================== --- ddg.h (revision 179138) +++ ddg.h (working copy) @@ -186,4 +186,6 @@ void free_ddg_all_sccs (ddg_all_sccs_ptr int find_nodes_on_paths (sbitmap result, ddg_ptr, sbitmap from, sbitmap to); int longest_simple_path (ddg_ptr, int from, int to, sbitmap via); +bool autoinc_var_is_used_p (rtx, rtx); + #endif /* GCC_DDG_H */ Index: modulo-sched.c =================================================================== --- modulo-sched.c (revision 179138) +++ modulo-sched.c (working copy) @@ -506,6 +506,10 @@ generate_reg_moves (partial_schedule_ptr we assume no regmoves are generated as the doloop instructions are tied to the branch with an edge. */ gcc_assert (set); + /* If the instruction contains auto-inc register then + validate that the regmov is being generated for the + target regsiter rather then the inc'ed register. */ + gcc_assert (!autoinc_var_is_used_p (u->insn, e->dest->insn)); } nreg_moves = MAX (nreg_moves, nreg_moves4e); @@ -1266,12 +1285,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 +1299,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 +1312,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");