From patchwork Wed Jun 9 01:14:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 1489675 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: 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=aasJMwqE; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G08KW6PYkz9sSn for ; Wed, 9 Jun 2021 11:14:54 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CC1953893C57 for ; Wed, 9 Jun 2021 01:14:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC1953893C57 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1623201291; bh=EDPqoODLhSCI4ynlWeUcwG2EaUcg8LlJnVAEe6pr2dk=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=aasJMwqE8XDeEgZ6243ptDJNEOpeAZF8e7XG5JN4Gh/uk+m8nh7r0SbvmZZ1b2u3f m5+BjAPZ2QNCVU1Jn4OdsV/QAyLwPLhnfdV2dLRNoUsLw5ag7qDlSEhFgma/xQD3WM T/G+TgaTwqQx00o8l4f80QpT0K6/fEdREATgaP2A= 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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id DBF7F3886C6B for ; Wed, 9 Jun 2021 01:14:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DBF7F3886C6B Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-589-XSc8GAKvOiafJcrll0Lwew-1; Tue, 08 Jun 2021 21:14:05 -0400 X-MC-Unique: XSc8GAKvOiafJcrll0Lwew-1 Received: by mail-qt1-f199.google.com with SMTP id c17-20020a05622a0591b0290249aef9a5d5so440701qtb.12 for ; Tue, 08 Jun 2021 18:14:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-language; bh=EDPqoODLhSCI4ynlWeUcwG2EaUcg8LlJnVAEe6pr2dk=; b=df4N7UPFtos1IGVOwx6DjPQ5NRzZjafhuHn9EcioN6D96iskNYMaGaRo2oJ+fXvEve vl3lWNnU2h+WZgTiWf7kKLnhFsXEcaYVs0b0muye5Mv0mFgTJt05nDYkeLbNyRTnUSK1 vlSOAizK1eIrnhB5uKT5iWokv6Df4gA2FFVEkTB+/Dm4f6DCz9lo3qbVL1h2IUdd7vUp yDAK0uLiYni+3XWMaYzB7uWdOwoGdNE/3d9/MBrQdOMJmKeXuf9LCsrGBlRlMW+/ujt0 PFI1fO9SVXiJkXU2m7jj0RuMMi5Prn9CZsXLYOrUyU2S6BezSjqzMoggR3uA4bbPL9hz yHAg== X-Gm-Message-State: AOAM5324cpXPMslncgpUEJOcgoWyuvmU727DB+nldy6fFjYVMMFrpG// MA6y2EussseRbnv7PEUvPzZJJ05mI8BQ0+S2tUd4X+5dAzX0TMtGNAVuhPeh7LcGe3n2t63LGyS i0ccRUWGkhV47afb/lg== X-Received: by 2002:aed:306f:: with SMTP id 102mr23812876qte.197.1623201244603; Tue, 08 Jun 2021 18:14:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw96vrCCHxroxrKHdLH6UoPS52Rj9NixCDKJ6FUucEbwjF2jh4GtOA+vti+aI1IDGxtHjGrUw== X-Received: by 2002:aed:306f:: with SMTP id 102mr23812865qte.197.1623201244405; Tue, 08 Jun 2021 18:14:04 -0700 (PDT) Received: from ?IPv6:2607:fea8:a25d:e700::1b2a? ([2607:fea8:a25d:e700::1b2a]) by smtp.gmail.com with ESMTPSA id f130sm13010599qke.37.2021.06.08.18.14.03 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 08 Jun 2021 18:14:03 -0700 (PDT) To: gcc-patches Subject: [PATCH] Improvements to fur_source interface class, enhanced stmt folding options. Message-ID: Date: Tue, 8 Jun 2021 21:14:02 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.10.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-CA X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Andrew MacLeod via Gcc-patches From: Andrew MacLeod Reply-To: Andrew MacLeod Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" I recently introduced the fur_source class as an intermediary between the Fold_Using_Ranges (FUR) class and where to pick up any ssa_names that it needs.    The initial idea was to abstract out a set of frequently changing parameters so the client fold routines wouldn't have to change every time we added a new way to do something with a statement.  Its also used by gori_compute when unwinding to allow for access to non-range-ops stmts when processing. That said, I hadn't really formalized it, so fold_using_ranges was accessing its members frequently.  We have encountered an opportunity to add something else which is useful,. but where the internals should be hidden. This patch a) formalizes the API (hiding the internals)  b) virtualizes the functions so we can use inheritance and not use conditions, and  c) adds the ability to pick up operands from a vector or list of ranges. There is no real visual difference to consumers since its an interface layer they don't normally see.  The net effect is now there are multiple versions of fold_stmt that all behave quite nicely: bool fold_range (irange &r, gimple *s, range_query *q = NULL); bool fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL); bool fold_range (irange &r, gimple *s, irange &r1); bool fold_range (irange &r, gimple *s, irange &r1, irange &r2); bool fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector); Now we can calculate ranges for a stmt,, ask for its range to be calculated as if it were on an edge, or we can supply one or more ranges to it to have the fold performed.  This latter set is akin to the old gimple_range_fold() routine we had, expect it only worked on a range-ops stmt, whereas this will work on any kind of stmt, including a PHI node. The routines have all been enhanced so that if a range_query is not provided, it will invoke the default range_query.   It will also invoke the default query if a list of ranges is supplied and it requires additional ranges to resolve the stmt being queried. There will probably be some additional tweaks going forward, especially since the list routines haven't really been tested. Aldy will be using them shortly, so that will be the test bed :-) Performance is basically a wash since there is a slight overhead for the virtual function calls, but it is offset by no longer have to do any conditional checks in the get_operand() routine. Bootstraps on x86_64-pc-linux-gnu with no regressions.  Pushed. Andrew commit 87f9ac937d6cfd81cbbe0a43518ba10781888d7c Author: Andrew MacLeod Date: Tue Jun 8 15:43:03 2021 -0400 Virtualize fur_source and turn it into a proper API. No more accessing the local info. Also add fur_source/fold_stmt where ranges are provided via being specified, or a vector to replace gimple_fold_range. * gimple-range-gori.cc (gori_compute::outgoing_edge_range_p): Use a fur_stmt source record. * gimple-range.cc (fur_source::get_operand): Generic range query. (fur_source::get_phi_operand): New. (fur_source::register_dependency): New. (fur_source::query): New. (class fur_edge): New. Edge source for operands. (fur_edge::fur_edge): New. (fur_edge::get_operand): New. (fur_edge::get_phi_operand): New. (fur_edge::query): New. (fur_stmt::fur_stmt): New. (fur_stmt::get_operand): New. (fur_stmt::get_phi_operand): New. (fur_stmt::query): New. (class fur_depend): New. Statement source and process dependencies. (fur_depend::fur_depend): New. (fur_depend::register_dependency): New. (class fur_list): New. List source for operands. (fur_list::fur_list): New. (fur_list::get_operand): New. (fur_list::get_phi_operand): New. (fold_range): New. Instantiate appropriate fur_source class and fold. (fold_using_range::range_of_range_op): Use new API. (fold_using_range::range_of_address): Ditto. (fold_using_range::range_of_phi): Ditto. (imple_ranger::fold_range_internal): Use fur_depend class. (fold_using_range::range_of_ssa_name_with_loop_info): Use new API. * gimple-range.h (class fur_source): Now a base class. (class fur_stmt): New. (fold_range): New prototypes. (fur_source::fur_source): Delete. diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 2c5360690db..09dcd694319 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -1008,7 +1008,7 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name, if (!stmt) return false; - fur_source src (&q, NULL, e, stmt); + fur_stmt src (stmt, &q); // If NAME can be calculated on the edge, use that. if (is_export_p (name, e->src)) diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index db8419bc4c6..b534b8e0a2c 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -49,19 +49,284 @@ along with GCC; see the file COPYING3. If not see // Evaluate expression EXPR using the source information the class was // instantiated with. Place the result in R, and return TRUE. If a range -// cannot be calcluated, return FALSE. +// cannot be calculated, return FALSE. bool fur_source::get_operand (irange &r, tree expr) { - // First look for a stmt. - if (m_stmt) - return m_query->range_of_expr (r, expr, m_stmt); + return get_range_query (cfun)->range_of_expr (r, expr); +} + +// Evaluate EXPR for this stmt as a PHI argument on edge E. Use the current +// range_query to get the range on the edge. + +bool +fur_source::get_phi_operand (irange &r, tree expr, edge e) +{ + return get_range_query (cfun)->range_on_edge (r, e, expr); +} + +// Default is to not register any dependencies from fold_using_range. + +void +fur_source::register_dependency (tree lhs ATTRIBUTE_UNUSED, + tree rhs ATTRIBUTE_UNUSED) +{ +} + +// Default object is the current range query. + +range_query * +fur_source::query () +{ + return get_range_query (cfun); +} + +// This version of fur_source will pick a range up off an edge. - // Finally must be on an edge. +class fur_edge : public fur_source +{ +public: + fur_edge (edge e, range_query *q = NULL); + virtual bool get_operand (irange &r, tree expr) OVERRIDE; + virtual bool get_phi_operand (irange &r, tree expr, edge e) OVERRIDE; + virtual range_query *query () OVERRIDE; +private: + range_query *m_query; + edge m_edge; +}; + +// Instantiate an edge based fur_source. + +inline +fur_edge::fur_edge (edge e, range_query *q) +{ + m_edge = e; + if (q) + m_query = q; + else + m_query = get_range_query (cfun); +} + +// Get the value of EXPR on edge m_edge. + +bool +fur_edge::get_operand (irange &r, tree expr) +{ return m_query->range_on_edge (r, m_edge, expr); } +// Evaluate EXPR for this stmt as a PHI argument on edge E. Use the current +// range_query to get the range on the edge. + +bool +fur_edge::get_phi_operand (irange &r, tree expr, edge e) +{ + // edge to edge recalculations not supoprted yet, until we sort it out. + gcc_checking_assert (e == m_edge); + return m_query->range_on_edge (r, e, expr); +} + +// Return the current range_query object. + +range_query * +fur_edge::query () +{ + return m_query; +} + + +// Instantiate a stmt based fur_source. + + +fur_stmt::fur_stmt (gimple *s, range_query *q) +{ + m_stmt= s; + if (q) + m_query = q; + else + m_query = get_global_range_query (); +} + +// Retirenve range of EXPR as it occurs as a use on stmt M_STMT. + +bool +fur_stmt::get_operand (irange &r, tree expr) +{ + return m_query->range_of_expr (r, expr, m_stmt); +} + +// Evaluate EXPR for this stmt as a PHI argument on edge E. Use the current +// range_query to get the range on the edge. + +bool +fur_stmt::get_phi_operand (irange &r, tree expr, edge e) +{ + // Pick up the range of expr from edge E. + fur_edge e_src (e, m_query); + return e_src.get_operand (r, expr); +} + +// Return the current range_query object. + +range_query * +fur_stmt::query () +{ + return m_query; +} + +// This version of fur_source will pick a range from a stmt, and register +// also dependencies via a gori_compute object. This is mostly an internal API. + +class fur_depend : public fur_stmt +{ +public: + fur_depend (gimple *s, gori_compute *gori, range_query *q = NULL); + virtual void register_dependency (tree lhs, tree rhs) OVERRIDE; +private: + gori_compute *m_gori; +}; + +// Instantiate a stmt based fur_source witrh a GORI object +inline +fur_depend::fur_depend (gimple *s, gori_compute *gori, range_query *q) + : fur_stmt (s, q) +{ + gcc_checking_assert (gori); + m_gori = gori; +} + + +// find and add any dependnecy between LHS and RHS + +void +fur_depend::register_dependency (tree lhs, tree rhs) +{ + m_gori->register_dependency (lhs, rhs); +} + + +// This version of fur_source will pick a range up from a list of ranges +// supplied by the caller. + +class fur_list : public fur_source +{ +public: + fur_list (irange &r1); + fur_list (irange &r1, irange &r2); + fur_list (unsigned num, irange *list); + virtual bool get_operand (irange &r, tree expr) OVERRIDE; + virtual bool get_phi_operand (irange &r, tree expr, edge e) OVERRIDE; +private: + int_range_max m_local[2]; + irange *m_list; + unsigned m_index; + unsigned m_limit; +}; + +// One range supplied for unary operations. + +fur_list::fur_list (irange &r1) +{ + m_list = m_local; + m_index = 0; + m_limit = 1; + m_local[0] = r1; +} + +// Two ranges supplied for binary operations. + +fur_list::fur_list (irange &r1, irange &r2) +{ + m_list = m_local; + m_index = 0; + m_limit = 2; + m_local[0] = r1; + m_local[0] = r2; +} + +// Arbitrary number of ranges in a vector. + +fur_list::fur_list (unsigned num, irange *list) +{ + m_list = list; + m_index = 0; + m_limit = num; +} + +// Get the next operand from the vector, ensure types are compatible, + +bool +fur_list::get_operand (irange &r, tree expr) +{ + if (m_index >= m_limit) + return get_range_query (cfun)->range_of_expr (r, expr); + r = m_list[m_index++]; + gcc_checking_assert (range_compatible_p (TREE_TYPE (expr), r.type ())); + return true; +} + +// This will simply pick the next operand from the vector. +bool +fur_list::get_phi_operand (irange &r, tree expr, edge e ATTRIBUTE_UNUSED) +{ + return get_operand (r, expr); +} + +// Fold stmt S into range R using R1 as the first operand. + +bool +fold_range (irange &r, gimple *s, irange &r1) +{ + fold_using_range f; + fur_list src (r1); + return f.fold_stmt (r, s, src); +} + +// Fold stmt S into range R using R1 and R2 as the first two operands. + +bool +fold_range (irange &r, gimple *s, irange &r1, irange &r2) +{ + fold_using_range f; + fur_list src (r1, r2); + return f.fold_stmt (r, s, src); +} + + +// Fold stmt S into range R using NUM_ELEMENTS from VECTOR as the initial +// operands encountered. + +bool +fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector) +{ + fold_using_range f; + fur_list src (num_elements, vector); + return f.fold_stmt (r, s, src); +} + + +// Fold stmt S into range R using range query Q. + +bool +fold_range (irange &r, gimple *s, range_query *q) +{ + fold_using_range f; + fur_stmt src (s, q); + return f.fold_stmt (r, s, src); +} + +// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE. + +bool +fold_range (irange &r, gimple *s, edge on_edge, range_query *q) +{ + fold_using_range f; + fur_edge src (on_edge, q); + return f.fold_stmt (r, s, src); +} + +// ------------------------------------------------------------------------- // Adjust the range for a pointer difference where the operands came // from a memchr. @@ -375,17 +640,17 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) // Fold range, and register any dependency if available. int_range<2> r2 (type); handler->fold_range (r, type, range1, r2); - if (lhs && src.m_gori) - src.m_gori->register_dependency (lhs, op1); + if (lhs) + src.register_dependency (lhs, op1); } else if (src.get_operand (range2, op2)) { // Fold range, and register any dependency if available. handler->fold_range (r, type, range1, range2); - if (lhs && src.m_gori) + if (lhs) { - src.m_gori->register_dependency (lhs, op1); - src.m_gori->register_dependency (lhs, op2); + src.register_dependency (lhs, op1); + src.register_dependency (lhs, op2); } } else @@ -425,8 +690,8 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src) { tree ssa = TREE_OPERAND (base, 0); tree lhs = gimple_get_lhs (stmt); - if (src.m_gori && lhs && gimple_range_ssa_p (ssa)) - src.m_gori->register_dependency (lhs, ssa); + if (lhs && gimple_range_ssa_p (ssa)) + src.register_dependency (lhs, ssa); gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa))); src.get_operand (r, ssa); range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt))); @@ -503,19 +768,12 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) edge e = gimple_phi_arg_edge (phi, x); // Register potential dependencies for stale value tracking. - if (src.m_gori && gimple_range_ssa_p (arg)) - src.m_gori->register_dependency (phi_def, arg); + if (gimple_range_ssa_p (arg)) + src.register_dependency (phi_def, arg); // Get the range of the argument on its edge. - fur_source e_src (src.m_query, e); - e_src.get_operand (arg_range, arg); + src.get_phi_operand (arg_range, arg, e); // If we're recomputing the argument elsewhere, try to refine it. - if (src.m_stmt != phi) - { - int_range_max tmp; - e_src.get_operand (tmp, arg); - arg_range.intersect (tmp); - } r.union_ (arg_range); // Once the value reaches varying, stop looking. if (r.varying_p ()) @@ -1012,7 +1270,7 @@ bool gimple_ranger::fold_range_internal (irange &r, gimple *s, tree name) { fold_using_range f; - fur_source src (this, &(gori ()), NULL, s); + fur_depend src (s, &(gori ()), this); return f.fold_stmt (r, s, src, name); } @@ -1191,22 +1449,18 @@ fold_using_range::range_of_ssa_name_with_loop_info (irange &r, tree name, { gcc_checking_assert (TREE_CODE (name) == SSA_NAME); tree min, max, type = TREE_TYPE (name); - if (bounds_of_var_in_loop (&min, &max, src.m_query, l, phi, name)) + if (bounds_of_var_in_loop (&min, &max, src.query (), l, phi, name)) { if (TREE_CODE (min) != INTEGER_CST) { - if (src.m_query - && src.m_query->range_of_expr (r, min, phi) - && !r.undefined_p ()) + if (src.query ()->range_of_expr (r, min, phi) && !r.undefined_p ()) min = wide_int_to_tree (type, r.lower_bound ()); else min = vrp_val_min (type); } if (TREE_CODE (max) != INTEGER_CST) { - if (src.m_query - && src.m_query->range_of_expr (r, max, phi) - && !r.undefined_p ()) + if (src.query ()->range_of_expr (r, max, phi) && !r.undefined_p ()) max = wide_int_to_tree (type, r.upper_bound ()); else max = vrp_val_max (type); diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 02b891fad69..9ac779a720c 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -73,28 +73,45 @@ protected: ranger_cache m_cache; }; -// Source of an operand for fold_using_range. -// It can specify a stmt or and edge, or thru an internal API which uses -// the ranger cache. -// Its primary function is to retreive an operand from the source via a -// call thru the range_query object. +// Source of all operands for fold_using_range and gori_compute. +// It abstracts out the source of an operand so it can come from a stmt or +// and edge or anywhere a derived classof fur_source wants. class fur_source { - friend class fold_using_range; public: - inline fur_source (range_query *q, edge e); - inline fur_source (range_query *q, gimple *s); - inline fur_source (range_query *q, gori_compute *g, edge e, gimple *s); - bool get_operand (irange &r, tree expr); -protected: - gori_compute *m_gori; + virtual bool get_operand (irange &r, tree expr); + virtual bool get_phi_operand (irange &r, tree expr, edge e); + virtual void register_dependency (tree lhs, tree rhs); + virtual range_query *query (); +}; + +// fur_stmt is the specification for drawing an operand from range_query Q +// via a range_of_Expr call on stmt S. + +class fur_stmt : public fur_source +{ +public: + fur_stmt (gimple *s, range_query *q = NULL); + virtual bool get_operand (irange &r, tree expr) OVERRIDE; + virtual bool get_phi_operand (irange &r, tree expr, edge e) OVERRIDE; + virtual range_query *query () OVERRIDE; +private: range_query *m_query; - edge m_edge; gimple *m_stmt; }; +// Fold stmt S into range R using range query Q. +bool fold_range (irange &r, gimple *s, range_query *q = NULL); +// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE. +bool fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL); +// These routines allow you to specify the operands to use when folding. +// Any excess queries will be drawn from the current range_query. +bool fold_range (irange &r, gimple *s, irange &r1); +bool fold_range (irange &r, gimple *s, irange &r1, irange &r2); +bool fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector); + // This class uses ranges to fold a gimple statement producinf a range for // the LHS. The source of all operands is supplied via the fur_source class // which provides a range_query as well as a source location and any other @@ -119,64 +136,6 @@ protected: }; -// Create a source for a query on an edge. - -inline -fur_source::fur_source (range_query *q, edge e) -{ - m_query = q; - m_gori = NULL; - m_edge = e; - m_stmt = NULL; -} - -// Create a source for a query at a statement. - -inline -fur_source::fur_source (range_query *q, gimple *s) -{ - m_query = q; - m_gori = NULL; - m_edge = NULL; - m_stmt = s; -} - -// Create a source for Ranger. THis can recalculate from a different location -// and can also set the dependency information as appropriate when invoked. - -inline -fur_source::fur_source (range_query *q, gori_compute *g, edge e, gimple *s) -{ - m_query = q; - m_gori = g; - m_edge = e; - m_stmt = s; -} - -// Fold stmt S into range R using range query Q. - -inline bool -fold_range (irange &r, gimple *s, range_query *q = NULL) -{ - fold_using_range f; - if (q == NULL) - q = get_global_range_query (); - fur_source src (q, s); - return f.fold_stmt (r, s, src); -} - -// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE. - -inline bool -fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL) -{ - fold_using_range f; - if (q == NULL) - q = get_global_range_query (); - fur_source src (q, on_edge); - return f.fold_stmt (r, s, src); -} - // These routines provide a GIMPLE interface to the range-ops code. extern tree gimple_range_operand1 (const gimple *s); extern tree gimple_range_operand2 (const gimple *s);