From patchwork Thu Mar 2 22:22:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 1751056 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=8.43.85.97; helo=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=WF3DWuKg; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (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 4PSQc54Q4cz23j7 for ; Fri, 3 Mar 2023 09:23:32 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 35266385841A for ; Thu, 2 Mar 2023 22:23:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 35266385841A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1677795810; bh=PRuXb2r81kwUMesaBciwcy4BKjsmhSLGto2g/75agFM=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=WF3DWuKg7pjUt0ng2M+tFovSd24jT2kx0AlLB1HcaG/6aLxKrrB4FP+zO9YtC+JIU K/wSB9P53VjKVI1WDmwGw/nPXc0H5RNzghXuHYK08lAkgl8Ot08YK5oNnbnxVZKggE NakdE68U1neB+o5/eshMqANlQGLU15ao91tu4e3U= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 156D53858D37 for ; Thu, 2 Mar 2023 22:23:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 156D53858D37 Received: from mail-io1-f69.google.com (mail-io1-f69.google.com [209.85.166.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-252-78YhqYgyOLip0ENAC9pkkA-1; Thu, 02 Mar 2023 17:23:01 -0500 X-MC-Unique: 78YhqYgyOLip0ENAC9pkkA-1 Received: by mail-io1-f69.google.com with SMTP id z128-20020a6bc986000000b0074d32ddcce7so295796iof.21 for ; Thu, 02 Mar 2023 14:23:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677795780; 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=NQcLnrCctQGYduizXGNGKYoQWriSbKFLdsNQuSJydm0=; b=Mzo2C7S9QvZQEoP/Q7Ci/aJtL+RstkjOsHB6WjRbm1dbbIxdDX6bFTcpNeW+1oPwGF +dMM/itkXTzmiGwZouQTPZfR2mi3riLVeoXPQhtS5V0hmFebtI/J2xmYpfXz/CiAmhSB NLxzsdBTPafQLItdNxHsJxHzWAB1/9tfk0KjDUuzat8+92ufBq9UYTjXWcbcOKQ+CRKd wAdQ90ori2WuDpTa4Ba+5Y/toBmgAnSJ9bWbCNCAE4OfaSYUlkKoYvYZEpRIZJphg3gb WMHDz42fe1tJR1nvzZkILaiisykhNFexEi8UV3C/5ZOK4L+YMumCEJa5gH5H8VkvfTNA nLKQ== X-Gm-Message-State: AO0yUKWyj94LUQBi282qVQi5Jc42nMlJ8ZjrZNkS/fzWm8fsiq5Ry7BV +4VxNboBvdGju62wJcZXZxyktTBpfSbb69RTp9l1bCPMZIk8isJZx+g4FngkQwg3ZSbdYuds8m1 BNOTUBoFks2F8OESY9kPmJBi3UY1VugBpdMg4GRSCgf4nBjVVo2POGEp1uwxaJonD7JwwP03pyV U= X-Received: by 2002:a05:6e02:1805:b0:316:e6e4:56ff with SMTP id a5-20020a056e02180500b00316e6e456ffmr76872ilv.1.1677795780105; Thu, 02 Mar 2023 14:23:00 -0800 (PST) X-Google-Smtp-Source: AK7set+oOfGV7Ef3ZPYbrgnN1cQ3UmRes07mwSqeZZyWipmF5emw/qasANmqjSJ+EuCsUPT1dmVnbA== X-Received: by 2002:a05:6e02:1805:b0:316:e6e4:56ff with SMTP id a5-20020a056e02180500b00316e6e456ffmr76856ilv.1.1677795779667; Thu, 02 Mar 2023 14:22:59 -0800 (PST) Received: from [192.168.1.104] (192-0-143-139.cpe.teksavvy.com. [192.0.143.139]) by smtp.gmail.com with ESMTPSA id l8-20020a02cd88000000b0038a3b8aaf11sm214470jap.37.2023.03.02.14.22.58 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 02 Mar 2023 14:22:59 -0800 (PST) Message-ID: Date: Thu, 2 Mar 2023 17:22:57 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0 To: "gcc-patches@gcc.gnu.org" Subject: [pushed][PR90706] IRA: Use minimal cost for hard register movement X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-12.1 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_H2, SPF_HELO_NONE, SPF_NONE, TXREP 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 for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90706 The patch was successfully bootstrapped and tested on i686, x86-64, aarch64, ppc64le. commit 23661e39df76e07fb4ce1ea015379c7601d947ef Author: Vladimir N. Makarov Date: Thu Mar 2 16:29:05 2023 -0500 IRA: Use minimal cost for hard register movement This is the 2nd attempt to fix PR90706. IRA calculates wrong AVR costs for moving general hard regs of SFmode. This was the reason for spilling a pseudo in the PR. In this patch we use smaller move cost of hard reg in its natural and operand modes. PR rtl-optimization/90706 gcc/ChangeLog: * ira-costs.cc: Include print-rtl.h. (record_reg_classes, scan_one_insn): Add code to print debug info. (record_operand_costs): Find and use smaller cost for hard reg move. gcc/testsuite/ChangeLog: * gcc.target/avr/pr90706.c: New. diff --git a/gcc/ira-costs.cc b/gcc/ira-costs.cc index 4c28171f27d..c0fdef807dd 100644 --- a/gcc/ira-costs.cc +++ b/gcc/ira-costs.cc @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "ira-int.h" #include "addresses.h" #include "reload.h" +#include "print-rtl.h" /* The flags is set up every time when we calculate pseudo register classes through function ira_set_pseudo_classes. */ @@ -503,6 +504,18 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, int insn_allows_mem[MAX_RECOG_OPERANDS]; move_table *move_in_cost, *move_out_cost; short (*mem_cost)[2]; + const char *p; + + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5) + { + fprintf (ira_dump_file, " Processing insn %u", INSN_UID (insn)); + if (INSN_CODE (insn) >= 0 + && (p = get_insn_name (INSN_CODE (insn))) != NULL) + fprintf (ira_dump_file, " {%s}", p); + fprintf (ira_dump_file, " (freq=%d)\n", + REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn))); + dump_insn_slim (ira_dump_file, insn); + } for (i = 0; i < n_ops; i++) insn_allows_mem[i] = 0; @@ -526,6 +539,21 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, continue; } + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5) + { + fprintf (ira_dump_file, " Alt %d:", alt); + for (i = 0; i < n_ops; i++) + { + p = constraints[i]; + if (*p == '\0') + continue; + fprintf (ira_dump_file, " (%d) ", i); + for (; *p != '\0' && *p != ',' && *p != '#'; p++) + fputc (*p, ira_dump_file); + } + fprintf (ira_dump_file, "\n"); + } + for (i = 0; i < n_ops; i++) { unsigned char c; @@ -593,12 +621,16 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, register, this alternative can't be used. */ if (classes[j] == NO_REGS) - alt_fail = 1; - /* Otherwise, add to the cost of this alternative - the cost to copy the other operand to the hard - register used for this operand. */ + { + alt_fail = 1; + } else - alt_cost += copy_cost (ops[j], mode, classes[j], 1, NULL); + /* Otherwise, add to the cost of this alternative the cost + to copy the other operand to the hard register used for + this operand. */ + { + alt_cost += copy_cost (ops[j], mode, classes[j], 1, NULL); + } } else { @@ -1021,18 +1053,45 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, for (i = 0; i < n_ops; i++) if (REG_P (ops[i]) && REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER) { + int old_cost; + bool cost_change_p = false; struct costs *pp = op_costs[i], *qq = this_op_costs[i]; int *pp_costs = pp->cost, *qq_costs = qq->cost; int scale = 1 + (recog_data.operand_type[i] == OP_INOUT); cost_classes_t cost_classes_ptr = regno_cost_classes[REGNO (ops[i])]; - pp->mem_cost = MIN (pp->mem_cost, + old_cost = pp->mem_cost; + pp->mem_cost = MIN (old_cost, (qq->mem_cost + op_cost_add) * scale); + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5 + && pp->mem_cost < old_cost) + { + cost_change_p = true; + fprintf (ira_dump_file, " op %d(r=%u) new costs MEM:%d", + i, REGNO(ops[i]), pp->mem_cost); + } for (k = cost_classes_ptr->num - 1; k >= 0; k--) - pp_costs[k] - = MIN (pp_costs[k], (qq_costs[k] + op_cost_add) * scale); + { + old_cost = pp_costs[k]; + pp_costs[k] + = MIN (old_cost, (qq_costs[k] + op_cost_add) * scale); + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5 + && pp_costs[k] < old_cost) + { + if (!cost_change_p) + fprintf (ira_dump_file, " op %d(r=%u) new costs", + i, REGNO(ops[i])); + cost_change_p = true; + fprintf (ira_dump_file, " %s:%d", + reg_class_names[cost_classes_ptr->classes[k]], + pp_costs[k]); + } + } + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5 + && cost_change_p) + fprintf (ira_dump_file, "\n"); } } @@ -1307,26 +1366,48 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref) || ((regno = REGNO (dest)) >= FIRST_PSEUDO_REGISTER && (other_regno = REGNO (src)) < FIRST_PSEUDO_REGISTER))) { - machine_mode mode = GET_MODE (SET_SRC (set)); + machine_mode mode = GET_MODE (SET_SRC (set)), cost_mode = mode; + machine_mode hard_reg_mode = GET_MODE(regno_reg_rtx[other_regno]); + poly_int64 pmode_size = GET_MODE_SIZE (mode); + poly_int64 phard_reg_mode_size = GET_MODE_SIZE (hard_reg_mode); + HOST_WIDE_INT mode_size, hard_reg_mode_size; cost_classes_t cost_classes_ptr = regno_cost_classes[regno]; enum reg_class *cost_classes = cost_classes_ptr->classes; reg_class_t rclass, hard_reg_class, bigger_hard_reg_class; - int cost, k; + int cost_factor = 1, cost, k; move_table *move_costs; bool dead_p = find_regno_note (insn, REG_DEAD, REGNO (src)); - ira_init_register_move_cost_if_necessary (mode); - move_costs = ira_register_move_cost[mode]; hard_reg_class = REGNO_REG_CLASS (other_regno); - bigger_hard_reg_class = ira_pressure_class_translate[hard_reg_class]; - /* Target code may return any cost for mode which does not - fit the hard reg class (e.g. DImode for AREG on - i386). Check this and use a bigger class to get the - right cost. */ - if (bigger_hard_reg_class != NO_REGS - && ! ira_hard_reg_in_set_p (other_regno, mode, - reg_class_contents[hard_reg_class])) - hard_reg_class = bigger_hard_reg_class; + bigger_hard_reg_class = ira_pressure_class_translate[hard_reg_class]; + /* Target code may return any cost for mode which does not fit the + hard reg class (e.g. DImode for AREG on i386). Check this and use + a bigger class to get the right cost. */ + if (bigger_hard_reg_class != NO_REGS + && ! ira_hard_reg_in_set_p (other_regno, mode, + reg_class_contents[hard_reg_class])) + hard_reg_class = bigger_hard_reg_class; + ira_init_register_move_cost_if_necessary (mode); + ira_init_register_move_cost_if_necessary (hard_reg_mode); + /* Use smaller movement cost for natural hard reg mode or its mode as + operand. */ + if (pmode_size.is_constant (&mode_size) + && phard_reg_mode_size.is_constant (&hard_reg_mode_size)) + { + /* Assume we are moving in the natural modes: */ + cost_factor = mode_size / hard_reg_mode_size; + if (mode_size % hard_reg_mode_size != 0) + cost_factor++; + if (cost_factor + * (ira_register_move_cost + [hard_reg_mode][hard_reg_class][hard_reg_class]) + < (ira_register_move_cost + [mode][hard_reg_class][hard_reg_class])) + cost_mode = hard_reg_mode; + else + cost_factor = 1; + } + move_costs = ira_register_move_cost[cost_mode]; i = regno == (int) REGNO (src) ? 1 : 0; for (k = cost_classes_ptr->num - 1; k >= 0; k--) { @@ -1334,7 +1415,7 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref) cost = (i == 0 ? move_costs[hard_reg_class][rclass] : move_costs[rclass][hard_reg_class]); - + cost *= cost_factor; op_costs[i]->cost[k] = cost * frequency; /* If this insn is a single set copying operand 1 to operand 0 and one operand is an allocno with the @@ -1506,12 +1587,24 @@ scan_one_insn (rtx_insn *insn) record_operand_costs (insn, pref); + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5) + { + const char *p; + fprintf (ira_dump_file, " Final costs after insn %u", INSN_UID (insn)); + if (INSN_CODE (insn) >= 0 + && (p = get_insn_name (INSN_CODE (insn))) != NULL) + fprintf (ira_dump_file, " {%s}", p); + fprintf (ira_dump_file, " (freq=%d)\n", + REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn))); + dump_insn_slim (ira_dump_file, insn); + } + /* Now add the cost for each operand to the total costs for its allocno. */ for (i = 0; i < recog_data.n_operands; i++) { rtx op = recog_data.operand[i]; - + if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER) @@ -1521,8 +1614,8 @@ scan_one_insn (rtx_insn *insn) struct costs *q = op_costs[i]; int *p_costs = p->cost, *q_costs = q->cost; cost_classes_t cost_classes_ptr = regno_cost_classes[regno]; - int add_cost; - + int add_cost = 0; + /* If the already accounted for the memory "cost" above, don't do so again. */ if (!counted_mem) @@ -1533,6 +1626,11 @@ scan_one_insn (rtx_insn *insn) else p->mem_cost += add_cost; } + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5) + { + fprintf (ira_dump_file, " op %d(r=%u) MEM:%d(+%d)", + i, REGNO(op), p->mem_cost, add_cost); + } for (k = cost_classes_ptr->num - 1; k >= 0; k--) { add_cost = q_costs[k]; @@ -1540,7 +1638,15 @@ scan_one_insn (rtx_insn *insn) p_costs[k] = INT_MAX; else p_costs[k] += add_cost; + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5) + { + fprintf (ira_dump_file, " %s:%d(+%d)", + reg_class_names[cost_classes_ptr->classes[k]], + p_costs[k], add_cost); + } } + if (ira_dump_file != NULL && internal_flag_ira_verbose > 5) + fprintf (ira_dump_file, "\n"); } } return insn; diff --git a/gcc/testsuite/gcc.target/avr/pr90706.c b/gcc/testsuite/gcc.target/avr/pr90706.c new file mode 100644 index 00000000000..4b9bcbe1152 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr90706.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +unsigned char check(float x) +{ + return (0.0 < x); +} + /* { dg-final { scan-assembler-not "ldd" } } */ + /* { dg-final { scan-assembler-not "std" } } */