From patchwork Wed Jul 10 09:37:21 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 257994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 2EF6D2C02AD for ; Wed, 10 Jul 2013 19:38:17 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=eVCOtKE94k5fiVMg dxuTP7nivAI0lpg4JjLS2hvZHfwIgh0kykkU2b9sy6S7lsrkGoZe7U0lbwTX+BKi CvirQ4ZquQ/GcJzO2w0U2wQCUOEGNIiPxN1+Ff4cOr9zEBrb+hgvEF1u4x1JOW// jD1v/qXlqwv5iv99sBWsXFYarc0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=pMW6xxFPT7d20wLA2E47Iu T/AoQ=; b=jTKj+Wc3QDk7ZwY2EOfiPgSMAt3iGxIIzq0DK+HRo3wjFkad70a7Zy lld7CXMt5EauaTxhdKvDOzCkSAKN9fSEloN3Wkhw2oHmCMfbwLhynDV1xOJHXOFh urR1pIUacIc0ytqh/X/cqN4wBC/oWWw0FUTVvpfZvjppbSBwcjDjQ= Received: (qmail 18428 invoked by alias); 10 Jul 2013 09:38:12 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 18418 invoked by uid 89); 10 Jul 2013 09:38:11 -0000 X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.1 Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 10 Jul 2013 09:38:03 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 3DF562653440; Wed, 10 Jul 2013 11:38:01 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cEd_I0W0jLm1; Wed, 10 Jul 2013 11:38:01 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 054BA265343A; Wed, 10 Jul 2013 11:38:01 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Cc: Jeff Law Subject: Preserve label alignment info through dbr Date: Wed, 10 Jul 2013 11:37:21 +0200 Message-ID: <1821473.SyjjZnTRdx@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 X-Virus-Found: No Hi, I was a little surprised to find out that dbr can silently drop the alignment information for labels computed when the CFG is valid (in compute_alignments). The pessimization can be significant for loops when the top label needs to be overaligned, as seen on a private port. Hence the attached patch. Tested on SPARC/Solaris and SPARC64/Solaris, any objections? 2013-07-10 Eric Botcazou * rtl.h (update_alignments): Declare. * final.c (grow_label_align): New function extracted from... (shorten_branches): ...here. Call it. (update_alignments): New function. * reorg.c (sibling_labels): New variable. (get_label_before): Add SIBLING parameter. If it is non-zero, push the new label along with it onto the sibling_labels vector. (fill_simple_delay_slots): Adjust call to get_label_before. (fill_slots_from_thread): Likewise. (relax_delay_slots): Likewise. (make_return_insns): Likewise. (dbr_schedule): Invoke update_alignment on the sibling_labels vector. Index: rtl.h =================================================================== --- rtl.h (revision 200780) +++ rtl.h (working copy) @@ -2749,6 +2749,7 @@ extern void simplify_using_condition (rt /* In final.c */ extern unsigned int compute_alignments (void); +extern void update_alignments (vec &); extern int asm_str_count (const char *templ); struct rtl_hooks Index: final.c =================================================================== --- final.c (revision 200780) +++ final.c (working copy) @@ -814,7 +814,53 @@ struct rtl_opt_pass pass_compute_alignme TODO_verify_rtl_sharing /* todo_flags_finish */ } }; + +/* Grow the LABEL_ALIGN array after new labels are created. */ + +static void +grow_label_align (void) +{ + int old = max_labelno; + int n_labels; + int n_old_labels; + + max_labelno = max_label_num (); + + n_labels = max_labelno - min_labelno + 1; + n_old_labels = old - min_labelno + 1; + label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels); + + /* Range of labels grows monotonically in the function. Failing here + means that the initialization of array got lost. */ + gcc_assert (n_old_labels <= n_labels); + + memset (label_align + n_old_labels, 0, + (n_labels - n_old_labels) * sizeof (struct label_alignment)); +} + +/* Update the already computed alignment information. LABEL_PAIRS is a vector + made up of pairs of labels for which the alignment information of the first + element will be copied from that of the second element. */ + +void +update_alignments (vec &label_pairs) +{ + unsigned int i = 0; + rtx iter, label; + + if (max_labelno != max_label_num ()) + grow_label_align (); + + FOR_EACH_VEC_ELT (label_pairs, i, iter) + if (i & 1) + { + LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter); + LABEL_TO_MAX_SKIP (label) = LABEL_TO_MAX_SKIP (iter); + } + else + label = iter; +} /* Make a pass over all insns and compute their actual lengths by shortening any branches of variable length if possible. */ @@ -852,25 +898,7 @@ shorten_branches (rtx first) uid_shuid = XNEWVEC (int, max_uid); if (max_labelno != max_label_num ()) - { - int old = max_labelno; - int n_labels; - int n_old_labels; - - max_labelno = max_label_num (); - - n_labels = max_labelno - min_labelno + 1; - n_old_labels = old - min_labelno + 1; - - label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels); - - /* Range of labels grows monotonically in the function. Failing here - means that the initialization of array got lost. */ - gcc_assert (n_old_labels <= n_labels); - - memset (label_align + n_old_labels, 0, - (n_labels - n_old_labels) * sizeof (struct label_alignment)); - } + grow_label_align (); /* Initialize label_align and set up uid_shuid to be strictly monotonically rising with insn order. */ Index: reorg.c =================================================================== --- reorg.c (revision 200780) +++ reorg.c (working copy) @@ -1856,10 +1856,15 @@ update_reg_unused_notes (rtx insn, rtx r } } -/* Return the label before INSN, or put a new label there. */ +static vec sibling_labels; + +/* Return the label before INSN, or put a new label there. If SIBLING is + non-zero, it is another label associated with the new label (if any), + typically the former target of the jump that will be redirected to + the new label. */ static rtx -get_label_before (rtx insn) +get_label_before (rtx insn, rtx sibling) { rtx label; @@ -1874,6 +1879,11 @@ get_label_before (rtx insn) label = gen_label_rtx (); emit_label_after (label, prev); LABEL_NUSES (label) = 0; + if (sibling) + { + sibling_labels.safe_push (label); + sibling_labels.safe_push (sibling); + } } return label; } @@ -2219,7 +2229,7 @@ fill_simple_delay_slots (int non_jumps_p rtx new_label = next_real_insn (next_trial); if (new_label != 0) - new_label = get_label_before (new_label); + new_label = get_label_before (new_label, JUMP_LABEL (trial)); else new_label = find_end_label (simple_return_rtx); @@ -2770,7 +2780,7 @@ fill_slots_from_thread (rtx insn, rtx co else if (LABEL_P (new_thread)) label = new_thread; else - label = get_label_before (new_thread); + label = get_label_before (new_thread, JUMP_LABEL (insn)); if (label) { @@ -3321,7 +3331,7 @@ relax_delay_slots (rtx first) /* Now emit a label before the special USE insn, and redirect our jump to the new label. */ - target_label = get_label_before (PREV_INSN (tmp)); + target_label = get_label_before (PREV_INSN (tmp), target_label); reorg_redirect_jump (delay_insn, target_label); next = insn; continue; @@ -3495,7 +3505,7 @@ make_return_insns (rtx first) for (insn = first; insn; insn = NEXT_INSN (insn)) if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn))) { - rtx t = get_label_before (insn); + rtx t = get_label_before (insn, NULL_RTX); if (PATTERN (insn) == ret_rtx) real_return_label = t; else @@ -3825,6 +3835,12 @@ dbr_schedule (rtx first) fprintf (dump_file, "\n"); } + if (!sibling_labels.is_empty ()) + { + update_alignments (sibling_labels); + sibling_labels.release (); + } + free_resource_info (); free (uid_to_ruid); crtl->dbr_scheduled_p = true;