From patchwork Tue Jan 19 11:47:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jesper_Broge_J=C3=B8rgensen?= X-Patchwork-Id: 569936 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7CDAD1402B4 for ; Tue, 19 Jan 2016 22:47:36 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=l8KMtYBG; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type:content-transfer-encoding; q=dns; s= default; b=cFGowdpJB71709sjSGDzWgJehOFXR0Q3B/6PNzbZIY6kxbLLswdOM aRithfYhSxMfpDG1HvvBJ8nUEIxjbVtQ6j3uwnd7yEHGPhXcI+unwSiramz4LPOl bCvlf2g8DSyAWb/LU2rkng4wSYlA5OJlHV7Sz05oYYrOSYzHQi5Xl0= 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 :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type:content-transfer-encoding; s=default; bh=nsxenbPuIxyWdqcivhksfzocbXI=; b=l8KMtYBGX2I07b40iT5wBj3z6xK9 0k243YwqK+6CoDhjxpJrDWoBv6QpisilwMMlsNJQmKlw2i3Z/jufCJcSAPzTg9qn 4CbxiARTog/RLbAHluM7SHOY1KgtbUisAWy0dMNuZj2VnwQIzhzTTh+HInQ9xVKI DbOIg8IuZ5Ykp28= Received: (qmail 38825 invoked by alias); 19 Jan 2016 11:47:27 -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 38809 invoked by uid 89); 19 Jan 2016 11:47:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=attr, sk:write_a, HContent-Transfer-Encoding:8bit X-HELO: mail-wm0-f49.google.com Received: from mail-wm0-f49.google.com (HELO mail-wm0-f49.google.com) (74.125.82.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 19 Jan 2016 11:47:25 +0000 Received: by mail-wm0-f49.google.com with SMTP id u188so139767012wmu.1 for ; Tue, 19 Jan 2016 03:47:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:date:from:user-agent:mime-version:to :cc:subject:references:in-reply-to:content-type :content-transfer-encoding; bh=bjtMuz0z/xVTd1kDAlzpSwjnnBgH8NF+x69HDXTToTE=; b=FHbmI1eJs56bWcalUCBeMUxKlhWNQBbzR2zwSrmohRncs4Jv0kyhseQu5PcQP9qlcj WffFB21cJgq4tdOA7Vz8QSx7LaJIIoQH3E9ENqf1+IPl6n7bL+2cuGPiiJt0Mj0AsmjI iTqgcmihNQSunzOgbN87IA2rRPQ257/FAvFEmDTUisGKkuODpce9nPi0aGLxKm/O2xhz WPByHNmslPy3+xLSmCPqJOQSdySHvDadsTJrOBCsOtjBt37pDJZeWmBr9Oa9InSEwhoD I1Vgwfiesb1jFvL8VfK/ubpHIa9juEfm5VvULZIfOMAuO6IQr97T19nnjmU1MyxwML+a +PrA== X-Gm-Message-State: ALoCoQnUF2gvhgFAwEnazwOk1kn3sPqAx6SELdV/wXSeKfgYG8WQ4S8l+4xK0fZM/LBRWMElDrC1ARDnUzrTiYD3ZN2QAj2MdA== X-Received: by 10.194.71.172 with SMTP id w12mr29299583wju.77.1453204041914; Tue, 19 Jan 2016 03:47:21 -0800 (PST) Received: from Jespers-MacBook-Pro.local ([178.157.250.117]) by smtp.googlemail.com with ESMTPSA id e9sm28172177wjp.18.2016.01.19.03.47.20 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 19 Jan 2016 03:47:21 -0800 (PST) Message-ID: <569E2248.9040605@gmail.com> Date: Tue, 19 Jan 2016 12:47:20 +0100 From: =?UTF-8?B?SmVzcGVyIEJyb2dlIErDuHJnZW5zZW4=?= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Richard Biener , Jeff Law CC: GCC Patches Subject: Re: [PING] genattrab.c generate switch References: <569CF21F.5020603@gmail.com> <569D3372.9050607@redhat.com> In-Reply-To: On 19/01/16 10:44, Richard Biener wrote: > On Mon, Jan 18, 2016 at 7:48 PM, Jeff Law wrote: >> On 01/18/2016 07:09 AM, Jesper Broge Jørgensen wrote: >>> Ping patch: >>> >>> https://gcc.gnu.org/ml/gcc-patches/2016-01/msg00784.html >> I'd put it in my gcc-7 queue. But if Richard, Bernd, Richi or someone else >> wants to work though the changes as a bugfix for bootstrapping on platforms >> with crippled compilers, I won't object. > I'd take it as a bugfix but the patch still needs review. > > Richard. > >> jeff Here is the reformatted patch: gcc/ChangeLog: 2016-01-19 Jesper Broge Jørgensen * genattrtab.c (check_attr_set_switch): New function (write_attr_set): Write a switch instead of if condition, if possible tests and sets of an attribute value. We are passed an indentation amount and prefix and suffix strings to write around each attribute value (e.g., "return" @@ -4123,6 +4220,7 @@ write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value, const char *prefix, const char *suffix, rtx known_true, int insn_code, int insn_index, unsigned int attrs_cached) { + int n_switches = 0; if (GET_CODE (value) == COND) { /* Assume the default value will be the default of the COND unless we @@ -4132,6 +4230,7 @@ write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value, rtx newexp; int first_if = 1; int i; + int is_switch = 0; if (cached_attr_count) { @@ -4176,40 +4275,68 @@ write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value, if (inner_true == false_rtx) continue; + is_switch = check_attr_set_switch (outf, testexp, attrs_cached, 0, + indent); + attrs_cached_inside = attrs_cached; attrs_cached_after = attrs_cached; write_indent (outf, indent); - fprintf (outf, "%sif ", first_if ? "" : "else "); - first_if = 0; - write_test_expr (outf, testexp, attrs_cached, - (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND)); - attrs_cached = attrs_cached_after; - fprintf (outf, "\n"); - write_indent (outf, indent + 2); - fprintf (outf, "{\n"); + if (is_switch) + { + fprintf (outf, "switch "); + n_switches++; + first_if = 1; + check_attr_set_switch (outf, testexp, attrs_cached, 1, indent); + indent += 4; + } + else + { + fprintf (outf, "%sif ", first_if ? "" : "else "); + first_if = 0; + write_test_expr (outf, testexp, attrs_cached, + (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND)); + attrs_cached = attrs_cached_after; + fprintf (outf, "\n"); + } + if (!is_switch) + { + write_indent (outf, indent + 2); + fprintf (outf, "{\n"); + } + write_attr_set (outf, attr, indent + 4, XVECEXP (value, 0, i + 1), prefix, suffix, inner_true, insn_code, insn_index, attrs_cached_inside); write_indent (outf, indent + 2); - fprintf (outf, "}\n"); + if (is_switch) + { + fprintf (outf, "break;\n"); + write_indent (outf, indent); + fprintf (outf, "default:\n"); + indent += 4; + } + else + fprintf (outf, "}\n"); our_known_true = newexp; } - if (! first_if) + if (! first_if && ! is_switch) { write_indent (outf, indent); fprintf (outf, "else\n"); write_indent (outf, indent + 2); fprintf (outf, "{\n"); } + else if (is_switch) + write_indent (outf, indent); - write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val, + write_attr_set (outf, attr, (first_if || is_switch) ? indent : indent + 4, default_val, prefix, suffix, our_known_true, insn_code, insn_index, attrs_cached); - if (! first_if) + if (! first_if && ! is_switch) { write_indent (outf, indent + 2); fprintf (outf, "}\n"); @@ -4222,6 +4349,12 @@ write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value, write_attr_value (outf, attr, value); fprintf (outf, "%s\n", suffix); } + while (n_switches--) + { + indent -= 2; + write_indent (outf, indent); + fprintf (outf, "}\n"); + } } /* Write a series of case statements for every instruction in list IE. diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 2caf8f6..8e7f9e6 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -4113,6 +4113,103 @@ eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index) return exp; } +/* Check if exp contains a series of IOR conditions on the same attr_name. + If it does it can be turned into a switch statement and returns true. + If write_cases is true it will write the cases of the switch to outf. */ + +static int +check_attr_set_switch (FILE *outf, rtx exp, unsigned int attrs_cached, + int write_cases, int indent) +{ + if (GET_CODE (exp) != IOR) + return 0; + if (GET_CODE (XEXP (exp, 0)) != EQ_ATTR) + return 0; + + rtx next = exp; + int ior_depth = 0; + int is_first = 1; + + const char *attr_name_cmp = XSTR (XEXP (exp, 0), 0); + + while (1) + { + rtx op1 = XEXP (next, 0); + rtx op2 = XEXP (next, 1); + + if (GET_CODE (op1) != EQ_ATTR) + return 0; + + const char *attr_name = XSTR (op1, 0); + const char *cmp_val = XSTR (op1, 1); + + /* pointer compare is enough. */ + if (attr_name_cmp != attr_name) + return 0; + + if (write_cases) + { + struct attr_desc *attr = find_attr (&attr_name, 0); + gcc_assert (attr); + if (is_first) + { + fprintf (outf, "("); + is_first = 0; + int i; + for (i = 0; i < cached_attr_count; i++) + if (attr->name == cached_attrs[i]) + break; + + if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0) + fprintf (outf, "cached_%s", attr->name); + else if (i < cached_attr_count && + (attrs_to_cache & (1U << i)) != 0) + fprintf (outf, "(cached_%s = get_attr_%s (insn))", attr->name, + attr->name); + else + fprintf (outf, "get_attr_%s (insn)", attr->name); + fprintf (outf, ")\n"); + write_indent (outf, indent); + fprintf (outf, "{\n"); + } + write_indent (outf, indent); + fprintf (outf, "case "); + write_attr_valueq (outf, attr, cmp_val); + fprintf (outf, ":\n"); + } + + const int code = GET_CODE (op2); + if (code != IOR) + { + if (code == EQ_ATTR) + { + const char *attr_name = XSTR (op2, 0); + const char *cmp_val = XSTR (op2, 1); + + if (attr_name == alternative_name) + return 0; + + struct attr_desc *attr = find_attr (&attr_name, 0); + gcc_assert (attr); + + if (attr->is_const) + return 0; + else if (write_cases) + { + write_indent (outf, indent); + fprintf (outf, "case "); + write_attr_valueq (outf, attr, cmp_val); + fprintf (outf, ":\n"); + } + } + break; + } + next = op2; + ior_depth++; + } + return ior_depth > 2; +} + /* Write out a series of tests and assignment statements to perform