From patchwork Thu Nov 24 00:58:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christopher Li X-Patchwork-Id: 9444603 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B006860778 for ; Thu, 24 Nov 2016 00:58:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A0BD2208E3 for ; Thu, 24 Nov 2016 00:58:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 935B227DCD; Thu, 24 Nov 2016 00:58:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_TVD_MIME_EPI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B8F3125D9E for ; Thu, 24 Nov 2016 00:58:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935421AbcKXA6k (ORCPT ); Wed, 23 Nov 2016 19:58:40 -0500 Received: from mail-io0-f194.google.com ([209.85.223.194]:33798 "EHLO mail-io0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935323AbcKXA6k (ORCPT ); Wed, 23 Nov 2016 19:58:40 -0500 Received: by mail-io0-f194.google.com with SMTP id r94so3468462ioe.1 for ; Wed, 23 Nov 2016 16:58:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=gIIF46+Af0D2tnlFj0LVFPvgJEPO5r737rKfhsBzHAQ=; b=fkj5HSmmUcqkMPlyjo7zJnYWoFVUYd8jEHLnrm0YBkkv+fzQolqvHRs0ONHpuX6KqK vx9HUJaSzIcojSlV3R44SfXK6W4zGqsGlYJV6Q+7rb5Yw4Hg9PNPm1zxiNZpFlyFi3MR fpu37sec44cizcH+CW1mENX728hrhyEVeyrHLdgr9rtKxJ8o84XYF2CGMVUVcArPPA/b jMMxTNURf/EBJCO7XRIoMW+luQX5usQgdafA08yCvaOXfNMXYKOhOB/f55Zi+ffsp6P9 4RupDyeVhONfw4teIAnK7yON2/ETo7VrYIjk0nsRU5P3GC7hZxHu91IbPwRSQhYVPFK8 fsMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=gIIF46+Af0D2tnlFj0LVFPvgJEPO5r737rKfhsBzHAQ=; b=ByOVgEUpPKt445QR2Rhh6kkZP2DbepWKs/28AkF4P3bfZSiBo4olQLwt6qmoZuMz2Q AplwZly6067zsRO5WHMD4hvqjMzjoaAMtlvRfwGiWQmwhGAipOsdUJ2e7nkCyaDKPz7u DbLnSxdIzLOFrz/TqYJnJnCfPZgRdktxMIv9qwTbldsOmngfMnhfx97TrY55QY30zOR9 9DHWlB1jNZgB7wMhlG0tdnVeg8zLvoWxPKqqY6LPEoX7L+gOtvkSghtYfgv40//tyRME TOgFYR8Gz8WMnUKZzwLmfpn6hzZu471Dn79XrpW6m4VWSl5qaeBp3uIsum5qSBEFiwYA o9zg== X-Gm-Message-State: AKaTC017WW6+sywX73PRuPDuNprq+g9nqdRh+Eeryz4ziUhtnn8oTET6FOMHyxj0DbL9oVViHoKJoOpxHXQccQ== X-Received: by 10.36.14.84 with SMTP id 81mr8664133ite.54.1479949116734; Wed, 23 Nov 2016 16:58:36 -0800 (PST) MIME-Version: 1.0 Received: by 10.36.209.68 with HTTP; Wed, 23 Nov 2016 16:58:35 -0800 (PST) In-Reply-To: References: <20161117095503.8754-1-johannes@sipsolutions.net> <1479721551.8662.10.camel@sipsolutions.net> <20161122131543.GA8370@macbook.local> <20161122201650.GA12172@macpro.local> <20161123204838.GA14875@macpro.local> From: Christopher Li Date: Thu, 24 Nov 2016 08:58:35 +0800 X-Google-Sender-Auth: KH_WGlVGbuL9PmrhA642pQIjSvI Message-ID: Subject: Re: [PATCH v2] implement constant-folding in __builtin_bswap*() To: Luc Van Oostenryck Cc: Johannes Berg , Linux-Sparse , Nicolai Stange Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Err, forget to attach. Here is the still buggy V2 patch. Chris On Thu, Nov 24, 2016 at 8:56 AM, Christopher Li wrote: > On Thu, Nov 24, 2016 at 4:48 AM, Luc Van Oostenryck > wrote: >> There is a problem though, with non-constant args. >> Now the predeclarations of the 3 __builtin_bswap16/32/64 >> are gone, no more prototype and thus no more typing information. >> >> For example, if you call __builtin_bswap64() with an int argument, >> there is no way for the next steps to know the arg must first >> be 64 bit extended. Same for the result's type. > > That is a very good point. Need more work on that. > > The currently problem if I include the function prototype, the > function prototype symbol will over shadow the symbol contain > swap_op. We need to make sure the function prototype symbol > is the one loading with correct swap_op. > > Ideally, all the "__builtin_xxx" related stuff should be move to a > separate builtin.c. Right now the function prototype is in lib.c > The implementation is sprinkle around symbol.c, evaluation.c > and expand.c. > > Re-attach the V2 patch as last email I forget to CC sparse > mailing list. This V2 patch still have the missing prototype problem > you describe here. > > > Chris diff --git a/expand.c b/expand.c index 0f6720c..b9a430b 100644 --- a/expand.c +++ b/expand.c @@ -802,6 +802,46 @@ int expand_safe_p(struct expression *expr, int cost) return 0; } +/* The arguments are constant if the cost of all of them is zero */ +int expand_bswap(struct expression *expr, int cost) +{ + struct symbol *sym; + struct expression_list *args = expr->args; + long long input; + int count; + + if (cost) + return cost; + + sym = expr->fn->ctype; + count = expression_list_size(args); + if (count != 1) { + sparse_error(expr->pos, "Invaild number of arguments for function %s (expected 1 got %d)", + show_ident(sym->ident), count); + return SIDE_EFFECTS; + } + + input = const_expression_value(first_expression(args)); + + if (sym->ident == &__builtin_bswap16_ident) { + expr->value = __builtin_bswap16(input); + expr->ctype = &ushort_ctype; + } else if (sym->ident == &__builtin_bswap32_ident) { + expr->value = __builtin_bswap32(input); + expr->ctype = &uint_ctype; + } else if (sym->ident == &__builtin_bswap64_ident) { + expr->value = __builtin_bswap64(input); + expr->ctype = &ullong_ctype; + } else { + die("Unexpected __builtin_bswap symbol %s\n", show_ident(sym->ident)); + } + + expr->type = EXPR_VALUE; + expr->taint = 0; + return 0; +} + + /* * expand a call expression with a symbol. This * should expand builtins. diff --git a/ident-list.h b/ident-list.h index b65b667..a683f6c 100644 --- a/ident-list.h +++ b/ident-list.h @@ -35,6 +35,9 @@ IDENT_RESERVED(__sizeof_ptr__); IDENT_RESERVED(__builtin_types_compatible_p); IDENT_RESERVED(__builtin_offsetof); IDENT_RESERVED(__label__); +IDENT(__builtin_bswap16); +IDENT(__builtin_bswap32); +IDENT(__builtin_bswap64); /* Attribute names */ IDENT(packed); IDENT(__packed__); diff --git a/lib.c b/lib.c index 2660575..7e35049 100644 --- a/lib.c +++ b/lib.c @@ -819,40 +819,6 @@ void declare_builtin_functions(void) add_pre_buffer("extern int __builtin_popcountl(unsigned long);\n"); add_pre_buffer("extern int __builtin_popcountll(unsigned long long);\n"); - /* And byte swaps.. */ - add_pre_buffer("extern unsigned short ____builtin_bswap16(unsigned short);\n"); - add_pre_buffer("extern unsigned int ____builtin_bswap32(unsigned int);\n"); - add_pre_buffer("extern unsigned long long ____builtin_bswap64(unsigned long long);\n"); - add_pre_buffer("#define __sparse_constant_swab16(x) ((unsigned short)(" - " (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) |" - " (((unsigned short)(x) & (unsigned short)0xff00U) >> 8)))\n"); - add_pre_buffer("#define __sparse_constant_swab32(x) ((unsigned int)(" - " (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) |" - " (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) |" - " (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) |" - " (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24)))\n"); - add_pre_buffer("#define __sparse_constant_swab64(x) ((unsigned long long)(" - " (((unsigned long long)(x) & (unsigned long long)0x00000000000000ffULL) << 56) |" - " (((unsigned long long)(x) & (unsigned long long)0x000000000000ff00ULL) << 40) |" - " (((unsigned long long)(x) & (unsigned long long)0x0000000000ff0000ULL) << 24) |" - " (((unsigned long long)(x) & (unsigned long long)0x00000000ff000000ULL) << 8) |" - " (((unsigned long long)(x) & (unsigned long long)0x000000ff00000000ULL) >> 8) |" - " (((unsigned long long)(x) & (unsigned long long)0x0000ff0000000000ULL) >> 24) |" - " (((unsigned long long)(x) & (unsigned long long)0x00ff000000000000ULL) >> 40) |" - " (((unsigned long long)(x) & (unsigned long long)0xff00000000000000ULL) >> 56)))\n"); - add_pre_buffer("#define __builtin_bswap16(x)" - " (__builtin_constant_p((unsigned short)(x)) ?" - " __sparse_constant_swab16(x) :" - " ____builtin_bswap16(x))\n"); - add_pre_buffer("#define __builtin_bswap32(x)" - " (__builtin_constant_p((unsigned int)(x)) ?" - " __sparse_constant_swab32(x) :" - " ____builtin_bswap32(x))\n"); - add_pre_buffer("#define __builtin_bswap64(x)" - " (__builtin_constant_p((unsigned long long)(x)) ?" - " __sparse_constant_swab64(x) :" - " ____builtin_bswap64(x))\n"); - /* And atomic memory access functions.. */ add_pre_buffer("extern int __sync_fetch_and_add(void *, ...);\n"); add_pre_buffer("extern int __sync_fetch_and_sub(void *, ...);\n"); diff --git a/lib.h b/lib.h index b778bdc..306ee45 100644 --- a/lib.h +++ b/lib.h @@ -200,6 +200,11 @@ static inline struct instruction *first_instruction(struct instruction_list *hea return first_ptr_list((struct ptr_list *)head); } +static inline struct expression *first_expression(struct expression_list *head) +{ + return first_ptr_list((struct ptr_list *)head); +} + static inline pseudo_t first_pseudo(struct pseudo_list *head) { return first_ptr_list((struct ptr_list *)head); diff --git a/symbol.c b/symbol.c index 92a7a62..e57f207 100644 --- a/symbol.c +++ b/symbol.c @@ -773,6 +773,11 @@ static struct symbol_op choose_op = { .args = arguments_choose, }; +static struct symbol_op bswap_op = { + .evaluate = evaluate_to_integer, + .expand = expand_bswap +}; + /* * Builtin functions */ @@ -788,6 +793,9 @@ static struct sym_init { { "__builtin_warning", &builtin_fn_type, MOD_TOPLEVEL, &warning_op }, { "__builtin_expect", &builtin_fn_type, MOD_TOPLEVEL, &expect_op }, { "__builtin_choose_expr", &builtin_fn_type, MOD_TOPLEVEL, &choose_op }, + { "__builtin_bswap16", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op }, + { "__builtin_bswap32", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op }, + { "__builtin_bswap64", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op }, { NULL, NULL, 0 } }; diff --git a/symbol.h b/symbol.h index 9b3f160..48bbfce 100644 --- a/symbol.h +++ b/symbol.h @@ -130,6 +130,7 @@ struct symbol_op { extern int expand_safe_p(struct expression *expr, int cost); extern int expand_constant_p(struct expression *expr, int cost); +extern int expand_bswap(struct expression *expr, int cost); #define SYM_ATTR_WEAK 0 #define SYM_ATTR_NORMAL 1