From patchwork Wed Dec 4 16:16:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 2018331 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gjlay.de header.i=@gjlay.de header.a=rsa-sha256 header.s=strato-dkim-0002 header.b=OQPdb8UN; dkim=pass header.d=gjlay.de header.i=@gjlay.de header.a=ed25519-sha256 header.s=strato-dkim-0003 header.b=QWXHbnEM; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Y3N2p1pnyz1yRK for ; Thu, 5 Dec 2024 03:17:22 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4D3963858D35 for ; Wed, 4 Dec 2024 16:17:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4D3963858D35 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gjlay.de header.i=@gjlay.de header.a=rsa-sha256 header.s=strato-dkim-0002 header.b=OQPdb8UN; dkim=pass header.d=gjlay.de header.i=@gjlay.de header.a=ed25519-sha256 header.s=strato-dkim-0003 header.b=QWXHbnEM X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mo4-p01-ob.smtp.rzone.de (mo4-p01-ob.smtp.rzone.de [81.169.146.165]) by sourceware.org (Postfix) with ESMTPS id 0A4973858D20 for ; Wed, 4 Dec 2024 16:16:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0A4973858D20 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=gjlay.de Authentication-Results: sourceware.org; spf=none smtp.mailfrom=gjlay.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0A4973858D20 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=81.169.146.165 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1733328993; cv=pass; b=gmnBMS1LXqmK9ff6ISN9D1P23A5WRaVVbgIqb8JJ6kyBzBi09qR/gBZs0WWt7NWwMD4xhet7oRauboIvnvLSwtQFnS+A4tXz2F5NpmUXKzwVdgUZDZKMSfYsLBmaxJD95cLHUeDLd2UdkSl7uS5xsIEfsTq1I3YJw8IRcWfrnFM= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1733328993; c=relaxed/simple; bh=w2ORvr6S34eL9ayrXSRSmaDmkAIIbvjysVr8ypbSQxw=; h=DKIM-Signature:DKIM-Signature:Message-ID:Date:MIME-Version:From: Subject:To; b=LNkPxpn+7tvCjJY3+6GOAsYdWg416roXuYuSDXS0m17wF9sr5CReM2dd0riAqPOrE+5r9E/Xtz7c7LuWtFitnVFIYUHGHNrayKaUhzIg/b8rmFkb9GCcnp7cp/sncKTez0zjIssLdSL1dl3eNbyD97kYc/+FLkcnDdFX7/vTEjo= ARC-Authentication-Results: i=2; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A4973858D20 ARC-Seal: i=1; a=rsa-sha256; t=1733328991; cv=none; d=strato.com; s=strato-dkim-0002; b=k9YDTbcktDg8HgxxGPb6N6NS4kkg5NhrBIKAcOEPT/SN1IRdSc04Z3VhJWMy1dn0Tk zG/3Za0VaXioFKu4uTra4FToAo+dz773ikwbkmwXO2+yPWxtu1CUY7YBb2WR/ylxIDpu 2r/2pYHe1h56fa6fjY37m4s/gPaYgq+BD8xYdCqYyhp/Hw+YvH0uy7YO7eWtT9EMYh9P 9hQ4G9UPvtuXx5EvfW2mT9PexRH/BcHxi6wM7g4u+otG3iX+KrLgqBJMVlmAAcY6Fdg0 PdSXHc8MXdFc53+DuO7m+hWv38QGRbCFytRILjngAxbiTYIBzamBlCciyWgkykGyIfOr KNog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1733328991; s=strato-dkim-0002; d=strato.com; h=To:Subject:From:Date:Message-ID:Cc:Date:From:Subject:Sender; bh=V1cs0wypnFRY2zvR536CFc0nxrWyEFg8cz+LOj6V7co=; b=Aenrnf9o0Ffoxv+h9J/iGDG9VeOafy8bQF3qCvZNaPKTaYk1EFsXqzUUPLN6Z5qchq Fwml1zrrtsYxm3mw2nz5q46RjhPRS1mJcVuZUJC49UzVTLbuXrczEpgt8JKj6WsKBSEz JUtitGmPu0Y8f6VREvYasnnUqheaEEsriaViqdtNKNr6TtdjcS7OpYLjUcQz67+XiqsY 1r3xAoHJdy0oqom1tZ3AP5SngnW7oTLsRTXkOoAtIQWEX12KCj1lLwwZLoenfxf8ow+g ZYCx/SiIRexvGCOip6qtxjwmHaTp3b+SkE3ubMqeUKXMY2K0d0WPZXAKWfiXacWcMoG6 vEQg== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo01 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1733328991; s=strato-dkim-0002; d=gjlay.de; h=To:Subject:From:Date:Message-ID:Cc:Date:From:Subject:Sender; bh=V1cs0wypnFRY2zvR536CFc0nxrWyEFg8cz+LOj6V7co=; b=OQPdb8UNn6xTcntDC2nIlV4ga5wpyBa7v8Z2YErY2iipHSYUVbomBDJOYIOB+g55ia 5efnoaScFNcWiC89YDZPQRfaks7VVY/wi5w73NwLTvye2gEDD3s7j9ywVw1KTuAYt0gK aq8X7JZiBiTR8m718SW4G+hWd0BSxm2QXFTSYThMLyXkyLhDwM9nD9oSbMoU+BsEQyFl JcPLfxdfL9Ez3hYvwfOssWXz2UD1ZmppuddhqdZXmgAl/W3WrjVlR4loJHPJOR6MNL3w efi3WvJIsr5AU38i/vnXMTMpQdGdI0l+NZcYWkDnRdBbfXR6bpmHKnpsj/CLpHVzWkU+ ylXA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1733328991; s=strato-dkim-0003; d=gjlay.de; h=To:Subject:From:Date:Message-ID:Cc:Date:From:Subject:Sender; bh=V1cs0wypnFRY2zvR536CFc0nxrWyEFg8cz+LOj6V7co=; b=QWXHbnEMbcTyywvhcrhVe1oaNtexhZGJekb9XeADidGGJuAqGezUmjrxFdNd7q7r2z RGPFlbFgEQhvG28GCbBg== X-RZG-AUTH: ":LXoWVUeid/7A29J/hMvvT3koxZnKXKoq0dKoR0vVqyQb0R7G22gRW+Qr5Q==" Received: from [192.168.2.102] by smtp.strato.de (RZmta 51.2.11 AUTH) with ESMTPSA id xd5faa0B4GGU2dE (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 4 Dec 2024 17:16:30 +0100 (CET) Message-ID: <862dbcda-b9d4-4144-83d3-772473c68adb@gjlay.de> Date: Wed, 4 Dec 2024 17:16:30 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Georg-Johann Lay Subject: [patch,avr] PR107957 - Split multi-byte loads and stores. To: "gcc-patches@gcc.gnu.org" , Denis Chertykov Content-Language: en-US X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This patch splits multi-byte loads and stores into single-byte ones provided: - New option -msplit-ldst is on (e.g. -O2 and higher), and - The memory is non-volatile, and - The address space is generic, and - The split addresses are natively supported by the hardware. Passes without regressions. Ok for trunk? Johann --- AVR: target/107957 - Split multi-byte loads and stores. This patch splits multi-byte loads and stores into single-byte ones provided: - New option -msplit-ldst is on (e.g. -O2 and higher), and - The memory is non-volatile, and - The address space is generic, and - The split addresses are natively supported by the hardware. gcc/ PR target/107957 * config/avr/avr.opt (-msplit-ldst, avropt_split_ldst): New option and associated var. * common/config/avr/avr-common.cc (avr_option_optimization_table) [OPT_LEVELS_2_PLUS]: Turn on -msplit_ldst. * config/avr/avr-passes.cc (splittable_address_p) (avr_byte_maybe_mem, avr_split_ldst): New functions. * config/avr/avr-protos.h (avr_split_ldst): New proto. * config/avr/avr.md (define_split) [avropt_split_ldst]: Run avr_split_ldst(). diff --git a/gcc/common/config/avr/avr-common.cc b/gcc/common/config/avr/avr-common.cc index 7473429fa36..9059e7d2b48 100644 --- a/gcc/common/config/avr/avr-common.cc +++ b/gcc/common/config/avr/avr-common.cc @@ -39,6 +39,7 @@ static const struct default_options avr_option_optimization_table[] = { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_mfuse_move_, NULL, 3 }, { OPT_LEVELS_2_PLUS, OPT_mfuse_move_, NULL, 23 }, { OPT_LEVELS_2_PLUS, OPT_msplit_bit_shift, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_msplit_ldst, NULL, 1 }, // Stick to the "old" placement of the subreg lowering pass. { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types_early, NULL, 1 }, /* Allow optimizer to introduce store data races. This used to be the diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc index 7be5ec25fbc..5ad20c46238 100644 --- a/gcc/config/avr/avr-passes.cc +++ b/gcc/config/avr/avr-passes.cc @@ -5462,6 +5462,112 @@ avr_split_fake_addressing_move (rtx_insn * /*insn*/, rtx *xop) } +/* Given memory reference mem(ADDR), return true when it can be split into + single-byte moves, and all resulting addresses are natively supported. + ADDR is in addr-space generic. */ + +static bool +splittable_address_p (rtx addr, int n_bytes) +{ + if (CONSTANT_ADDRESS_P (addr) + || GET_CODE (addr) == PRE_DEC + || GET_CODE (addr) == POST_INC) + return true; + + if (! AVR_TINY) + { + rtx base = select() + : REG_P (addr) ? addr + : GET_CODE (addr) == PLUS ? XEXP (addr, 0) + : NULL_RTX; + + int off = select() + : REG_P (addr) ? 0 + : GET_CODE (addr) == PLUS ? (int) INTVAL (XEXP (addr, 1)) + : -1; + + return (base && REG_P (base) + && (REGNO (base) == REG_Y || REGNO (base) == REG_Z) + && IN_RANGE (off, 0, 64 - n_bytes)); + } + + return false; +} + + +/* Like avr_byte(), but also knows how to split POST_INC and PRE_DEC + memory references. */ + +static rtx +avr_byte_maybe_mem (rtx x, int n) +{ + rtx addr, b; + if (MEM_P (x) + && (GET_CODE (addr = XEXP (x, 0)) == POST_INC + || GET_CODE (addr) == PRE_DEC)) + b = gen_rtx_MEM (QImode, copy_rtx (addr)); + else + b = avr_byte (x, n); + + if (MEM_P (x)) + gcc_assert (MEM_P (b)); + + return b; +} + + +/* Split multi-byte load / stores into 1-byte such insns + provided non-volatile, addr-space = generic, no reg-overlap + and the resulting addressings are all natively supported. + Returns true when the XOP[0] = XOP[1] insn has been split and + false, otherwise. */ + +bool +avr_split_ldst (rtx *xop) +{ + rtx dest = xop[0]; + rtx src = xop[1]; + machine_mode mode = GET_MODE (dest); + int n_bytes = GET_MODE_SIZE (mode); + rtx mem, reg_or_0; + + if (MEM_P (dest) && reg_or_0_operand (src, mode)) + { + mem = dest; + reg_or_0 = src; + } + else if (register_operand (dest, mode) && MEM_P (src)) + { + reg_or_0 = dest; + mem = src; + } + else + return false; + + rtx addr = XEXP (mem, 0); + + if (MEM_VOLATILE_P (mem) + || ! ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (mem)) + || ! IN_RANGE (n_bytes, 2, 4) + || ! splittable_address_p (addr, n_bytes) + || reg_overlap_mentioned_p (reg_or_0, addr)) + return false; + + const int step = GET_CODE (addr) == PRE_DEC ? -1 : 1; + const int istart = step > 0 ? 0 : n_bytes - 1; + const int iend = istart + step * n_bytes; + + for (int i = istart; i != iend; i += step) + { + rtx di = avr_byte_maybe_mem (dest, i); + rtx si = avr_byte_maybe_mem (src, i); + emit_move_ccc (di, si); + } + + return true; +} + + // Functions make_ (gcc::context*) where is // according to the pass declaration in avr-passes.def. GCC's pass diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 4aa8554000b..5329d29702e 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -173,6 +173,7 @@ extern int n_avr_fuse_add_executed; extern bool avr_shift_is_3op (); extern bool avr_split_shift_p (int n_bytes, int offset, rtx_code); extern bool avr_split_shift (rtx xop[], rtx xscratch, rtx_code); +extern bool avr_split_ldst (rtx xop[]); extern int avr_optimize_size_level (); diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index e343fb23d07..42f41891a90 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -1000,15 +1000,24 @@ (define_split (match_operand:MOVMODE 1 "general_operand")) (clobber (reg:CC REG_CC))])] "reload_completed - && avropt_fuse_add > 0 - // Only split this for .split2 when we are before - // pass .avr-fuse-add (which runs after proep). - && ! epilogue_completed && (MEM_P (operands[0]) || MEM_P (operands[1]))" [(scratch)] { - if (avr_split_fake_addressing_move (curr_insn, operands)) + if (avropt_fuse_add > 0 + // Only split fake addressing for .split2 when we are before + // pass .avr-fuse-add (which runs after proep). + && ! epilogue_completed + && avr_split_fake_addressing_move (curr_insn, operands)) DONE; + + // Splitting multi-byte load / stores into 1-byte such insns + // provided non-volatile, addr-space = generic, no reg-overlap + // and the resulting addressings are natively supported. + if (avropt_split_ldst + && GET_MODE_SIZE (mode) > 1 + && avr_split_ldst (operands)) + DONE; + FAIL; }) diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index 7770c278d40..6c86d2bb42a 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -98,6 +98,10 @@ msplit-bit-shift Target Var(avropt_split_bit_shift) Init(0) Optimization Optimization. Split shifts of 4-byte values into a byte shift and a residual bit shift. +msplit-ldst +Target Var(avropt_split_ldst) Init(0) Optimization +Optimization. Split most of the load and store instructions into byte load and stores. + mstrict-X Target Var(avropt_strict_X) Init(0) Optimization Optimization. When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register. Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X.