From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26975 invoked by alias); 16 Sep 2013 04:48:53 -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 26965 invoked by uid 89); 16 Sep 2013 04:48:52 -0000 Received: from mail-pb0-f45.google.com (HELO mail-pb0-f45.google.com) (209.85.160.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 16 Sep 2013 04:48:52 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,KHOP_THREADED autolearn=ham version=3.3.2 X-HELO: mail-pb0-f45.google.com Received: by mail-pb0-f45.google.com with SMTP id mc17so3585387pbc.4 for ; Sun, 15 Sep 2013 21:48:49 -0700 (PDT) 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; bh=qEZXscZQ9yOvVw4zqlu3UeqmThyeDBmp5WqQFT/PIjM=; b=acJFcwv9KtmLJ/iEEtmlmnO2r9twRE/tGPXhBa1Ek6bSYwatmedKhUZmLElFyTV3Xn cpXAzvJMdx1Y9gT3g304bt9zBK7rnW0jAQjQjysCtYzOZBTAOwFv26rj/MeRIfppjyZ/ m1EFPSx2/0SOpOhUGy/k7pdvQ1+IA9os0GhLvZuLP+/KKxwJYu952p+qFxEaMAOMBYO8 i0fJ9f+yS7GGnAi0l8G1PObMs1E0V6+xSRxrXiJSIeaCGav6EAYujCJFp4IAOIXHC81F qSNd84WzwmavFDJxe2233bhgca2mTDG+bNMek30jElTeOSLASDxNb2suMfTcUA9VgZok AzGA== X-Gm-Message-State: ALoCoQkkLG2Hr3Uu87NFmhLiDgRwn7il30tIoHjydz7flhRBk5RIpUqQbN+/5xLWNbkmsPkMLKKt X-Received: by 10.68.252.233 with SMTP id zv9mr26841954pbc.69.1379306929326; Sun, 15 Sep 2013 21:48:49 -0700 (PDT) Received: from [192.168.1.8] (27-33-114-215.tpgi.com.au. [27.33.114.215]) by mx.google.com with ESMTPSA id sy10sm35504167pac.15.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 15 Sep 2013 21:48:48 -0700 (PDT) Message-ID: <52368DAB.1040103@linaro.org> Date: Mon, 16 Sep 2013 06:46:00 -0000 From: Kugan User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130803 Thunderbird/17.0.8 MIME-Version: 1.0 To: Richard Biener , Jakub Jelinek CC: "gcc-patches@gcc.gnu.org" , Eric Botcazou , Ramana Radhakrishnan , Richard Earnshaw Subject: Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL References: <5225D2E4.303@linaro.org> <52297A5B.1010309@suse.de> <522D03B9.6060201@linaro.org> <522E99DD.2080505@linaro.org> <20130910134006.GZ1817@tucnak.redhat.com> <52300715.4080307@linaro.org> <20130911090837.GM1817@tucnak.redhat.com> <52329E95.1080501@linaro.org> In-Reply-To: <52329E95.1080501@linaro.org> Content-Type: multipart/mixed; boundary="------------060701070803050206080705" X-IsSubscribed: yes X-SW-Source: 2013-09/txt/msg01120.txt.bz2 This is a multi-part message in MIME format. --------------060701070803050206080705 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1079 Hi, Updated the patch to the latest changes in trunk that splits tree.h. I also noticed an error in printing double_int and fixed it. Is this OK? Thanks, Kugan +2013-09-12 Kugan Vivekanandarajah + + * cfgexpand.c (maybe_dump_rtl_for_gimple_stmt) : Add range to dump. + * gimple-pretty-print.c (print_double_int) : New function. + * gimple-pretty-print.c (dump_gimple_phi) : Dump range info. + * (pp_gimple_stmt_1) : Likewise. + * tree-ssa-alias.c (dump_alias_info) : Check pointer type. + * tree-ssa-copy.c (fini_copy_prop) : Check pointer type and copy + range info. + * tree-ssanames.c (make_ssa_name_fn) : Check pointer type in + initialize. + * (set_range_info) : New function. + * (get_range_info) : Likewise. + * (duplicate_ssa_name_range_info) : Likewise. + * (duplicate_ssa_name_fn) : Check pointer type and call correct + duplicate function. + * tree-vrp.c (vrp_finalize): Call set_range_info to upddate + value range of SSA_NAMEs. + * tree.h (SSA_NAME_PTR_INFO) : changed to access via union + * tree.h (SSA_NAME_RANGE_INFO) : New macro + --------------060701070803050206080705 Content-Type: text/x-patch; name="vrp_extension_elimination_patch1_r4.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="vrp_extension_elimination_patch1_r4.diff" Content-length: 15507 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 88e48c2..302188e 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1820,7 +1820,7 @@ maybe_dump_rtl_for_gimple_stmt (gimple stmt, rtx since) { fprintf (dump_file, "\n;; "); print_gimple_stmt (dump_file, stmt, 0, - TDF_SLIM | (dump_flags & TDF_LINENO)); + TDF_SLIM | TDF_RANGE | (dump_flags & TDF_LINENO)); fprintf (dump_file, "\n"); print_rtl (dump_file, since ? NEXT_INSN (since) : since); diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h index ddc770a..8896d89 100644 --- a/gcc/dumpfile.h +++ b/gcc/dumpfile.h @@ -83,9 +83,10 @@ enum tree_dump_index #define TDF_CSELIB (1 << 23) /* Dump cselib details. */ #define TDF_SCEV (1 << 24) /* Dump SCEV details. */ #define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */ -#define MSG_OPTIMIZED_LOCATIONS (1 << 26) /* -fopt-info optimized sources */ -#define MSG_MISSED_OPTIMIZATION (1 << 27) /* missed opportunities */ -#define MSG_NOTE (1 << 28) /* general optimization info */ +#define TDF_RANGE (1 << 26) /* Dump range information. */ +#define MSG_OPTIMIZED_LOCATIONS (1 << 27) /* -fopt-info optimized sources */ +#define MSG_MISSED_OPTIMIZATION (1 << 28) /* missed opportunities */ +#define MSG_NOTE (1 << 29) /* general optimization info */ #define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \ | MSG_NOTE) diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 01a1ab5..6531010 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1600,6 +1600,25 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags) } } +/* Dumps double_int CST to BUFFER. */ + +static void +print_double_int (pretty_printer *buffer, double_int cst) +{ + tree node = double_int_to_tree (integer_type_node, cst); + if (TREE_INT_CST_HIGH (node) == 0) + pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node)); + else if (TREE_INT_CST_HIGH (node) == -1 + && TREE_INT_CST_LOW (node) != 0) + pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED, + -TREE_INT_CST_LOW (node)); + else + sprintf (pp_buffer (buffer)->digit_buffer, + HOST_WIDE_INT_PRINT_DOUBLE_HEX, + (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node), + (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node)); +} + /* Dump a PHI node PHI. BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1. The caller is responsible for calling pp_flush on BUFFER to finalize @@ -1628,6 +1647,27 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags) pp_string (buffer, "# "); } + if ((flags & TDF_RANGE) + && !POINTER_TYPE_P (TREE_TYPE (lhs)) + && SSA_NAME_RANGE_INFO (lhs)) + { + double_int min, max; + value_range_type range_type; + get_range_info (lhs, min, max, range_type); + if (range_type == VR_VARYING) + pp_printf (buffer, "# RANGE VR_VARYING"); + else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE) + { + pp_printf (buffer, "# RANGE "); + pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~"); + print_double_int (buffer, min); + pp_printf (buffer, ", "); + print_double_int (buffer, max); + pp_printf (buffer, "]"); + newline_and_indent (buffer, spc); + } + } + if (flags & TDF_RAW) dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi, gimple_phi_result (phi)); @@ -1930,6 +1970,32 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) } } + if ((flags & TDF_RANGE) + && gimple_has_lhs (gs)) + { + tree lhs = gimple_get_lhs (gs); + if ((TREE_CODE (lhs) == SSA_NAME) + && !POINTER_TYPE_P (TREE_TYPE (lhs)) + && SSA_NAME_RANGE_INFO (lhs)) + { + double_int min, max; + value_range_type range_type; + get_range_info (lhs, min, max, range_type); + if (range_type == VR_VARYING) + pp_printf (buffer, "# RANGE VR_VARYING"); + else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE) + { + pp_printf (buffer, "# RANGE "); + pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~"); + print_double_int (buffer, min); + pp_printf (buffer, ", "); + print_double_int (buffer, max); + pp_printf (buffer, "]"); + newline_and_indent (buffer, spc); + } + } + } + switch (gimple_code (gs)) { case GIMPLE_ASM: diff --git a/gcc/tree-core.h b/gcc/tree-core.h index b1bc56a..30e0557 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -43,6 +43,7 @@ struct function; struct real_value; struct fixed_value; struct ptr_info_def; +struct range_info_def; struct die_struct; struct pointer_set_t; @@ -1041,8 +1042,14 @@ struct GTY(()) tree_ssa_name { /* Statement that defines this SSA name. */ gimple def_stmt; - /* Pointer attributes used for alias analysis. */ - struct ptr_info_def *ptr_info; + /* Value range information. */ + union ssa_name_info_type { + /* Pointer attributes used for alias analysis. */ + struct GTY ((tag ("0"))) ptr_info_def *ptr_info; + /* Value range attributes used for zero/sign extension elimination. */ + struct GTY ((tag ("1"))) range_info_def *range_info; + } GTY ((desc ("%1.typed.type ?" \ + "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info; /* Immediate uses list for this SSA_NAME. */ struct ssa_use_operand_d imm_uses; diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 9c5d979..f76f1bf 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -131,6 +131,15 @@ enum need_phi_state { NEED_PHI_STATE_MAYBE }; +/* Value range information for SSA_NAMEs representing non-pointer variables. */ + +struct GTY (()) range_info_def { + /* Minmum for value range. */ + double_int min; + /* Maximum for value range. */ + double_int max; +}; + /* Immediate use lists are used to directly access all uses for an SSA name and get pointers to the statement for each use. diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 9a6d5f4..0ef7401 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -404,6 +404,7 @@ dump_alias_info (FILE *file) struct ptr_info_def *pi; if (ptr == NULL_TREE + || !POINTER_TYPE_P (TREE_TYPE (ptr)) || SSA_NAME_IN_FREE_LIST (ptr)) continue; diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 3197917..25a43ff 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -767,11 +767,19 @@ fini_copy_prop (void) of the representative to the first solution we find if it doesn't have one already. */ if (copy_of[i].value != var - && TREE_CODE (copy_of[i].value) == SSA_NAME - && POINTER_TYPE_P (TREE_TYPE (var)) - && SSA_NAME_PTR_INFO (var) - && !SSA_NAME_PTR_INFO (copy_of[i].value)) - duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var)); + && TREE_CODE (copy_of[i].value) == SSA_NAME) + { + if (POINTER_TYPE_P (TREE_TYPE (var)) + && SSA_NAME_PTR_INFO (var) + && !SSA_NAME_PTR_INFO (copy_of[i].value)) + duplicate_ssa_name_ptr_info (copy_of[i].value, + SSA_NAME_PTR_INFO (var)); + else if (!POINTER_TYPE_P (TREE_TYPE (var)) + && SSA_NAME_RANGE_INFO (var) + && !SSA_NAME_RANGE_INFO (copy_of[i].value)) + duplicate_ssa_name_range_info (copy_of[i].value, + SSA_NAME_RANGE_INFO (var)); + } } /* Don't do DCE if SCEV is initialized. It would destroy the scev cache. */ diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index e64bd65..4489f2b 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -154,7 +154,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt) SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var); } SSA_NAME_DEF_STMT (t) = stmt; - SSA_NAME_PTR_INFO (t) = NULL; + if (POINTER_TYPE_P (TREE_TYPE (t))) + SSA_NAME_PTR_INFO (t) = NULL; + else + SSA_NAME_RANGE_INFO (t) = NULL; + SSA_NAME_IN_FREE_LIST (t) = 0; SSA_NAME_IS_DEFAULT_DEF (t) = 0; imm = &(SSA_NAME_IMM_USE_NODE (t)); @@ -166,6 +170,64 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt) return t; } +/* Store range information MIN, and MAX to tree ssa_name NAME. */ + +void +set_range_info (tree name, double_int min, double_int max) +{ + gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); + gcc_assert (TREE_CODE (name) == SSA_NAME); + range_info_def *ri = SSA_NAME_RANGE_INFO (name); + + /* Allocate if not available. */ + if (ri == NULL) + { + ri = ggc_alloc_cleared_range_info_def (); + SSA_NAME_RANGE_INFO (name) = ri; + } + + /* Set the values. */ + ri->min = min; + ri->max = max; +} + + +/* Get range information MIN, MAX and RANGE_TYPE + corresponding to tree ssa_name NAME. */ + +void +get_range_info (tree name, double_int &min, double_int &max, + enum value_range_type &range_type) +{ + gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); + gcc_assert (TREE_CODE (name) == SSA_NAME); + range_info_def *ri = SSA_NAME_RANGE_INFO (name); + + /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs + with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. */ + if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name))) + > 2 * HOST_BITS_PER_WIDE_INT)) + { + range_type = VR_VARYING; + return; + } + + /* If min > max, it is VR_ANTI_RANGE. */ + if (ri->min.scmp (ri->max) == 1) + { + /* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1]. */ + range_type = VR_ANTI_RANGE; + min = ri->max + double_int_one; + max = ri->min - double_int_one; + } + else + { + /* Otherwise (when min <= max), it is VR_RANGE. */ + range_type = VR_RANGE; + min = ri->min; + max = ri->max; + } +} /* We no longer need the SSA_NAME expression VAR, release it so that it may be reused. @@ -362,6 +424,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info) SSA_NAME_PTR_INFO (name) = new_ptr_info; } +/* Creates a duplicate of the range_info_def at RANGE_INFO for use by + the SSA name NAME. */ +void +duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info) +{ + struct range_info_def *new_range_info; + + gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); + gcc_assert (!SSA_NAME_RANGE_INFO (name)); + + if (!range_info) + return; + + new_range_info = ggc_alloc_range_info_def (); + *new_range_info = *range_info; + + SSA_NAME_RANGE_INFO (name) = new_range_info; +} + + /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT in function FN. */ @@ -370,10 +452,20 @@ tree duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt) { tree new_name = copy_ssa_name_fn (fn, name, stmt); - struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name); + if (POINTER_TYPE_P (TREE_TYPE (name))) + { + struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name); - if (old_ptr_info) - duplicate_ssa_name_ptr_info (new_name, old_ptr_info); + if (old_ptr_info) + duplicate_ssa_name_ptr_info (new_name, old_ptr_info); + } + else + { + struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name); + + if (old_range_info) + duplicate_ssa_name_range_info (new_name, old_range_info); + } return new_name; } diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index 8cc3efd..5224bfb 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -71,6 +71,7 @@ extern struct ptr_info_def *get_ptr_info (tree); extern tree copy_ssa_name_fn (struct function *, tree, gimple); extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *); extern tree duplicate_ssa_name_fn (struct function *, tree, gimple); +extern void duplicate_ssa_name_range_info (tree, struct range_info_def *); extern void release_defs (gimple); extern void replace_ssa_name_symbol (tree, tree); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index ae27dc4..057abc2 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -41,9 +41,6 @@ along with GCC; see the file COPYING3. If not see #include "optabs.h" -/* Type of value ranges. See value_range_d for a description of these - types. */ -enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING }; /* Range of values that can be associated with an SSA_NAME after VRP has executed. */ @@ -9452,6 +9449,39 @@ vrp_finalize (void) the datastructures built by VRP. */ identify_jump_threads (); + /* Set value range to non pointer SSA_NAMEs. */ + for (i = 0; i < num_vr_values; i++) + if (vr_value[i]) + { + tree name = ssa_name (i); + + if (POINTER_TYPE_P (TREE_TYPE (name)) + || (vr_value[i]->type == VR_VARYING) + || (vr_value[i]->type == VR_UNDEFINED)) + continue; + + if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST) + && (TREE_CODE (vr_value[i]->max) == INTEGER_CST)) + { + if (vr_value[i]->type == VR_RANGE) + set_range_info (name, + tree_to_double_int (vr_value[i]->min), + tree_to_double_int (vr_value[i]->max)); + else if (vr_value[i]->type == VR_ANTI_RANGE) + { + /* VR_ANTI_RANGE ~[min, max] is encoded compactly as + [max + 1, min - 1] without additional attributes. + When min value > max value, we know that it is + VR_ANTI_RANGE; it is VR_RANGE othewise. */ + set_range_info (name, + tree_to_double_int (vr_value[i]->max) + + double_int_one, + tree_to_double_int (vr_value[i]->min) + - double_int_one); + } + } + } + /* Free allocated memory. */ for (i = 0; i < num_vr_values; i++) if (vr_value[i]) diff --git a/gcc/tree.h b/gcc/tree.h index a263a2c..6eb7e56 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1336,7 +1336,22 @@ extern void protected_set_expr_location (tree, location_t); /* Attributes for SSA_NAMEs for pointer-type variables. */ #define SSA_NAME_PTR_INFO(N) \ - SSA_NAME_CHECK (N)->ssa_name.ptr_info + SSA_NAME_CHECK (N)->ssa_name.info.ptr_info + +/* Value range info Attributes for SSA_NAMEs of non pointer-type variables. */ +#define SSA_NAME_RANGE_INFO(N) \ + SSA_NAME_CHECK (N)->ssa_name.info.range_info + + +/* Type of value ranges. See value_range_d In tree-vrp.c for a + description of these types. */ +enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING }; + +/* Sets the value range to SSA. */ +void set_range_info (tree ssa, double_int min, double_int max); +/* Gets the value range from SSA. */ +void get_range_info (tree name, double_int &min, double_int &max, + enum value_range_type &range_type); /* Return the immediate_use information for an SSA_NAME. */ #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses --------------060701070803050206080705--