From patchwork Tue Aug 17 23:30:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 1517875 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=8.43.85.97; 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=mCNpTpQ+; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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 4Gq6k21ktbz9sWq for ; Wed, 18 Aug 2021 09:31:36 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A3912382CC29 for ; Tue, 17 Aug 2021 23:31:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A3912382CC29 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1629243092; bh=nUkZtAjL0tHiLwE6zqdNyQpXAlLZdWDy80dUxiuAPqE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=mCNpTpQ+6q3dueqrD0kl6RcfOHPgUzlsDxvP1EEkpD6cZpmUIxGVdPXdBOVKSLrfY 5i1eBFjM7SzE61bowj2ShqJu1/24paWRy96MH2Fc+CNqHjXR6grGy1FYmyM01BSEam kIRI4ttHcOSOiKWOVi5Rc1E/TRujnrOsDuLQ2u5Y= 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 B610A38438A3 for ; Tue, 17 Aug 2021 23:30:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B610A38438A3 Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-25-MAztZDT-NQCupLWoyCC1jg-1; Tue, 17 Aug 2021 19:30:57 -0400 X-MC-Unique: MAztZDT-NQCupLWoyCC1jg-1 Received: by mail-qk1-f197.google.com with SMTP id p123-20020a378d810000b02903ad5730c883so395115qkd.22 for ; Tue, 17 Aug 2021 16:30:57 -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=nUkZtAjL0tHiLwE6zqdNyQpXAlLZdWDy80dUxiuAPqE=; b=r5WZ3lf97XhPx/Q2PCwBQgY65k1PCEdFPtktym8d/qkENRiCar8ftlwlOGEv1Siu8R hQUo8uqKQwFTcI4NpSsVFGA7A+b/QDSwoguKzjMwsdFC27a1nt20OFU5iXGTyH2TonsU lkl7aI2HePW9buJ3lFGcwaerrO4ZvTE9y8NtgfxxcgqG5SuWu0uW6km5/FT14IYvQgfN zk+N1vTYUdHJG1nJl7NE1j40Ok4DvxMtX/koZ6kt3oFGNBs5Hv1xWfjQOn2+HyBExiP8 ghBSdGKembhvbPSy89f0ORHJwyBfLVOEEvKBDDz5ZZ1eds7I98wZ+TLPNrc1COIEVQkQ Z8aA== X-Gm-Message-State: AOAM531PhO2N9OSZa8kkn0ubGJxKWuMZUEUPr3bBEPmTid3OCDcSi074 e4OX5AYVSw2v+50VF3UOTwVW8oBaW4iMva359XVmAx9EFaxSJspC0rWn/g+CYkOLUSCXY5oRkC/ wJQ17joOoOsKH90RddA== X-Received: by 2002:a37:5d42:: with SMTP id r63mr6475280qkb.470.1629243057205; Tue, 17 Aug 2021 16:30:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyQMdn7JjtmYtk7el0Hd6NNW1qW+20qoqm/5dAp1XmvaZtkRl2N2OYt3wP3q2ZX/SQyNvSfQg== X-Received: by 2002:a37:5d42:: with SMTP id r63mr6475265qkb.470.1629243057005; Tue, 17 Aug 2021 16:30:57 -0700 (PDT) Received: from [192.168.0.102] ([104.219.123.55]) by smtp.gmail.com with ESMTPSA id 37sm1969502qtf.33.2021.08.17.16.30.55 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 17 Aug 2021 16:30:56 -0700 (PDT) To: gcc-patches Subject: [COMMITTED 1/3] Abstract range tracing routines into a class. Message-ID: Date: Tue, 17 Aug 2021 19:30:54 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.12.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-CA X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, BODY_8BITS, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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 originally implemented range tracing as a derived class so I wouldn't mess-up the basic range routines in ranger.  Having tracing enabled this way had its advantages, but also had some disadvantages, such as requiring a different class to be instantiated when we want to turn on tracing. Regardless,there is an ongoing need to be able to debug range-ops and GORI. It seems that the tracing mechanism can be utilized there as well, so this patch abstracts the tracing routines into a class and re-implements range tracing in ranger using it. If you have never looked at a ranger trace, it looks something like this (an early part of a run where the backedge hasn't been resolved fully yet) : 42                 range_of_stmt (j_32) at stmt j_32 = j_14 + 1; 43                   range_of_expr(j_14) at stmt j_32 = j_14 + 1; 44                     range_on_entry (j_14) to BB 8 45                       range_of_stmt (j_14) at stmt j_14 = PHI <0(19), j_32(8)>                          TRUE : (45)  cached (j_14) int VARYING                        TRUE : (44) range_on_entry (j_14) int [-INF, 31]                      TRUE : (43) range_of_expr (j_14) int [-INF, 31]  Registering value_relation (j_32 > j_14) (bb8) at j_32 = j_14 + 1;                    TRUE : (42) range_of_stmt (j_32) int [-2147483647, 32] It follows all the various range query calls and shows ranges as they are requested/calculated. Request 42 is asking for the range of j_32 on it's defining statement. That is followed by request 43 which asks for the range of j_14 on that statement, and the series of requests that go off and find that value. Eventually we see the TRUE returned for request 43 and the range of j_14 was determined to be int [-INF, 31]. When that is applied to request 42, we see true returned and [-INF, 31] + 1 is calculated as int [-2147483647, 32] This allows us to trace the range calculations based on each request, and see where something has gone wrong. Furthermore, the trace index is now static, so the index is unique across the compilation unit, and a 'breakpoint' routine has been added to the range_tracer class which allows one to easily set a breakpoint on a specific index.  so within gdb,    b range_tracer::breakpoint if index == 43 Will cause the debugger to stop when we are beginning to process request 43... making it much easier to look around when something is wrong. Bootstrapped on x86_64-pc-linux-gnu  with no regressions. Pushed. Andrew From e68c8280fa2e1b7071378cfdd876155c73ec944f Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Fri, 30 Jul 2021 15:15:29 -0400 Subject: [PATCH 1/3] Abstract tracing routines into a class. Generalize range tracing into a class and integrae it with gimple_ranger. Remove the old derived trace_ranger class. * Makefile.in (OBJS): Add gimple-range-trace.o. * gimple-range-cache.h (enable_new_values): Remove unused prototype. * gimple-range-fold.cc: Adjust headers. * gimple-range-trace.cc: New. * gimple-range-trace.h: New. * gimple-range.cc (gimple_ranger::gimple_ranger): Enable tracer. (gimple_ranger::range_of_expr): Add tracing. (gimple_ranger::range_on_entry): Ditto. (gimple_ranger::range_on_exit): Ditto. (gimple_ranger::range_on_edge): Ditto. (gimple_ranger::fold_range_internal): Ditto. (gimple_ranger::dump_bb): Do not calculate edge range twice. (trace_ranger::*): Remove. (enable_ranger): Never create a trace_ranger. (debug_seed_ranger): Move to gimple-range-trace.cc. (dump_ranger): Ditto. (debug_ranger): Ditto. * gimple-range.h: Include gimple-range-trace.h. (range_on_entry, range_on_exit): No longer virtual. (class trace_ranger): Remove. (DEBUG_RANGE_CACHE): Move to gimple-range-trace.h. --- gcc/Makefile.in | 1 + gcc/gimple-range-cache.h | 1 - gcc/gimple-range-fold.cc | 4 +- gcc/gimple-range-trace.cc | 206 ++++++++++++++++++++ gcc/gimple-range-trace.h | 64 +++++++ gcc/gimple-range.cc | 393 ++++++++++---------------------------- gcc/gimple-range.h | 34 +--- 7 files changed, 377 insertions(+), 326 deletions(-) create mode 100644 gcc/gimple-range-trace.cc create mode 100644 gcc/gimple-range-trace.h diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 6653e9e2142..9714fcaac37 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1406,6 +1406,7 @@ OBJS = \ gimple-range-edge.o \ gimple-range-fold.o \ gimple-range-gori.o \ + gimple-range-trace.o \ gimple-ssa-backprop.o \ gimple-ssa-evrp.o \ gimple-ssa-evrp-analyze.o \ diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h index 1e77c9bf3a9..3b55673fd29 100644 --- a/gcc/gimple-range-cache.h +++ b/gcc/gimple-range-cache.h @@ -103,7 +103,6 @@ public: bool get_non_stale_global_range (irange &r, tree name); void set_global_range (tree name, const irange &r); - bool enable_new_values (bool state); non_null_ref m_non_null; gori_compute m_gori; diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index d3e3e14ff64..94dd042721e 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -42,9 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "range.h" #include "value-query.h" #include "range-op.h" -#include "gimple-range-fold.h" -#include "gimple-range-edge.h" -#include "gimple-range-gori.h" +#include "gimple-range.h" // Construct a fur_source, and set the m_query field. fur_source::fur_source (range_query *q) diff --git a/gcc/gimple-range-trace.cc b/gcc/gimple-range-trace.cc new file mode 100644 index 00000000000..1feb978e928 --- /dev/null +++ b/gcc/gimple-range-trace.cc @@ -0,0 +1,206 @@ +/* Code for GIMPLE range trace and debugging related routines. + Copyright (C) 2019-2021 Free Software Foundation, Inc. + Contributed by Andrew MacLeod + and Aldy Hernandez . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "tree.h" +#include "gimple.h" +#include "ssa.h" +#include "gimple-pretty-print.h" +#include "gimple-iterator.h" +#include "tree-cfg.h" +#include "fold-const.h" +#include "tree-cfg.h" +#include "cfgloop.h" +#include "tree-scalar-evolution.h" +#include "gimple-range.h" + + +// Breakpoint to trap at a specific index. From GDB, this provides a simple +// place to put a breakpoint to stop at a given trace line. +// ie. b range_tracer::breakpoint if index == 45678 + +void +range_tracer::breakpoint (unsigned index ATTRIBUTE_UNUSED) +{ +} + +// Construct a range_tracer with component NAME. + +range_tracer::range_tracer (const char *name) +{ + gcc_checking_assert (strlen(name) < name_len -1); + strcpy (component, name); + indent = 0; + tracing = false; +} + +// This routine does the initial line spacing/indenting for a trace. +// If BLANKS is false, then IDX is printed, otherwise spaces. + +void +range_tracer::print_prefix (unsigned idx, bool blanks) +{ + // Print counter index as well as INDENT spaces. + if (!blanks) + fprintf (dump_file, "%-7u ", idx); + else + fprintf (dump_file, " "); + fprintf (dump_file, "%s ", component); + unsigned x; + for (x = 0; x< indent; x++) + fputc (' ', dump_file); + +} +// If dumping, return the next call index and print the prefix for the next +// output line. If not, retrurn 0. +// Counter is static to monotonically increase across the compilation unit. + +unsigned +range_tracer::do_header (const char *str) +{ + static unsigned trace_count = 0; + + unsigned idx = ++trace_count; + print_prefix (idx, false); + fprintf (dump_file, "%s", str); + indent += bump; + breakpoint (idx); + return idx; +} + +// Print a line without starting or ending a trace. + +void +range_tracer::print (unsigned counter, const char *str) +{ + print_prefix (counter, true); + fprintf (dump_file, "%s", str); +} + +// End a trace and print the CALLER, NAME, and RESULT and range R, + +void +range_tracer::trailer (unsigned counter, const char *caller, bool result, + tree name, const irange &r) +{ + gcc_checking_assert (tracing && counter != 0); + + indent -= bump; + print_prefix (counter, true); + fputs(result ? "TRUE : " : "FALSE : ", dump_file); + fprintf (dump_file, "(%u) ", counter); + fputs (caller, dump_file); + fputs (" (",dump_file); + if (name) + print_generic_expr (dump_file, name, TDF_SLIM); + fputs (") ",dump_file); + if (result) + { + r.dump (dump_file); + fputc('\n', dump_file); + } + else + fputc('\n', dump_file); +} + +// ========================================= +// Debugging helpers. +// ========================================= + +// Query all statements in the IL to precalculate computable ranges in RANGER. + +static DEBUG_FUNCTION void +debug_seed_ranger (gimple_ranger &ranger) +{ + // Recalculate SCEV to make sure the dump lists everything. + if (scev_initialized_p ()) + { + scev_finalize (); + scev_initialize (); + } + + basic_block bb; + int_range_max r; + gimple_stmt_iterator gsi; + FOR_EACH_BB_FN (bb, cfun) + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + + if (is_gimple_debug (stmt)) + continue; + + ranger.range_of_stmt (r, stmt); + } +} + +// Dump all that ranger knows for the current function. + +DEBUG_FUNCTION void +dump_ranger (FILE *out) +{ + gimple_ranger ranger; + debug_seed_ranger (ranger); + ranger.dump (out); +} + +DEBUG_FUNCTION void +debug_ranger () +{ + dump_ranger (stderr); +} + +// Dump all that ranger knows on a path of BBs. +// +// Note that the blocks are in reverse order, thus the exit block is +// path[0]. + +DEBUG_FUNCTION void +dump_ranger (FILE *dump_file, const vec &path) +{ + if (path.length () == 0) + { + fprintf (dump_file, "empty\n"); + return; + } + + gimple_ranger ranger; + debug_seed_ranger (ranger); + + unsigned i = path.length (); + do + { + i--; + ranger.dump_bb (dump_file, path[i]); + } + while (i > 0); +} + +DEBUG_FUNCTION void +debug_ranger (const vec &path) +{ + dump_ranger (stderr, path); +} + +#include "gimple-range-tests.cc" diff --git a/gcc/gimple-range-trace.h b/gcc/gimple-range-trace.h new file mode 100644 index 00000000000..6f89fcccf4f --- /dev/null +++ b/gcc/gimple-range-trace.h @@ -0,0 +1,64 @@ +/* Header file for the GIMPLE range tracing/debugging facilties. + Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Andrew MacLeod + and Aldy Hernandez . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_GIMPLE_RANGE_TRACE_H +#define GCC_GIMPLE_RANGE_TRACE_H + +// This class manages range tracing for the ranger and gori components. +// Tracing will provide a unique integer index whenever a new trace +// is started. This can be used to identify where a calculation has gone wrong. + +class range_tracer +{ +public: + range_tracer (const char *name = ""); + unsigned header (const char *str); + void trailer (unsigned counter, const char *caller, bool result, tree name, + const irange &r); + void print (unsigned counter, const char *str); + inline void enable_trace () { tracing = true; } + inline void disable_trace () { tracing = false; } + virtual void breakpoint (unsigned index); +private: + unsigned do_header (const char *str); + void print_prefix (unsigned idx, bool blanks); + static const unsigned bump = 2; + unsigned indent; + static const unsigned name_len = 100; + char component[name_len]; + bool tracing; +}; + + +// If tracing is enabled, start a new trace header, returning the trace index. +// Otherwise return 0. + +inline unsigned +range_tracer::header (const char *str) +{ + if (tracing) + return do_header (str); + return 0; +} + +#define DEBUG_RANGE_CACHE (dump_file && (param_evrp_mode & EVRP_MODE_DEBUG)) + +#endif // GCC_GIMPLE_RANGE_TRACE_H diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index b210787d0b7..60b7d3a59cd 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -35,46 +35,61 @@ along with GCC; see the file COPYING3. If not see #include "tree-scalar-evolution.h" #include "gimple-range.h" -gimple_ranger::gimple_ranger () +gimple_ranger::gimple_ranger () : tracer ("") { // If the cache has a relation oracle, use it. m_oracle = m_cache.oracle (); + if (dump_file && (param_evrp_mode & EVRP_MODE_TRACE)) + tracer.enable_trace (); } bool gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt) { + unsigned idx; if (!gimple_range_ssa_p (expr)) return get_tree_range (r, expr, stmt); + if ((idx = tracer.header ("range_of_expr("))) + { + print_generic_expr (dump_file, expr, TDF_SLIM); + fputs (")", dump_file); + if (stmt) + { + fputs (" at stmt ", dump_file); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + else + fputs ("\n", dump_file); + } + // If there is no statement, just get the global value. if (!stmt) { if (!m_cache.get_global_range (r, expr)) r = gimple_range_global (expr); - return true; } - // For a debug stmt, pick the best value currently available, do not // trigger new value calculations. PR 100781. - if (is_gimple_debug (stmt)) + else if (is_gimple_debug (stmt)) + m_cache.range_of_expr (r, expr, stmt); + else { - m_cache.range_of_expr (r, expr, stmt); - return true; - } - basic_block bb = gimple_bb (stmt); - gimple *def_stmt = SSA_NAME_DEF_STMT (expr); + basic_block bb = gimple_bb (stmt); + gimple *def_stmt = SSA_NAME_DEF_STMT (expr); - // If name is defined in this block, try to get an range from S. - if (def_stmt && gimple_bb (def_stmt) == bb) - { - range_of_stmt (r, def_stmt, expr); - m_cache.m_non_null.adjust_range (r, expr, bb, true); + // If name is defined in this block, try to get an range from S. + if (def_stmt && gimple_bb (def_stmt) == bb) + { + range_of_stmt (r, def_stmt, expr); + m_cache.m_non_null.adjust_range (r, expr, bb, true); + } + // Otherwise OP comes from outside this block, use range on entry. + else + range_on_entry (r, bb, expr); } - else - // Otherwise OP comes from outside this block, use range on entry. - range_on_entry (r, bb, expr); - + if (idx) + tracer.trailer (idx, "range_of_expr", true, expr, r); return true; } @@ -86,6 +101,13 @@ gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name) int_range_max entry_range; gcc_checking_assert (gimple_range_ssa_p (name)); + unsigned idx; + if ((idx = tracer.header ("range_on_entry ("))) + { + print_generic_expr (dump_file, name, TDF_SLIM); + fprintf (dump_file, ") to BB %d\n", bb->index); + } + // Start with any known range range_of_stmt (r, SSA_NAME_DEF_STMT (name), name); @@ -94,6 +116,9 @@ gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name) r.intersect (entry_range); m_cache.m_non_null.adjust_range (r, name, bb, true); + + if (idx) + tracer.trailer (idx, "range_on_entry", true, name, r); } // Calculate the range for NAME at the end of block BB and return it in R. @@ -106,6 +131,13 @@ gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name) gcc_checking_assert (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)); gcc_checking_assert (gimple_range_ssa_p (name)); + unsigned idx; + if ((idx = tracer.header ("range_on_exit ("))) + { + print_generic_expr (dump_file, name, TDF_SLIM); + fprintf (dump_file, ") from BB %d\n", bb->index); + } + gimple *s = SSA_NAME_DEF_STMT (name); basic_block def_bb = gimple_bb (s); // If this is not the definition block, get the range on the last stmt in @@ -119,6 +151,9 @@ gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name) range_on_entry (r, bb, name); gcc_checking_assert (r.undefined_p () || range_compatible_p (r.type (), TREE_TYPE (name))); + + if (idx) + tracer.trailer (idx, "range_on_exit", true, name, r); } // Calculate a range for NAME on edge E and return it in R. @@ -133,6 +168,13 @@ gimple_ranger::range_on_edge (irange &r, edge e, tree name) if (!gimple_range_ssa_p (name)) return range_of_expr (r, name); + unsigned idx; + if ((idx = tracer.header ("range_on_edge ("))) + { + print_generic_expr (dump_file, name, TDF_SLIM); + fprintf (dump_file, ") on edge %d->%d\n", e->src->index, e->dest->index); + } + range_on_exit (r, e->src, name); gcc_checking_assert (r.undefined_p () || range_compatible_p (r.type(), TREE_TYPE (name))); @@ -141,6 +183,8 @@ gimple_ranger::range_on_edge (irange &r, edge e, tree name) if (m_cache.range_on_edge (edge_range, e, name)) r.intersect (edge_range); + if (idx) + tracer.trailer (idx, "range_on_edge", true, name, r); return true; } @@ -163,33 +207,50 @@ gimple_ranger::fold_range_internal (irange &r, gimple *s, tree name) bool gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name) { + bool res; r.set_undefined (); + unsigned idx; + if ((idx = tracer.header ("range_of_stmt ("))) + { + if (name) + print_generic_expr (dump_file, name, TDF_SLIM); + fputs (") at stmt ", dump_file); + print_gimple_stmt (dump_file, s, 0, TDF_SLIM); + } + if (!name) name = gimple_get_lhs (s); // If no name, simply call the base routine. if (!name) - return fold_range_internal (r, s, NULL_TREE); - - if (!gimple_range_ssa_p (name)) - return false; - + res = fold_range_internal (r, s, NULL_TREE); + else if (!gimple_range_ssa_p (name)) + res = false; // Check if the stmt has already been processed, and is not stale. - if (m_cache.get_non_stale_global_range (r, name)) - return true; - - // Otherwise calculate a new value. - int_range_max tmp; - fold_range_internal (tmp, s, name); - - // Combine the new value with the old value. This is required because - // the way value propagation works, when the IL changes on the fly we - // can sometimes get different results. See PR 97741. - r.intersect (tmp); - m_cache.set_global_range (name, r); + else if (m_cache.get_non_stale_global_range (r, name)) + { + if (idx) + tracer.trailer (idx, " cached", true, name, r); + return true; + } + else + { + // Otherwise calculate a new value. + int_range_max tmp; + fold_range_internal (tmp, s, name); + + // Combine the new value with the old value. This is required because + // the way value propagation works, when the IL changes on the fly we + // can sometimes get different results. See PR 97741. + r.intersect (tmp); + m_cache.set_global_range (name, r); + res = true; + } - return true; + if (idx) + tracer.trailer (idx, "range_of_stmt", res, name, r); + return res; } // This routine will export whatever global ranges are known to GCC @@ -243,7 +304,7 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb) unsigned x; edge_iterator ei; edge e; - int_range_max range; + int_range_max range, tmp_range; fprintf (f, "\n=========== BB %d ============\n", bb->index); m_cache.dump_bb (f, bb); @@ -282,10 +343,9 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb) // the on entry cache for either end of the edge is // set. if ((s && bb == gimple_bb (s)) || - m_cache.block_range (range, bb, name, false) || - m_cache.block_range (range, e->dest, name, false)) + m_cache.block_range (tmp_range, bb, name, false) || + m_cache.block_range (tmp_range, e->dest, name, false)) { - m_cache.range_on_edge (range, e, name); if (!range.varying_p ()) { fprintf (f, "%d->%d ", e->src->index, @@ -321,182 +381,12 @@ gimple_ranger::dump (FILE *f) m_cache.dump (f); } -// trace_ranger implementation. - - -trace_ranger::trace_ranger () -{ - indent = 0; - trace_count = 0; -} - -// If dumping, return true and print the prefix for the next output line. - -bool -trace_ranger::dumping (unsigned counter, bool trailing) -{ - if (dump_file && (dump_flags & TDF_DETAILS)) - { - // Print counter index as well as INDENT spaces. - if (!trailing) - fprintf (dump_file, " %-7u ", counter); - else - fprintf (dump_file, " "); - unsigned x; - for (x = 0; x< indent; x++) - fputc (' ', dump_file); - return true; - } - return false; -} - -// After calling a routine, if dumping, print the CALLER, NAME, and RESULT, -// returning RESULT. - -bool -trace_ranger::trailer (unsigned counter, const char *caller, bool result, - tree name, const irange &r) -{ - if (dumping (counter, true)) - { - indent -= bump; - fputs(result ? "TRUE : " : "FALSE : ", dump_file); - fprintf (dump_file, "(%u) ", counter); - fputs (caller, dump_file); - fputs (" (",dump_file); - if (name) - print_generic_expr (dump_file, name, TDF_SLIM); - fputs (") ",dump_file); - if (result) - { - r.dump (dump_file); - fputc('\n', dump_file); - } - else - fputc('\n', dump_file); - // Marks the end of a request. - if (indent == 0) - fputc('\n', dump_file); - } - return result; -} - -// Tracing version of range_on_edge. Call it with printing wrappers. - -bool -trace_ranger::range_on_edge (irange &r, edge e, tree name) -{ - unsigned idx = ++trace_count; - if (dumping (idx)) - { - fprintf (dump_file, "range_on_edge ("); - print_generic_expr (dump_file, name, TDF_SLIM); - fprintf (dump_file, ") on edge %d->%d\n", e->src->index, e->dest->index); - indent += bump; - } - - bool res = gimple_ranger::range_on_edge (r, e, name); - trailer (idx, "range_on_edge", true, name, r); - return res; -} - -// Tracing version of range_on_entry. Call it with printing wrappers. - -void -trace_ranger::range_on_entry (irange &r, basic_block bb, tree name) -{ - unsigned idx = ++trace_count; - if (dumping (idx)) - { - fprintf (dump_file, "range_on_entry ("); - print_generic_expr (dump_file, name, TDF_SLIM); - fprintf (dump_file, ") to BB %d\n", bb->index); - indent += bump; - } - - gimple_ranger::range_on_entry (r, bb, name); - - trailer (idx, "range_on_entry", true, name, r); -} - -// Tracing version of range_on_exit. Call it with printing wrappers. - -void -trace_ranger::range_on_exit (irange &r, basic_block bb, tree name) -{ - unsigned idx = ++trace_count; - if (dumping (idx)) - { - fprintf (dump_file, "range_on_exit ("); - print_generic_expr (dump_file, name, TDF_SLIM); - fprintf (dump_file, ") from BB %d\n", bb->index); - indent += bump; - } - - gimple_ranger::range_on_exit (r, bb, name); - - trailer (idx, "range_on_exit", true, name, r); -} - -// Tracing version of range_of_stmt. Call it with printing wrappers. - -bool -trace_ranger::range_of_stmt (irange &r, gimple *s, tree name) -{ - bool res; - unsigned idx = ++trace_count; - if (dumping (idx)) - { - fprintf (dump_file, "range_of_stmt ("); - if (name) - print_generic_expr (dump_file, name, TDF_SLIM); - fputs (") at stmt ", dump_file); - print_gimple_stmt (dump_file, s, 0, TDF_SLIM); - indent += bump; - } - - res = gimple_ranger::range_of_stmt (r, s, name); - - return trailer (idx, "range_of_stmt", res, name, r); -} - -// Tracing version of range_of_expr. Call it with printing wrappers. - -bool -trace_ranger::range_of_expr (irange &r, tree name, gimple *s) -{ - bool res; - unsigned idx = ++trace_count; - if (dumping (idx)) - { - fprintf (dump_file, "range_of_expr("); - print_generic_expr (dump_file, name, TDF_SLIM); - fputs (")", dump_file); - if (s) - { - fputs (" at stmt ", dump_file); - print_gimple_stmt (dump_file, s, 0, TDF_SLIM); - } - else - fputs ("\n", dump_file); - indent += bump; - } - - res = gimple_ranger::range_of_expr (r, name, s); - - return trailer (idx, "range_of_expr", res, name, r); -} - gimple_ranger * enable_ranger (struct function *fun) { gimple_ranger *r; - if (param_evrp_mode & EVRP_MODE_TRACE) - r = new trace_ranger; - else - r = new gimple_ranger; - + r = new gimple_ranger; fun->x_range_query = r; return r; @@ -509,84 +399,3 @@ disable_ranger (struct function *fun) fun->x_range_query = &global_ranges; } - -// ========================================= -// Debugging helpers. -// ========================================= - -// Query all statements in the IL to precalculate computable ranges in RANGER. - -static DEBUG_FUNCTION void -debug_seed_ranger (gimple_ranger &ranger) -{ - // Recalculate SCEV to make sure the dump lists everything. - if (scev_initialized_p ()) - { - scev_finalize (); - scev_initialize (); - } - - basic_block bb; - int_range_max r; - gimple_stmt_iterator gsi; - FOR_EACH_BB_FN (bb, cfun) - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - - if (is_gimple_debug (stmt)) - continue; - - ranger.range_of_stmt (r, stmt); - } -} - -// Dump all that ranger knows for the current function. - -DEBUG_FUNCTION void -dump_ranger (FILE *out) -{ - gimple_ranger ranger; - debug_seed_ranger (ranger); - ranger.dump (out); -} - -DEBUG_FUNCTION void -debug_ranger () -{ - dump_ranger (stderr); -} - -// Dump all that ranger knows on a path of BBs. -// -// Note that the blocks are in reverse order, thus the exit block is -// path[0]. - -DEBUG_FUNCTION void -dump_ranger (FILE *dump_file, const vec &path) -{ - if (path.length () == 0) - { - fprintf (dump_file, "empty\n"); - return; - } - - gimple_ranger ranger; - debug_seed_ranger (ranger); - - unsigned i = path.length (); - do - { - i--; - ranger.dump_bb (dump_file, path[i]); - } - while (i > 0); -} - -DEBUG_FUNCTION void -debug_ranger (const vec &path) -{ - dump_ranger (stderr, path); -} - -#include "gimple-range-tests.cc" diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index aa620393dea..41845b14fd6 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -22,10 +22,10 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_GIMPLE_RANGE_H #define GCC_GIMPLE_RANGE_H - #include "range.h" #include "value-query.h" #include "range-op.h" +#include "gimple-range-trace.h" #include "gimple-range-edge.h" #include "gimple-range-fold.h" #include "gimple-range-gori.h" @@ -43,7 +43,6 @@ along with GCC; see the file COPYING3. If not see // type is not supported, then false is returned. Non-statement // related methods return whatever the current global value is. - class gimple_ranger : public range_query { public: @@ -51,8 +50,8 @@ public: virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL) OVERRIDE; virtual bool range_of_expr (irange &r, tree name, gimple * = NULL) OVERRIDE; virtual bool range_on_edge (irange &r, edge e, tree name) OVERRIDE; - virtual void range_on_entry (irange &r, basic_block bb, tree name); - virtual void range_on_exit (irange &r, basic_block bb, tree name); + void range_on_entry (irange &r, basic_block bb, tree name); + void range_on_exit (irange &r, basic_block bb, tree name); void export_global_ranges (); inline gori_compute &gori () { return m_cache.m_gori; } virtual void dump (FILE *f) OVERRIDE; @@ -60,34 +59,9 @@ public: protected: bool fold_range_internal (irange &r, gimple *s, tree name); ranger_cache m_cache; + range_tracer tracer; }; - -// This class overloads the ranger routines to provide tracing facilties -// Entry and exit values to each of the APIs is placed in the dumpfile. - -class trace_ranger : public gimple_ranger -{ -public: - trace_ranger (); - virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE); - virtual bool range_of_expr (irange &r, tree name, gimple *s = NULL); - virtual bool range_on_edge (irange &r, edge e, tree name); - virtual void range_on_entry (irange &r, basic_block bb, tree name); - virtual void range_on_exit (irange &r, basic_block bb, tree name); -private: - static const unsigned bump = 2; - unsigned indent; - unsigned trace_count; // Current trace index count. - - bool dumping (unsigned counter, bool trailing = false); - bool trailer (unsigned counter, const char *caller, bool result, tree name, - const irange &r); -}; - -// Flag to enable debugging the various internal Caches. -#define DEBUG_RANGE_CACHE (dump_file && (param_evrp_mode & EVRP_MODE_DEBUG)) - extern gimple_ranger *enable_ranger (struct function *); extern void disable_ranger (struct function *); -- 2.17.2 From patchwork Tue Aug 17 23:31:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 1517876 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=TZ8zFuvn; 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 4Gq6lN669Qz9sWq for ; Wed, 18 Aug 2021 09:32:48 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 322E4382C43A for ; Tue, 17 Aug 2021 23:32:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 322E4382C43A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1629243166; bh=bKqVHTg820m1LzQEeCskpN1SPlMQ40uHhRsHqKKVxnQ=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=TZ8zFuvnuwft6GpnIc6JGHU3M5yKYc55uFynaAvDRjdX3je6Kt4OGrr/IwImtgM0Q lg0kPi7JksdPJnz4xhXS8fO5ypgL9GtNfoyWEKdr3Vi/iHEIk6bC0pnL7u9EXcjIHe ooG9/gy0TU9YcmkTwr9ZK+EpaA6FOjsa+06Nx19g= 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 [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 296CE3835821 for ; Tue, 17 Aug 2021 23:31:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 296CE3835821 Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-546-usOY2ftDPDejpmJ8bEzPNw-1; Tue, 17 Aug 2021 19:31:11 -0400 X-MC-Unique: usOY2ftDPDejpmJ8bEzPNw-1 Received: by mail-qv1-f71.google.com with SMTP id n5-20020a056214008500b0035b6a75b52eso779471qvr.3 for ; Tue, 17 Aug 2021 16:31:11 -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=bKqVHTg820m1LzQEeCskpN1SPlMQ40uHhRsHqKKVxnQ=; b=ip81TXL/PmoEDWMZkawaB0CNDTGdfjiDZbLPk8B6rbgctbVdVT88WGt5SiOp1bdmSY 8fQCmmHyvu9ps2C9/aAOUsT9ljo8ajpKVRn5jGQoa4uMQm3dFCfJqNDLEd/O5Al0sUdx fwbgPzmVdYELG/GxVdxgUhZMaEWG395rlFhIU2d5v/9prKolaikdDkguVHWb15D5NeEE 6X6SjtnUx/O1eaOaXIi1S488mI1s97qIeUqCWUaBPfQdWDOBbgbUKulcE6ECnHmg5UEd gvowwvhokw0mb9DzFstmQ/U203DIuyQvU68Kelz/TpHe5wk4iYLTKAKq9gKL8nvGjDOM CbUQ== X-Gm-Message-State: AOAM530hujIY4HUDE+2E18O9JVI53CuTZxzh2F6AQTNWprvkgJeEyzCZ I94zCoB9quIsSaN3/nK9z1xi1+cugIMRVnTT3UZKJZSX5VRZ6959rKgSlV+DVqHK+QNb9Iv1BjT OHx+VgQ9epowW3gR7MQ== X-Received: by 2002:a37:90b:: with SMTP id 11mr5150760qkj.419.1629243070974; Tue, 17 Aug 2021 16:31:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz5zu2WLOyvr5L1LyG2IKRcSOYyKpwfo1YQ1evtlZWok3PmXhu42GIBKJYTLJNePDKYiikmMA== X-Received: by 2002:a37:90b:: with SMTP id 11mr5150754qkj.419.1629243070845; Tue, 17 Aug 2021 16:31:10 -0700 (PDT) Received: from [192.168.0.102] ([104.219.123.55]) by smtp.gmail.com with ESMTPSA id p19sm1897697qtx.10.2021.08.17.16.31.09 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 17 Aug 2021 16:31:10 -0700 (PDT) To: gcc-patches Subject: [COMMITTED 2/3] Change evrp-mode options. Message-ID: Date: Tue, 17 Aug 2021 19:31:09 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.12.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.0 required=5.0 tests=BAYES_00, BODY_8BITS, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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" This patch alters the options for --param=evrp-mode=. It removes the option of tracing when in hybrid mode, and adds some extra discrimination. legacy/ranger/legacy-first/ranger-first are unchanged.  the default is still 'ranger' The modifications are: trace    : enable range tracing in ranger (this is the original trace) gori     : enable gori tracing (enabled in the final patch) cache    : separate out cache debugging.. in theory this is what 'debug' was before tracegori: trace and gori enabled debug    : just trace EVERYTHING! :-) Bootstrapped on x86_64-pc-linux-gnu  with no regressions. Pushed. Andrew From 0bb74a28e1318cbac9c895f1079b384a42513a9c Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 12 Aug 2021 14:02:20 -0400 Subject: [PATCH 2/3] Change evrp-mode options. Remove tracing in hybrid mode. Add trace/gori/cache tracing options. tracing options are now 'trace', 'gori', 'cache', or all combined in 'debug' * flag-types.h (enum evrp_mode): Adjust evrp-mode values. * gimple-range-cache.cc (DEBUG_RANGE_CACHE): Relocate from. * gimple-range-trace.h (DEBUG_RANGE_CACHE): Here. * params.opt (--param=evrp-mode): Adjust options. --- gcc/flag-types.h | 11 ++++++----- gcc/gimple-range-cache.cc | 3 +++ gcc/gimple-range-trace.h | 3 --- gcc/params.opt | 11 +++++++---- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/gcc/flag-types.h b/gcc/flag-types.h index e43d1de490d..4fb1cb4743d 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -444,14 +444,15 @@ enum parloops_schedule_type /* EVRP mode. */ enum evrp_mode { - EVRP_MODE_EVRP_FIRST = 0, + EVRP_MODE_RVRP_ONLY = 0, EVRP_MODE_EVRP_ONLY = 1, - EVRP_MODE_RVRP_ONLY = 2, + EVRP_MODE_EVRP_FIRST = 2, EVRP_MODE_RVRP_FIRST = 3, EVRP_MODE_TRACE = 4, - EVRP_MODE_DEBUG = 8 | EVRP_MODE_TRACE, - EVRP_MODE_RVRP_TRACE = EVRP_MODE_RVRP_ONLY | EVRP_MODE_TRACE, - EVRP_MODE_RVRP_DEBUG = EVRP_MODE_RVRP_ONLY | EVRP_MODE_DEBUG + EVRP_MODE_CACHE = (8 | EVRP_MODE_TRACE), + EVRP_MODE_GORI = 16, + EVRP_MODE_TRACE_GORI = (EVRP_MODE_TRACE | EVRP_MODE_GORI), + EVRP_MODE_DEBUG = (EVRP_MODE_GORI | EVRP_MODE_CACHE) }; /* Modes of OpenACC 'kernels' constructs handling. */ diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 91541f12c3c..4138d0556c6 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -30,6 +30,9 @@ along with GCC; see the file COPYING3. If not see #include "gimple-range.h" #include "tree-cfg.h" +#define DEBUG_RANGE_CACHE (dump_file && (param_evrp_mode & EVRP_MODE_CACHE) \ + == EVRP_MODE_CACHE) + // During contructor, allocate the vector of ssa_names. non_null_ref::non_null_ref () diff --git a/gcc/gimple-range-trace.h b/gcc/gimple-range-trace.h index 6f89fcccf4f..d2d1a8b270c 100644 --- a/gcc/gimple-range-trace.h +++ b/gcc/gimple-range-trace.h @@ -58,7 +58,4 @@ range_tracer::header (const char *str) return do_header (str); return 0; } - -#define DEBUG_RANGE_CACHE (dump_file && (param_evrp_mode & EVRP_MODE_DEBUG)) - #endif // GCC_GIMPLE_RANGE_TRACE_H diff --git a/gcc/params.opt b/gcc/params.opt index 92b003e38cb..f9264887b40 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -132,7 +132,7 @@ Maximum number of basic blocks before EVRP uses a sparse cache. -param=evrp-mode= Common Joined Var(param_evrp_mode) Enum(evrp_mode) Init(EVRP_MODE_RVRP_ONLY) Param Optimization ---param=evrp-mode=[legacy|ranger|legacy-first|ranger-first|ranger-trace|ranger-debug|trace|debug] Specifies the mode Early VRP should operate in. +--param=evrp-mode=[legacy|ranger|legacy-first|ranger-first|trace|gori|cache|tracegori|debug] Specifies the mode Early VRP should operate in. Enum Name(evrp_mode) Type(enum evrp_mode) UnknownError(unknown evrp mode %qs) @@ -150,13 +150,16 @@ EnumValue Enum(evrp_mode) String(ranger-first) Value(EVRP_MODE_RVRP_FIRST) EnumValue -Enum(evrp_mode) String(ranger-trace) Value(EVRP_MODE_RVRP_TRACE) +Enum(evrp_mode) String(trace) Value(EVRP_MODE_TRACE) EnumValue -Enum(evrp_mode) String(ranger-debug) Value(EVRP_MODE_RVRP_DEBUG) +Enum(evrp_mode) String(cache) Value(EVRP_MODE_CACHE) EnumValue -Enum(evrp_mode) String(trace) Value(EVRP_MODE_TRACE) +Enum(evrp_mode) String(gori) Value(EVRP_MODE_GORI) + +EnumValue +Enum(evrp_mode) String(tracegori) Value(EVRP_MODE_TRACE_GORI) EnumValue Enum(evrp_mode) String(debug) Value(EVRP_MODE_DEBUG) -- 2.17.2 From patchwork Tue Aug 17 23:31:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 1517877 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=wBhKNKGv; 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 4Gq6mY090Zz9sWq for ; Wed, 18 Aug 2021 09:33:49 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 95FC23889002 for ; Tue, 17 Aug 2021 23:33:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 95FC23889002 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1629243226; bh=1sv+C2tD2wST7pYx+jc52mbKcJVGF/StbXmnQu3Q/3Y=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=wBhKNKGvEISfns+aJcALYOCCqUrYIH/4BQG2nNiryKq9txDykf9h7ObNPKHAVs2YE GOG/F2OFHlt/lSJa3/O3btxJsr1yGc5PajGO8EO/KpHXmhwmMMrIDHKOOAXg7eNB5d QuWfMKa9lA6h0031jnW2GtF59PY0yvL77dvOxTHk= 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 62B12382CC23 for ; Tue, 17 Aug 2021 23:31:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 62B12382CC23 Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-465-7OgNT_6gNC-QvN6QEtG7JA-1; Tue, 17 Aug 2021 19:31:28 -0400 X-MC-Unique: 7OgNT_6gNC-QvN6QEtG7JA-1 Received: by mail-qk1-f197.google.com with SMTP id y27-20020a05620a09db00b003d3401f54ceso440373qky.5 for ; Tue, 17 Aug 2021 16:31:28 -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=1sv+C2tD2wST7pYx+jc52mbKcJVGF/StbXmnQu3Q/3Y=; b=uM+kCw9nzPqsrlGvVrXWWF1IwwNmwGPiaeQd5nUB8pm5xKMswO9YlNEicDHrt4YBLD 6ygdvvqZxCDJSOKBGZNs4zMlRiNqt2en9hY/eHQhox126fNIDjEhEHjnOBF7fougO4Ng 5fzhWsuW2hcuySK+t7JEewb/3SiNbTClnn0f8RwmI79sCaw4mzntUf89XpSIkR79QGKW ESg6SX1m0ealN/6rJT4QsnYCfOEBF021lAmfAElF/thCmJ4iGQoxLdKzv0W3W6utYNJv NZYm1LfuowIAw1Ubpkr4CEnCLNG8IfQG/yxXdXmD9meQ7pNohamWClN0CXRRlYp0Z8u0 mpSA== X-Gm-Message-State: AOAM532BY+NlePXI0gR9E/s1UbOXoaZUqccciKklDqyND7omYnyGgA8+ 5oN6BRrQvzcbEOXIFPPvX/xlx0h6Z0SFtJqXAYwQn+Cft5vlGGJ2Q9ZXl4nEvjlRiI8S+8dveLt lWt0rd2IrE8ngoBCJTQ== X-Received: by 2002:a37:6103:: with SMTP id v3mr6465625qkb.12.1629243087665; Tue, 17 Aug 2021 16:31:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyfbRmHo07z41DLwiDXepY7VIHT1l5PFrGGwUpKEhcP3shj0EflYyZqTjDcTN+NjDorMDrPlg== X-Received: by 2002:a37:6103:: with SMTP id v3mr6465609qkb.12.1629243087511; Tue, 17 Aug 2021 16:31:27 -0700 (PDT) Received: from [192.168.0.102] ([104.219.123.55]) by smtp.gmail.com with ESMTPSA id v5sm2496820qkh.39.2021.08.17.16.31.26 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 17 Aug 2021 16:31:27 -0700 (PDT) To: gcc-patches Subject: [COMMITTED 3/3] Add GORI tracing faciltiies. Message-ID: Date: Tue, 17 Aug 2021 19:31:24 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.12.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.0 required=5.0 tests=BAYES_00, BODY_8BITS, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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" And this final patch provides tracing in the GORI component. This is what I used to find the ABS problem with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101938 The code sequence looked like:     :     a1_8 = -arg1_7(D);     _1 = ABS_EXPR ;     a2_10 = -_1;     if (a1_8 > a2_10)       goto ; [INV] and the threader was threading a condition later on because the outgoing range for arg2_9 was being compared to   0x80000000 and folded to [0,0] as it didnt think that could happen. The GORi trace looked like: 237     GORI  outgoing_edge for arg2_9(D) on edge 2->3 238     GORI    compute op 2 (a2_10) at if (a1_8 > a2_10)         GORI      LHS = _Bool [1, 1], a1_8 = int64 VARYING         GORI      Computes a2_10 = int64 [-INF, 9223372036854775806] intersect Known range : int64 VARYING         GORI    TRUE : (238)  produces  (a2_10) int64 [-INF, 9223372036854775806] 239     GORI    compute op 1 (_1) at a2_10 = -_1;         GORI      LHS =int64 [-INF, 9223372036854775806]         GORI      Computes _1 = long long int [-INF, -INF][-9223372036854775806, +INF] intersect Known range : long long int VARYING         GORI    TRUE : (239) produces  (_1) long long int [-INF, -INF][-9223372036854775806, +INF] 240     GORI    compute op 1 (arg2_9(D)) at _1 = ABS_EXPR ;         GORI      LHS =long long int [-INF, -INF][-9223372036854775806, +INF]         GORI      Computes arg2_9(D) = int64 [-9223372036854775807, +INF] intersect Known range : int64 VARYING         GORI    TRUE : (240) produces  (arg2_9(D)) int64 [-9223372036854775807, +INF]         GORI  TRUE : (237) outgoing_edge (arg2_9(D)) int64 [-9223372036854775807, +INF] Which shows the range can never be -9223372036854775808 (thats 0x8000000 or MIN_INT) . Note the result of request  239 shows that _1 on this edge is calculated as [-INF, -INF][0xFFFFFFFE, +INF], and when solving the ABS_EXPR:    [-INF, -INF][0XFFFFFFFE, +INF] = ABS_EXPR Range-ops was solving that as-9223372036854775807, +INF] ( AKA [0xFFFFFFFF, 0x7FFFFFFF])...  losing the [-INF, -INF] possibility.   which pointed to the bug in op1_range for ABS_EXPR. Im sure there will be more tweaking to this, but its a start. Anyway, Bootstrapped on x86_64-pc-linux-gnu  with no regressions. Pushed. Andrew From 4759e1e0453bef163d8dbeebbb96dc40b049c117 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 12 Aug 2021 12:29:48 -0400 Subject: [PATCH 3/3] Add GORI tracing faciltiies. Debugging range-ops and gori unwinding needed some help. * gimple-range-gori.cc (gori_compute::gori_compute): Enable tracing. (gori_compute::compute_operand_range): Add tracing. (gori_compute::logical_combine): Ditto. (gori_compute::compute_logical_operands): Ditto. (gori_compute::compute_operand1_range): Ditto. (gori_compute::compute_operand2_range): Ditto. (gori_compute::outgoing_edge_range_p): Ditto. * gimple-range-gori.h (class gori_compute): Add range_tracer. --- gcc/gimple-range-gori.cc | 172 +++++++++++++++++++++++++++++++++------ gcc/gimple-range-gori.h | 1 + 2 files changed, 149 insertions(+), 24 deletions(-) diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index c124b3c1ce4..f78829595dc 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -634,11 +634,13 @@ debug (gori_map &g) // Construct a gori_compute object. -gori_compute::gori_compute () +gori_compute::gori_compute () : tracer ("GORI ") { // Create a boolean_type true and false range. m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node); m_bool_one = int_range<2> (boolean_true_node, boolean_true_node); + if (dump_file && (param_evrp_mode & EVRP_MODE_GORI)) + tracer.enable_trace (); } // Given the switch S, return an evaluation in R for NAME when the lhs @@ -712,29 +714,43 @@ gori_compute::compute_operand_range (irange &r, gimple *stmt, if (!op1_in_chain && !op2_in_chain) return false; + bool res; // Process logicals as they have special handling. if (is_gimple_logical_p (stmt)) { + unsigned idx; + if ((idx = tracer.header ("compute_operand "))) + { + print_generic_expr (dump_file, name, TDF_SLIM); + fprintf (dump_file, " with LHS = "); + lhs.dump (dump_file); + fprintf (dump_file, " at stmt "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + int_range_max op1_trange, op1_frange; int_range_max op2_trange, op2_frange; compute_logical_operands (op1_trange, op1_frange, stmt, lhs, name, src, op1, op1_in_chain); compute_logical_operands (op2_trange, op2_frange, stmt, lhs, name, src, op2, op2_in_chain); - return logical_combine (r, gimple_expr_code (stmt), lhs, - op1_trange, op1_frange, op2_trange, op2_frange); + res = logical_combine (r, gimple_expr_code (stmt), lhs, + op1_trange, op1_frange, op2_trange, op2_frange); + if (idx) + tracer.trailer (idx, "compute_operand", res, name, r); } - // Follow the appropriate operands now. - if (op1_in_chain && op2_in_chain) - return compute_operand1_and_operand2_range (r, stmt, lhs, name, src); - if (op1_in_chain) - return compute_operand1_range (r, stmt, lhs, name, src); - if (op2_in_chain) - return compute_operand2_range (r, stmt, lhs, name, src); + else if (op1_in_chain && op2_in_chain) + res = compute_operand1_and_operand2_range (r, stmt, lhs, name, src); + else if (op1_in_chain) + res = compute_operand1_range (r, stmt, lhs, name, src); + else if (op2_in_chain) + res = compute_operand2_range (r, stmt, lhs, name, src); + else + gcc_unreachable (); // If neither operand is derived, this statement tells us nothing. - return false; + return res; } @@ -767,6 +783,38 @@ gori_compute::logical_combine (irange &r, enum tree_code code, && op2_true.varying_p () && op2_false.varying_p ()) return false; + unsigned idx; + if ((idx = tracer.header ("logical_combine"))) + { + switch (code) + { + case TRUTH_OR_EXPR: + case BIT_IOR_EXPR: + fprintf (dump_file, " || "); + break; + case TRUTH_AND_EXPR: + case BIT_AND_EXPR: + fprintf (dump_file, " && "); + break; + default: + break; + } + fprintf (dump_file, " with LHS = "); + lhs.dump (dump_file); + fputc ('\n', dump_file); + + tracer.print (idx, "op1_true = "); + op1_true.dump (dump_file); + fprintf (dump_file, " op1_false = "); + op1_false.dump (dump_file); + fputc ('\n', dump_file); + tracer.print (idx, "op2_true = "); + op2_true.dump (dump_file); + fprintf (dump_file, " op2_false = "); + op2_false.dump (dump_file); + fputc ('\n', dump_file); + } + // This is not a simple fold of a logical expression, rather it // determines ranges which flow through the logical expression. // @@ -804,6 +852,7 @@ gori_compute::logical_combine (irange &r, enum tree_code code, // would be lost. if (!range_is_either_true_or_false (lhs)) { + bool res; int_range_max r1; if (logical_combine (r1, code, m_bool_zero, op1_true, op1_false, op2_true, op2_false) @@ -811,9 +860,12 @@ gori_compute::logical_combine (irange &r, enum tree_code code, op2_true, op2_false)) { r.union_ (r1); - return true; + res = true; } - return false; + else + res = false; + if (idx) + tracer.trailer (idx, "logical_combine", res, NULL_TREE, r); } switch (code) @@ -873,6 +925,8 @@ gori_compute::logical_combine (irange &r, enum tree_code code, gcc_unreachable (); } + if (idx) + tracer.trailer (idx, "logical_combine", true, NULL_TREE, r); return true; } @@ -895,6 +949,13 @@ gori_compute::compute_logical_operands (irange &true_range, irange &false_range, // use its known value on entry to the block. src.get_operand (true_range, name); false_range = true_range; + unsigned idx; + if ((idx = tracer.header ("logical_operand"))) + { + print_generic_expr (dump_file, op, TDF_SLIM); + fprintf (dump_file, " not in computation chain. Queried.\n"); + tracer.trailer (idx, "logical_operand", true, NULL_TREE, true_range); + } return; } @@ -958,15 +1019,43 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt, return false; } + unsigned idx; + if ((idx = tracer.header ("compute op 1 ("))) + { + print_generic_expr (dump_file, op1, TDF_SLIM); + fprintf (dump_file, ") at "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + tracer.print (idx, "LHS ="); + lhs.dump (dump_file); + if (op2 && TREE_CODE (op2) == SSA_NAME) + { + fprintf (dump_file, ", "); + print_generic_expr (dump_file, op2, TDF_SLIM); + fprintf (dump_file, " = "); + op2_range.dump (dump_file); + } + fprintf (dump_file, "\n"); + tracer.print (idx, "Computes "); + print_generic_expr (dump_file, op1, TDF_SLIM); + fprintf (dump_file, " = "); + r.dump (dump_file); + fprintf (dump_file, " intersect Known range : "); + op1_range.dump (dump_file); + fputc ('\n', dump_file); + } // Intersect the calculated result with the known result and return if done. if (op1 == name) { r.intersect (op1_range); + if (idx) + tracer.trailer (idx, "produces ", true, name, r); return true; } // If the calculation continues, we're using op1_range as the new LHS. op1_range.intersect (r); + if (idx) + tracer.trailer (idx, "produces ", true, op1, op1_range); gimple *src_stmt = SSA_NAME_DEF_STMT (op1); gcc_checking_assert (src_stmt); @@ -995,15 +1084,43 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt, if (!gimple_range_calc_op2 (r, stmt, lhs, op1_range)) return false; + unsigned idx; + if ((idx = tracer.header ("compute op 2 ("))) + { + print_generic_expr (dump_file, op2, TDF_SLIM); + fprintf (dump_file, ") at "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + tracer.print (idx, "LHS = "); + lhs.dump (dump_file); + if (TREE_CODE (op1) == SSA_NAME) + { + fprintf (dump_file, ", "); + print_generic_expr (dump_file, op1, TDF_SLIM); + fprintf (dump_file, " = "); + op1_range.dump (dump_file); + } + fprintf (dump_file, "\n"); + tracer.print (idx, "Computes "); + print_generic_expr (dump_file, op2, TDF_SLIM); + fprintf (dump_file, " = "); + r.dump (dump_file); + fprintf (dump_file, " intersect Known range : "); + op2_range.dump (dump_file); + fputc ('\n', dump_file); + } // Intersect the calculated result with the known result and return if done. if (op2 == name) { r.intersect (op2_range); + if (idx) + tracer.trailer (idx, " produces ", true, NULL_TREE, r); return true; } // If the calculation continues, we're using op2_range as the new LHS. op2_range.intersect (r); + if (idx) + tracer.trailer (idx, " produces ", true, op2, op2_range); gimple *src_stmt = SSA_NAME_DEF_STMT (op2); gcc_checking_assert (src_stmt); // gcc_checking_assert (!is_import_p (op2, find.bb)); @@ -1095,6 +1212,7 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name, range_query &q) { int_range_max lhs; + unsigned idx; gcc_checking_assert (gimple_range_ssa_p (name)); // Determine if there is an outgoing edge. @@ -1122,7 +1240,15 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name, // If NAME can be calculated on the edge, use that. if (is_export_p (name, e->src)) { - if (compute_operand_range (r, stmt, lhs, name, src)) + bool res; + if ((idx = tracer.header ("outgoing_edge"))) + { + fprintf (dump_file, " for "); + print_generic_expr (dump_file, name, TDF_SLIM); + fprintf (dump_file, " on edge %d->%d\n", + e->src->index, e->dest->index); + } + if ((res = compute_operand_range (r, stmt, lhs, name, src))) { // Sometimes compatible types get interchanged. See PR97360. // Make sure we are returning the type of the thing we asked for. @@ -1132,28 +1258,26 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name, TREE_TYPE (name))); range_cast (r, TREE_TYPE (name)); } - return true; } + if (idx) + tracer.trailer (idx, "outgoing_edge", res, name, r); + return res; } // If NAME isn't exported, check if it can be recomputed. else if (may_recompute_p (name, e)) { gimple *def_stmt = SSA_NAME_DEF_STMT (name); - if (dump_file && (dump_flags & TDF_DETAILS)) + if ((idx = tracer.header ("recomputation"))) { - fprintf (dump_file, "recomputation attempt on edge %d->%d for ", + fprintf (dump_file, " attempt on edge %d->%d for ", e->src->index, e->dest->index); - print_generic_expr (dump_file, name, TDF_SLIM); + print_gimple_stmt (dump_file, def_stmt, 0, TDF_SLIM); } // Simply calculate DEF_STMT on edge E using the range query Q. fold_range (r, def_stmt, e, &q); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, " : Calculated :"); - r.dump (dump_file); - fputc ('\n', dump_file); - } + if (idx) + tracer.trailer (idx, "recomputation", true, name, r); return true; } return false; diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index ad833240bbb..688468c8790 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -180,6 +180,7 @@ private: int_range<2> m_bool_one; // Boolean true cached. gimple_outgoing_range outgoing; // Edge values for COND_EXPR & SWITCH_EXPR. + range_tracer tracer; }; // These routines provide a GIMPLE interface to the range-ops code. -- 2.17.2