From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 52667 invoked by alias); 23 Oct 2017 11:22:06 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 52657 invoked by uid 89); 23 Oct 2017 11:22:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-15.4 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=2526 X-HELO: mail-wr0-f179.google.com Received: from mail-wr0-f179.google.com (HELO mail-wr0-f179.google.com) (209.85.128.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Oct 2017 11:22:03 +0000 Received: by mail-wr0-f179.google.com with SMTP id p96so3090539wrb.7 for ; Mon, 23 Oct 2017 04:22:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=PjioiK22EQu39b4M2bQThgvKf2SEHSdH54DWebBh0GQ=; b=mkACJiUPvdIu2UfoJCrGIhMH13OTRPdtwzm+/aC1DpYPnRiYIQ+U+ANyjdafxrf8U4 E5m6Oa5Wn71IW8j9nDh/D2P0MYzGkbR9RsprOz1rhU9U/SfZdnnMRxXfX5va8044RjX/ eBUPJgogIwccgaKAFf/tNIvCQxQZELA61eHOHPvT50EYgtR7TpW5ifqpeNqrftRTEUry QAIOrYeCVhBjxiyAetNDtKJb+XqNs6KRQ9V+oGjXJK47+OcqMqcO8g6Geyh/0A6vnU0g VyBSP61e0CQ2l/yhDAwgilSseuOR9GHAdTD+INZpEmiVCExN6VLLH18un0DchFjTU0o+ gMGA== X-Gm-Message-State: AMCzsaUikKxqnYaWebgeC1jhG0oM86urzrX7lW7EYZL6zeTVT1CJsOgq b1suly1wIpfUXELJDZu9V2nufoJSPT4= X-Google-Smtp-Source: ABhQp+SP6NtEf83WVBnmy4TeqcH2O2SNJKJa8wIEjk/PNmLC83619ExEFPadmusTK4gr6PRUHwiFDA== X-Received: by 10.223.152.16 with SMTP id v16mr10349158wrb.108.1508757720901; Mon, 23 Oct 2017 04:22:00 -0700 (PDT) Received: from localhost ([2.26.27.199]) by smtp.gmail.com with ESMTPSA id o138sm5425073wmg.36.2017.10.23.04.21.59 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Oct 2017 04:22:00 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [07/nn] Add unique CONSTs References: <87wp3mxgir.fsf@linaro.org> Date: Mon, 23 Oct 2017 11:22:00 -0000 In-Reply-To: <87wp3mxgir.fsf@linaro.org> (Richard Sandiford's message of "Mon, 23 Oct 2017 12:14:36 +0100") Message-ID: <87376axg6i.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2017-10/txt/msg01458.txt.bz2 This patch adds a way of treating certain kinds of CONST as unique, so that pointer equality is equivalent to value equality. For now it is restricted to VEC_DUPLICATE and VEC_SERIES, although the code to generate them remains in the else arm of an "if (1)" until a later patch. This is needed so that (const (vec_duplicate xx)) can used as the CONSTxx_RTX of a variable-length vector. 2017-10-23 Richard Sandiford Alan Hayward David Sherwood gcc/ * rtl.h (unique_const_p): New function. (gen_rtx_CONST): Declare. * emit-rtl.c (const_hasher): New struct. (const_htab): New variable. (init_emit_once): Initialize it. (const_hasher::hash, const_hasher::equal): New functions. (gen_rtx_CONST): New function. (spare_vec_duplicate, spare_vec_series): New variables. (gen_const_vec_duplicate_1): Add code for use (const (vec_duplicate)), but disable it for now. (gen_const_vec_series): Likewise (const (vec_series)). * gengenrtl.c (special_rtx): Return true for CONST. * rtl.c (shared_const_p): Return true if unique_const_p. Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2017-10-23 11:41:41.549050496 +0100 +++ gcc/rtl.h 2017-10-23 11:42:47.297720974 +0100 @@ -2861,6 +2861,23 @@ vec_series_p (const_rtx x, rtx *base_out return const_vec_series_p (x, base_out, step_out); } +/* Return true if there should only ever be one instance of (const X), + so that constants of this type can be compared using pointer equality. */ + +inline bool +unique_const_p (const_rtx x) +{ + switch (GET_CODE (x)) + { + case VEC_DUPLICATE: + case VEC_SERIES: + return true; + + default: + return false; + } +} + /* Return the unpromoted (outer) mode of SUBREG_PROMOTED_VAR_P subreg X. */ inline scalar_int_mode @@ -3542,6 +3559,7 @@ extern rtx_insn_list *gen_rtx_INSN_LIST gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn, basic_block bb, rtx pattern, int location, int code, rtx reg_notes); +extern rtx gen_rtx_CONST (machine_mode, rtx); extern rtx gen_rtx_CONST_INT (machine_mode, HOST_WIDE_INT); extern rtx gen_rtx_CONST_VECTOR (machine_mode, rtvec); extern void set_mode_and_regno (rtx, machine_mode, unsigned int); Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-10-23 11:41:41.548050496 +0100 +++ gcc/emit-rtl.c 2017-10-23 11:42:47.296720974 +0100 @@ -175,6 +175,15 @@ struct const_fixed_hasher : ggc_cache_pt static GTY ((cache)) hash_table *const_fixed_htab; +/* A hash table storing unique CONSTs. */ +struct const_hasher : ggc_cache_ptr_hash +{ + static hashval_t hash (rtx x); + static bool equal (rtx x, rtx y); +}; + +static GTY ((cache)) hash_table *const_htab; + #define cur_insn_uid (crtl->emit.x_cur_insn_uid) #define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid) #define first_label_num (crtl->emit.x_first_label_num) @@ -310,6 +319,28 @@ const_fixed_hasher::equal (rtx x, rtx y) return fixed_identical (CONST_FIXED_VALUE (a), CONST_FIXED_VALUE (b)); } +/* Returns a hash code for X (which is either an existing unique CONST + or an operand to gen_rtx_CONST). */ + +hashval_t +const_hasher::hash (rtx x) +{ + if (GET_CODE (x) == CONST) + x = XEXP (x, 0); + + int do_not_record_p = 0; + return hash_rtx (x, GET_MODE (x), &do_not_record_p, NULL, false); +} + +/* Returns true if the operand of unique CONST X is equal to Y. */ + +bool +const_hasher::equal (rtx x, rtx y) +{ + gcc_checking_assert (GET_CODE (x) == CONST); + return rtx_equal_p (XEXP (x, 0), y); +} + /* Return true if the given memory attributes are equal. */ bool @@ -5756,16 +5787,55 @@ init_emit (void) #endif } +rtx +gen_rtx_CONST (machine_mode mode, rtx val) +{ + if (unique_const_p (val)) + { + /* Look up the CONST in the hash table. */ + rtx *slot = const_htab->find_slot (val, INSERT); + if (*slot == 0) + *slot = gen_rtx_raw_CONST (mode, val); + return *slot; + } + + return gen_rtx_raw_CONST (mode, val); +} + +/* Temporary rtx used by gen_const_vec_duplicate_1. */ +static GTY((deletable)) rtx spare_vec_duplicate; + /* Like gen_const_vec_duplicate, but ignore const_tiny_rtx. */ static rtx gen_const_vec_duplicate_1 (machine_mode mode, rtx el) { int nunits = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (nunits); - for (int i = 0; i < nunits; ++i) - RTVEC_ELT (v, i) = el; - return gen_rtx_raw_CONST_VECTOR (mode, v); + if (1) + { + rtvec v = rtvec_alloc (nunits); + + for (int i = 0; i < nunits; ++i) + RTVEC_ELT (v, i) = el; + + return gen_rtx_raw_CONST_VECTOR (mode, v); + } + else + { + if (spare_vec_duplicate) + { + PUT_MODE (spare_vec_duplicate, mode); + XEXP (spare_vec_duplicate, 0) = el; + } + else + spare_vec_duplicate = gen_rtx_VEC_DUPLICATE (mode, el); + + rtx res = gen_rtx_CONST (mode, spare_vec_duplicate); + if (XEXP (res, 0) == spare_vec_duplicate) + spare_vec_duplicate = NULL_RTX; + + return res; + } } /* Generate a vector constant of mode MODE in which every element has @@ -5827,6 +5897,9 @@ const_vec_series_p_1 (const_rtx x, rtx * return true; } +/* Temporary rtx used by gen_const_vec_series. */ +static GTY((deletable)) rtx spare_vec_series; + /* Generate a vector constant of mode MODE in which element I has the value BASE + I * STEP. */ @@ -5836,13 +5909,33 @@ gen_const_vec_series (machine_mode mode, gcc_assert (CONSTANT_P (base) && CONSTANT_P (step)); int nunits = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (nunits); - scalar_mode inner_mode = GET_MODE_INNER (mode); - RTVEC_ELT (v, 0) = base; - for (int i = 1; i < nunits; ++i) - RTVEC_ELT (v, i) = simplify_gen_binary (PLUS, inner_mode, - RTVEC_ELT (v, i - 1), step); - return gen_rtx_raw_CONST_VECTOR (mode, v); + if (1) + { + rtvec v = rtvec_alloc (nunits); + scalar_mode inner_mode = GET_MODE_INNER (mode); + RTVEC_ELT (v, 0) = base; + for (int i = 1; i < nunits; ++i) + RTVEC_ELT (v, i) = simplify_gen_binary (PLUS, inner_mode, + RTVEC_ELT (v, i - 1), step); + return gen_rtx_raw_CONST_VECTOR (mode, v); + } + else + { + if (spare_vec_series) + { + PUT_MODE (spare_vec_series, mode); + XEXP (spare_vec_series, 0) = base; + XEXP (spare_vec_series, 1) = step; + } + else + spare_vec_series = gen_rtx_VEC_SERIES (mode, base, step); + + rtx res = gen_rtx_CONST (mode, spare_vec_series); + if (XEXP (res, 0) == spare_vec_series) + spare_vec_series = NULL_RTX; + + return res; + } } /* Generate a vector of mode MODE in which element I has the value @@ -6000,6 +6093,8 @@ init_emit_once (void) reg_attrs_htab = hash_table::create_ggc (37); + const_htab = hash_table::create_ggc (37); + #ifdef INIT_EXPANDERS /* This is to initialize {init|mark|free}_machine_status before the first call to push_function_context_to. This is needed by the Chill front Index: gcc/gengenrtl.c =================================================================== --- gcc/gengenrtl.c 2017-08-03 10:40:53.029491180 +0100 +++ gcc/gengenrtl.c 2017-10-23 11:42:47.297720974 +0100 @@ -143,7 +143,8 @@ special_rtx (int idx) || strcmp (defs[idx].enumname, "CC0") == 0 || strcmp (defs[idx].enumname, "RETURN") == 0 || strcmp (defs[idx].enumname, "SIMPLE_RETURN") == 0 - || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0); + || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0 + || strcmp (defs[idx].enumname, "CONST") == 0); } /* Return nonzero if the RTL code given by index IDX is one that we should Index: gcc/rtl.c =================================================================== --- gcc/rtl.c 2017-08-03 10:40:55.646123304 +0100 +++ gcc/rtl.c 2017-10-23 11:42:47.297720974 +0100 @@ -252,6 +252,9 @@ shared_const_p (const_rtx orig) { gcc_assert (GET_CODE (orig) == CONST); + if (unique_const_p (XEXP (orig, 0))) + return true; + /* CONST can be shared if it contains a SYMBOL_REF. If it contains a LABEL_REF, it isn't sharable. */ return (GET_CODE (XEXP (orig, 0)) == PLUS