From patchwork Tue May 8 11:42:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 157672 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]) by ozlabs.org (Postfix) with SMTP id 548ADB6FA1 for ; Tue, 8 May 2012 21:43:04 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1337082185; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=82wWPFfjtFH2E24urr9N uJprDhU=; b=fFIIQHJhwk4uhj8iruyhxsjmu8AeNfXPbGYzaNuP+Zc3yIOdNMbS Ru/unKYtmDNeHx1R9j6axuELmfrsptg/9SItJNtN0MxAV6IAMlew1wSWYpJgqsHW n90xINf0JFpfKo+0+Hrtb2Yi6Wp5iRw2tmTT9gmSrGQrJQ8odcdSq9o= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=ufT9Ld4MiU0K3VUeX/My5rDeG9JR5+27Bu4gfApcknMbp4CpcsGKeX/GuGTHo+ +84tPPsc6rcPY5xpYT/M8wLqPBDcRmKe8tAFhYs2XFYukSYkK0a6e4QzEYy1Mi+R nee72jOCAHWtWPhznQ5jrhkm7sOcnRFwYpnEZIC3vSu/k=; Received: (qmail 29175 invoked by alias); 8 May 2012 11:43:01 -0000 Received: (qmail 29165 invoked by uid 22791); 8 May 2012 11:42:59 -0000 X-SWARE-Spam-Status: No, hits=-5.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 08 May 2012 11:42:45 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id CC156974AA; Tue, 8 May 2012 13:42:44 +0200 (CEST) Date: Tue, 8 May 2012 13:42:44 +0200 (CEST) From: Richard Guenther To: gcc-patches@gcc.gnu.org Cc: ebotcazou@adacore.com Subject: [PATCH] Optimize byte_from_pos, pos_from_bit Message-ID: MIME-Version: 1.0 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 This optimizes byte_from_pos and pos_from_bit by noting that we operate on sizes whose computations have no intermediate (or final) overflow. This is the single patch necessary to get Ada to bootstrap and test with TYPE_IS_SIZETYPE removed. Rather than amending size_binop (my original plan) I chose to optimize the above two commonly used accessors. Conveniently normalize_offset can be re-written to use pos_from_bit instead of inlinig it. I also took the liberty to document the functions (sic). The patch already passed bootstrap & regtest on x86_64-unknown-linux-gnu with TYPE_IS_SIZETYPE removed, now re-testing without that change. Any comments? Would you like different factoring of the optimization (I considered adding a byte_from_bitpos)? Any idea why byte_from_pos is using TRUNC_DIV_EXPR (only positive offsets?) and pos_from_bit FLOOR_DIV_EXPR (also negative offsets?) - that seems inconsistent, and we fold FLOOR_DIV_EXPR of unsigned types (sizetype) to TRUNC_DIV_EXPR anyways. Thanks, Richard. 2012-05-08 Richard Guenther * stor-layout.c (bit_from_pos): Document. (byte_from_pos): Likewise. Optimize. (pos_from_bit): Likewise. (normalize_offset): Use pos_from_bit instead of replicating it. Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c (revision 187276) +++ gcc/stor-layout.c (working copy) @@ -785,8 +785,8 @@ start_record_layout (tree t) return rli; } -/* These four routines perform computations that convert between - the offset/bitpos forms and byte and bit offsets. */ +/* Return the combined bit position for the byte offset OFFSET and the + bit position BITPOS. */ tree bit_from_pos (tree offset, tree bitpos) @@ -797,25 +797,46 @@ bit_from_pos (tree offset, tree bitpos) bitsize_unit_node)); } +/* Return the combined truncated byte position for the byte offset OFFSET and + the bit position BITPOS. */ + tree byte_from_pos (tree offset, tree bitpos) { - return size_binop (PLUS_EXPR, offset, - fold_convert (sizetype, - size_binop (TRUNC_DIV_EXPR, bitpos, - bitsize_unit_node))); + tree bytepos; + if (TREE_CODE (bitpos) == MULT_EXPR + && tree_int_cst_equal (TREE_OPERAND (bitpos, 1), bitsize_unit_node)) + bytepos = TREE_OPERAND (bitpos, 0); + else + bytepos = size_binop (TRUNC_DIV_EXPR, bitpos, bitsize_unit_node); + return size_binop (PLUS_EXPR, offset, fold_convert (sizetype, bytepos)); } +/* Split the bit position POS into a byte offset *POFFSET and a bit + position *PBITPOS with the byte offset aligned to OFF_ALIGN bits. */ + void pos_from_bit (tree *poffset, tree *pbitpos, unsigned int off_align, tree pos) { - *poffset = size_binop (MULT_EXPR, - fold_convert (sizetype, - size_binop (FLOOR_DIV_EXPR, pos, - bitsize_int (off_align))), - size_int (off_align / BITS_PER_UNIT)); - *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align)); + tree toff_align = bitsize_int (off_align); + if (TREE_CODE (pos) == MULT_EXPR + && tree_int_cst_equal (TREE_OPERAND (pos, 1), toff_align)) + { + *poffset = size_binop (MULT_EXPR, + fold_convert (sizetype, TREE_OPERAND (pos, 0)), + size_int (off_align / BITS_PER_UNIT)); + *pbitpos = bitsize_zero_node; + } + else + { + *poffset = size_binop (MULT_EXPR, + fold_convert (sizetype, + size_binop (FLOOR_DIV_EXPR, pos, + toff_align)), + size_int (off_align / BITS_PER_UNIT)); + *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, toff_align); + } } /* Given a pointer to bit and byte offsets and an offset alignment, @@ -828,17 +849,10 @@ normalize_offset (tree *poffset, tree *p downwards. */ if (compare_tree_int (*pbitpos, off_align) >= 0) { - tree extra_aligns = size_binop (FLOOR_DIV_EXPR, *pbitpos, - bitsize_int (off_align)); - - *poffset - = size_binop (PLUS_EXPR, *poffset, - size_binop (MULT_EXPR, - fold_convert (sizetype, extra_aligns), - size_int (off_align / BITS_PER_UNIT))); - - *pbitpos - = size_binop (FLOOR_MOD_EXPR, *pbitpos, bitsize_int (off_align)); + tree offset, bitpos; + pos_from_bit (&offset, &bitpos, off_align, *pbitpos); + *poffset = size_binop (PLUS_EXPR, *poffset, offset); + *pbitpos = bitpos; } }