From patchwork Wed Jul 19 17:59:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 1809983 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=yiyyKJ3T; dkim-atps=neutral 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 (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R5k9V0KDcz1yY1 for ; Thu, 20 Jul 2023 03:59:39 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 32C32385773C for ; Wed, 19 Jul 2023 17:59:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 32C32385773C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1689789577; bh=8ZLb0IMaEakyOG4zUFChN9QjyfgGRiDzv0oq+yCBCmc=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=yiyyKJ3TG/GFNDqkewQBhb495IcO/bojrGn7J2niaqC/MQbW8a4AUWxJ0Iwx4s/kv 52sg8GL42jPpquvwgEPiBRP+JDOA9B0Xkfzz6ose47PuwqCaUt4/dVWC0PBcmv8hCv NdqpKbgzkT4jwv6cRsE4oddNIj0uIcKlpoJh+Lzo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 86DCE3858436 for ; Wed, 19 Jul 2023 17:59:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 86DCE3858436 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-307-ZmVdIEQWMfemvGMhHRfCMA-1; Wed, 19 Jul 2023 13:59:11 -0400 X-MC-Unique: ZmVdIEQWMfemvGMhHRfCMA-1 Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-403c7ffd25eso77584311cf.2 for ; Wed, 19 Jul 2023 10:59:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689789550; x=1692381550; h=subject:from:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=8qrhnZY1/ml+qzmg64OqD3c38AjvoX65lyvmhVLEhi4=; b=f0XYD6j13VGsFPRoIROrzyCgY1zOjFTTja6N35G+1SkhQFNrtyGKTQbJXC3WB0al1w AHxRbFA+vxkkcRBEljr/2ND7wRcqwL/tDTefvC7d7ETJ4PbmTtU/oYJMJA+1untENfmE t2RhXcQxXl6xELSdntvP0qJNr25RPmpaCS9pbk7B6YCSXv7vdcb+O8uiWkIkJBn/ZLdl DYGFKZQOvyvT35Nw0022Rd7NTEZRPKHlvtbdCUoq7uwv+CdhHNIrThnscOB1zTd4lPAO dSLbmcY0gsxnH8iXVwSJHrkR7cagq1cONOZvd2JdMObwK/359HS2p28u8ZWIFadAIbSb 90GQ== X-Gm-Message-State: ABy/qLZsVnhKAYldHjzy3zwGWs9cgxcnUfWRi8Z5LQxfMYZhF0ucl8T8 IJt0oITlGmNP55vsxEI2Gx7drRwUGOq/hh2fnxCEdFY6KPLTn+8rkq9otSniDIlAydosDDZbP1A Q6Rn5bd7mOa6O5p9jXNnbPJ3iMxJaHtWKLXXHkswl7KRTK311umfoC2kPz4jQgfjwep2CcdXN2I jPMQ== X-Received: by 2002:ac8:5ccf:0:b0:403:fee8:7fdc with SMTP id s15-20020ac85ccf000000b00403fee87fdcmr4139983qta.39.1689789550209; Wed, 19 Jul 2023 10:59:10 -0700 (PDT) X-Google-Smtp-Source: APBJJlFK9tZyS0mQFTpfE07Ka3IlEg1LQUlBovBMAKHeG/KxQ/DaHiE12WFcQq09uWgzd+JghGJSHA== X-Received: by 2002:ac8:5ccf:0:b0:403:fee8:7fdc with SMTP id s15-20020ac85ccf000000b00403fee87fdcmr4139967qta.39.1689789549910; Wed, 19 Jul 2023 10:59:09 -0700 (PDT) Received: from [192.168.1.88] (192-0-143-139.cpe.teksavvy.com. [192.0.143.139]) by smtp.gmail.com with ESMTPSA id a13-20020ac84d8d000000b004039e9199cesm1474767qtw.60.2023.07.19.10.59.08 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 19 Jul 2023 10:59:09 -0700 (PDT) Message-ID: <10df283b-93c8-1d05-fa8a-11c5b256f943@redhat.com> Date: Wed, 19 Jul 2023 13:59:04 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 To: "gcc-patches@gcc.gnu.org" , SenthilKumar.Selvaraj@microchip.com Subject: [pushed][LRA]: Check and update frame to stack pointer elimination after stack slot allocation X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Vladimir Makarov via Gcc-patches From: Vladimir Makarov Reply-To: Vladimir Makarov Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" The following patch is necessary for porting avr to LRA. The patch was successfully bootstrapped and tested on x86-64, aarch64, and ppc64le. There is still avr poring problem with reloading of subreg of frame pointer.  I'll address it later on this week. commit 2971ff7b1d564ac04b537d907c70e6093af70832 Author: Vladimir N. Makarov Date: Wed Jul 19 09:35:37 2023 -0400 [LRA]: Check and update frame to stack pointer elimination after stack slot allocation Avr is an interesting target which does not use stack pointer to address stack slots. The elimination of stack pointer to frame pointer is impossible if there are stack slots. During LRA works, the stack slots can be allocated and used and the elimination can be done anymore. The situation can be complicated even more if some pseudos were allocated to the frame pointer. gcc/ChangeLog: * lra-int.h (lra_update_fp2sp_elimination): New prototype. (lra_asm_insn_error): New prototype. * lra-spills.cc (remove_pseudos): Add check for pseudo slot memory existence. (lra_spill): Call lra_update_fp2sp_elimination. * lra-eliminations.cc: Remove trailing spaces. (elimination_fp2sp_occured_p): New static flag. (lra_eliminate_regs_1): Set the flag up. (update_reg_eliminate): Modify the assert for stack to frame pointer elimination. (lra_update_fp2sp_elimination): New function. (lra_eliminate): Clear flag elimination_fp2sp_occured_p. gcc/testsuite/ChangeLog: * gcc.target/avr/lra-elim.c: New test. diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index 68225339cb6..cf0aa94b69a 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -286,7 +286,7 @@ move_plus_up (rtx x) { rtx subreg_reg; machine_mode x_mode, subreg_reg_mode; - + if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x)) return x; subreg_reg = SUBREG_REG (x); @@ -309,6 +309,9 @@ move_plus_up (rtx x) return x; } +/* Flag that we already did frame pointer to stack pointer elimination. */ +static bool elimination_fp2sp_occured_p = false; + /* Scan X and replace any eliminable registers (such as fp) with a replacement (such as sp) if SUBST_P, plus an offset. The offset is a change in the offset between the eliminable register and its @@ -366,6 +369,9 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, { rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) + elimination_fp2sp_occured_p = true; + if (maybe_ne (update_sp_offset, 0)) { if (ep->to_rtx == stack_pointer_rtx) @@ -396,9 +402,12 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, poly_int64 offset, curr_offset; rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) + elimination_fp2sp_occured_p = true; + if (! update_p && ! full_p) return gen_rtx_PLUS (Pmode, to, XEXP (x, 1)); - + if (maybe_ne (update_sp_offset, 0)) offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0; else @@ -456,6 +465,9 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, { rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) + elimination_fp2sp_occured_p = true; + if (maybe_ne (update_sp_offset, 0)) { if (ep->to_rtx == stack_pointer_rtx) @@ -500,7 +512,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, case LE: case LT: case LEU: case LTU: { rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, - subst_p, update_p, + subst_p, update_p, update_sp_offset, full_p); rtx new1 = XEXP (x, 1) ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, @@ -749,7 +761,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset)))) { poly_int64 size = GET_MODE_SIZE (mem_mode); - + #ifdef PUSH_ROUNDING /* If more bytes than MEM_MODE are pushed, account for them. */ @@ -822,7 +834,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) { /* See if this is setting the replacement hard register for an elimination. - + If DEST is the hard frame pointer, we do nothing because we assume that all assignments to the frame pointer are for non-local gotos and are being done at a time when @@ -838,7 +850,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) && SET_DEST (x) != hard_frame_pointer_rtx) setup_can_eliminate (ep, false); } - + mark_not_eliminable (SET_SRC (x), mem_mode); return; @@ -1047,7 +1059,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS) { rtx reg1, reg2, op1, op2; - + reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0); reg2 = op2 = XEXP (SET_SRC (set), 1); if (GET_CODE (reg1) == SUBREG) @@ -1160,11 +1172,17 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) fprintf (lra_dump_file, " Elimination %d to %d is not possible anymore\n", ep->from, ep->to); - /* If after processing RTL we decides that SP can be used as - a result of elimination, it cannot be changed. */ - gcc_assert ((ep->to_rtx != stack_pointer_rtx) - || (ep->from < FIRST_PSEUDO_REGISTER + /* If after processing RTL we decides that SP can be used as a result + of elimination, it cannot be changed. For frame pointer to stack + pointer elimination the condition is a bit relaxed and we just require + that actual elimination has not been done yet. */ + gcc_assert (ep->to_rtx != stack_pointer_rtx + || (ep->from == FRAME_POINTER_REGNUM + && !elimination_fp2sp_occured_p) + || (ep->from != FRAME_POINTER_REGNUM + && ep->from < FIRST_PSEUDO_REGISTER && fixed_regs [ep->from])); + /* Mark that is not eliminable anymore. */ elimination_map[ep->from] = NULL; for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++) @@ -1363,6 +1381,30 @@ process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p) } } +/* Update frame pointer to stack pointer elimination if we started with + permitted frame pointer elimination and now target reports that we can not + do this elimination anymore. */ +void +lra_update_fp2sp_elimination (void) +{ + HARD_REG_SET set; + class lra_elim_table *ep; + + if (frame_pointer_needed || !targetm.frame_pointer_required ()) + return; + gcc_assert (!elimination_fp2sp_occured_p); + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + " Frame pointer can not be eliminated anymore\n"); + frame_pointer_needed = true; + CLEAR_HARD_REG_SET (set); + add_to_hard_reg_set (&set, Pmode, FRAME_POINTER_REGNUM); + spill_pseudos (set); + for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) + if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) + setup_can_eliminate (ep, false); +} + /* Entry function to do final elimination if FINAL_P or to update elimination register offsets (FIRST_P if we are doing it the first time). */ @@ -1379,7 +1421,10 @@ lra_eliminate (bool final_p, bool first_p) timevar_push (TV_LRA_ELIMINATE); if (first_p) - init_elimination (); + { + elimination_fp2sp_occured_p = false; + init_elimination (); + } bitmap_initialize (&insns_with_changed_offsets, ®_obstack); if (final_p) diff --git a/gcc/lra-int.h b/gcc/lra-int.h index a32359e5772..633d9af8058 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -414,6 +414,7 @@ extern int lra_get_elimination_hard_regno (int); extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode, bool, bool, poly_int64, bool); extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64); +extern void lra_update_fp2sp_elimination (void); extern void lra_eliminate (bool, bool); extern poly_int64 lra_update_sp_offset (rtx, poly_int64); diff --git a/gcc/lra-spills.cc b/gcc/lra-spills.cc index 4af85c49d43..3a7bb7e8cd9 100644 --- a/gcc/lra-spills.cc +++ b/gcc/lra-spills.cc @@ -453,7 +453,10 @@ remove_pseudos (rtx *loc, rtx_insn *insn) return true; if ((hard_reg = spill_hard_reg[i]) != NULL_RTX) *loc = copy_rtx (hard_reg); - else + else if (pseudo_slots[i].mem != NULL_RTX) + /* There might be no memory slot or hard reg for a pseudo when we spill + the frame pointer after elimination of frame pointer to stack + pointer became impossible. */ { rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem, GET_MODE (pseudo_slots[i].mem), @@ -629,6 +632,7 @@ lra_spill (void) for (i = 0; i < n; i++) if (pseudo_slots[pseudo_regnos[i]].mem == NULL_RTX) assign_mem_slot (pseudo_regnos[i]); + lra_update_fp2sp_elimination (); if (n > 0 && crtl->stack_alignment_needed) /* If we have a stack frame, we must align it now. The stack size may be a part of the offset computation for register diff --git a/gcc/testsuite/gcc.target/avr/lra-elim.c b/gcc/testsuite/gcc.target/avr/lra-elim.c new file mode 100644 index 00000000000..d5086a7fd5d --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/lra-elim.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mmcu=avr25 -Os" } */ + +typedef int HItype __attribute__ ((mode (HI))); +HItype +__mulvhi3 (HItype a, HItype b) +{ + HItype w; + + if (__builtin_mul_overflow (a, b, &w)) + __builtin_trap (); + + return w; +}