This is v3 of the patch; previous versions were: v2: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg00446.html v1: https://gcc.gnu.org/ml/gcc-patches/2018-06/msg01462.html This patch introduces a class opt_problem, along with wrapper classes for bool (opt_result) and for pointers (e.g. opt_loop_vec_info for loop_vec_info). opt_problem instances are created when an optimization problem is encountered, but only if dump_enabled_p. They are manually propagated up the callstack, and are manually reported at the "top level" of an optimization if dumping is enabled, to give the user a concise summary of the problem *after* the failure is reported. In particular, the location of the problematic statement is captured and emitted, rather than just the loop's location. For example: no-vfa-vect-102.c:24:3: missed: couldn't vectorize loop no-vfa-vect-102.c:27:7: missed: statement clobbers memory: __asm__ __volatile__("" : : : "memory"); Changed in v3: * This version bootstraps and passes regression testing (on x86_64-pc-linux-gnu). * added selftests, to exercise the opt_problem machinery * removed the "bool to opt_result" ctor, so that attempts to use e.g. return a bool from an opt_result-returning function will fail at compile time * use formatted printing within opt_problem ctor to replace the various dump_printf_loc calls * dropped i18n * changed the sense of vect_analyze_data_ref_dependence's return value (see the ChangeLog) * add MSG_PRIORITY_REEMITTED, so that -fopt-info can show the messages, without them messing up the counts in scan-tree-dump-times in DejaGnu tests gcc/ChangeLog: * Makefile.in (OBJS): Add opt-problem.o. * dump-context.h: Include "selftest.h. (selftest::temp_dump_context): New forward decl. (class dump_context): Make friend of class selftest::temp_dump_context. (dump_context::dump_loc_immediate): New decl. (class dump_pretty_printer): Move here from dumpfile.c. (class temp_dump_context): Move to namespace selftest. (temp_dump_context::temp_dump_context): Add param "forcibly_enable_dumping". (selftest::verify_dumped_text): (ASSERT_DUMPED_TEXT_EQ): Move here from dumpfile.c. (selftest::verify_item): (ASSERT_IS_TEXT): Move here from dumpfile.c. (ASSERT_IS_TREE): Likewise. (ASSERT_IS_GIMPLE): Likewise. * dumpfile.c (dump_context::dump_loc): Move immediate dumping to... (dump_context::dump_loc_immediate): ...this new function. (class dump_pretty_printer): Move to dump-context.h. (dump_switch_p_1): Don't enable MSG_PRIORITY_REEMITTED. (opt_info_switch_p_1): Enable MSG_PRIORITY_REEMITTED. (temp_dump_context::temp_dump_context): Move to "selftest" namespace. Add param "forcibly_enable_dumping", and use it to conditionalize the use of m_pp; (selftest::verify_dumped_text): Make non-static. (ASSERT_DUMPED_TEXT_EQ): Move to dump-context.h. (selftest::verify_item): Make non-static. (ASSERT_IS_TEXT): Move to dump-context.h. (ASSERT_IS_TREE): Likewise. (ASSERT_IS_GIMPLE): Likewise. (selftest::test_capture_of_dump_calls): Pass "true" for new param of temp_dump_context. * dumpfile.h (enum dump_flag): Add MSG_PRIORITY_REEMITTED, adding it to MSG_ALL_PRIORITIES. Update values of TDF_COMPARE_DEBUG and TDF_COMPARE_DEBUG. * opt-problem.cc: New file. * opt-problem.h: New file. * optinfo-emit-json.cc (selftest::test_building_json_from_dump_calls): Pass "true" for new param of temp_dump_context. * optinfo.cc (optinfo_kind_to_dump_flag): New function. (optinfo::emit_for_opt_problem): New function. (optinfo::emit): Clarity which emit_item is used. * optinfo.h (optinfo::get_dump_location): New accessor. (optinfo::emit_for_opt_problem): New decl. (optinfo::emit): Make const. * selftest-run-tests.c (selftest::run_tests): Call selftest::opt_problem_cc_tests. * selftest.h (selftest::opt_problem_cc_tests): New decl. * tree-data-ref.c (dr_analyze_innermost): Convert return type from bool to opt_result, converting fprintf messages to opt_result::failure_at calls. Add "stmt" param for use by the failure_at calls. (create_data_ref): Pass "stmt" to the dr_analyze_innermost call. (runtime_alias_check_p): Convert return type from bool to opt_result, converting dump_printf calls to opt_result::failure_at, using the statement DDR_A for their location. (find_data_references_in_stmt): Convert return type from bool to opt_result, converting "return false" to opt_result::failure_at with a new message. * tree-data-ref.h: Include "opt-problem.h". (dr_analyze_innermost): Convert return type from bool to opt_result, and add a const gimple * param. (find_data_references_in_stmt): Convert return type from bool to opt_result. (runtime_alias_check_p): Likewise. * tree-predcom.c (find_looparound_phi): Pass "init_stmt" to dr_analyze_innermost. * tree-vect-data-refs.c (vect_mark_for_runtime_alias_test): Convert return type from bool to opt_result, adding a message for the PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS zero case. (vect_analyze_data_ref_dependence): Convert return type from bool to opt_result. Change sense of return type from "false" effectively meaning "no problems" to "false" meaning a problem, so that "return false" becomes "return opt_result::success". Convert "return true" calls to opt_result::failure_at, using the location of statement A rather than vect_location. (vect_analyze_data_ref_dependences): Convert return type from bool to opt_result. (verify_data_ref_alignment): Likewise, converting dump_printf_loc calls to opt_result::failure_at, using the stmt location rather than vect_location. (vect_verify_datarefs_alignment): Convert return type from bool to opt_result. (vect_enhance_data_refs_alignment): Likewise. Split local "stat" into multiple more-tightly-scoped copies. (vect_analyze_data_refs_alignment): Convert return type from bool to opt_result. (vect_analyze_data_ref_accesses): Likewise, converting a "return false" to a "return opt_result::failure_at", adding a new message. (vect_prune_runtime_alias_test_list): Convert return type from bool to opt_result, converting dump_printf_loc to opt_result::failure_at. Add a %G to show the pertinent statement, and use the stmt's location rather than vect_location. (vect_find_stmt_data_reference): Convert return type from bool to opt_result, converting dump_printf_loc to opt_result::failure_at, using stmt's location. (vect_analyze_data_refs): Convert return type from bool to opt_result. Convert "return false" to "return opt_result::failure_at", adding messages as needed. * tree-vect-loop.c (vect_determine_vf_for_stmt_1): Convert return type from bool to opt_result. (vect_determine_vf_for_stmt): Likewise. (vect_determine_vectorization_factor): Likewise, converting dump_printf_loc to opt_result::failure_at, using location of phi rather than vect_location. (vect_analyze_loop_form_1): Convert return type from bool to opt_result, converting dump_printf_loc calls, retaining the use of vect_location. (vect_analyze_loop_form): Convert return type from loop_vec_info to opt_loop_vec_info. (vect_analyze_loop_operations): Convert return type from bool to opt_result, converting dump_printf_loc calls, using the location of phi/stmt rather than vect_location where available. Convert various "return false" to "return opt_result::failure_at" with "unsupported phi" messages. (vect_get_datarefs_in_loop): Convert return type from bool to opt_result. Add a message for the PARAM_LOOP_MAX_DATAREFS_FOR_DATADEPS failure. (vect_analyze_loop_2): Convert return type from bool to opt_result. Ensure "ok" is set to a opt_result::failure_at before each "goto again;", adding new messages where needed. Add "unsupported grouped {store|load}" messages. (vect_analyze_loop): Convert return type from loop_vec_info to opt_loop_vec_info. * tree-vect-slp.c (vect_analyze_slp): Convert return type from bool to opt_result. * tree-vect-stmts.c (process_use): Likewise, converting dump_printf_loc call and using stmt location, rather than vect_location. (vect_mark_stmts_to_be_vectorized): Likeise. (vect_analyze_stmt): Likewise, adding a %G. (vect_get_vector_types_for_stmt): Convert return type from bool to opt_result, converting dump_printf_loc calls and using stmt location, rather than vect_location. (vect_get_mask_type_for_stmt): Convert return type from tree to opt_tree, converting dump_printf_loc calls and using stmt location. * tree-vectorizer.c: Include "opt-problem.h. (try_vectorize_loop_1): Flag "Analyzing loop at" dump message as MSG_PRIORITY_INTERNALS. Convert local "loop_vinfo" from loop_vec_info to opt_loop_vec_info. If if fails, and dumping is enabled, use it to report at the top level "couldn't vectorize loop" followed by the problem. * tree-vectorizer.h (opt_loop_vec_info): New typedef. (vect_mark_stmts_to_be_vectorized): Convert return type from bool to opt_result. (vect_analyze_stmt): Likewise. (vect_get_vector_types_for_stmt): Likewise. (tree vect_get_mask_type_for_stmt): Likewise. (vect_analyze_data_ref_dependences): Likewise. (vect_enhance_data_refs_alignment): Likewise. (vect_analyze_data_refs_alignment): Likewise. (vect_verify_datarefs_alignment): Likewise. (vect_analyze_data_ref_accesses): Likewise. (vect_prune_runtime_alias_test_list): Likewise. (vect_find_stmt_data_reference): Likewise. (vect_analyze_data_refs): Likewise. (vect_analyze_loop): Convert return type from loop_vec_info to opt_loop_vec_info. (vect_analyze_loop_form): Likewise. (vect_analyze_slp): Convert return type from bool to opt_result. gcc/testsuite/ChangeLog: * gcc.dg/vect/nodump-vect-opt-info-2.c: New test. * gcc.dg/vect/vect-alias-check-4.c: Add "-fopt-info-vec-all" to dg-additional-options. Add dg-message and dg-missed directives to verify that -fopt-info messages are written at the correct locations. From-SVN: r264852
173 lines
4.1 KiB
C++
173 lines
4.1 KiB
C++
/* Optimization information.
|
|
Copyright (C) 2018 Free Software Foundation, Inc.
|
|
Contributed by David Malcolm <dmalcolm@redhat.com>.
|
|
|
|
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
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include "config.h"
|
|
#include "system.h"
|
|
#include "coretypes.h"
|
|
|
|
#include "backend.h"
|
|
#include "tree.h"
|
|
#include "gimple.h"
|
|
|
|
#include "optinfo.h"
|
|
#include "optinfo-emit-json.h"
|
|
#include "dump-context.h"
|
|
#include "pretty-print.h"
|
|
#include "gimple-pretty-print.h"
|
|
#include "cgraph.h"
|
|
#include "selftest.h"
|
|
|
|
/* optinfo_item's ctor. Takes ownership of TEXT. */
|
|
|
|
optinfo_item::optinfo_item (enum optinfo_item_kind kind, location_t location,
|
|
char *text)
|
|
: m_kind (kind), m_location (location), m_text (text)
|
|
{
|
|
}
|
|
|
|
/* optinfo_item's dtor. */
|
|
|
|
optinfo_item::~optinfo_item ()
|
|
{
|
|
free (m_text);
|
|
}
|
|
|
|
/* Get a string from KIND. */
|
|
|
|
const char *
|
|
optinfo_kind_to_string (enum optinfo_kind kind)
|
|
{
|
|
switch (kind)
|
|
{
|
|
default:
|
|
gcc_unreachable ();
|
|
case OPTINFO_KIND_SUCCESS:
|
|
return "success";
|
|
case OPTINFO_KIND_FAILURE:
|
|
return "failure";
|
|
case OPTINFO_KIND_NOTE:
|
|
return "note";
|
|
case OPTINFO_KIND_SCOPE:
|
|
return "scope";
|
|
}
|
|
}
|
|
|
|
/* optinfo's dtor. */
|
|
|
|
optinfo::~optinfo ()
|
|
{
|
|
/* Cleanup. */
|
|
unsigned i;
|
|
optinfo_item *item;
|
|
FOR_EACH_VEC_ELT (m_items, i, item)
|
|
delete item;
|
|
}
|
|
|
|
/* Add ITEM to this optinfo. */
|
|
|
|
void
|
|
optinfo::add_item (optinfo_item *item)
|
|
{
|
|
gcc_assert (item);
|
|
m_items.safe_push (item);
|
|
}
|
|
|
|
/* Get MSG_* flags corresponding to KIND. */
|
|
|
|
static dump_flags_t
|
|
optinfo_kind_to_dump_flag (enum optinfo_kind kind)
|
|
{
|
|
switch (kind)
|
|
{
|
|
default:
|
|
gcc_unreachable ();
|
|
case OPTINFO_KIND_SUCCESS:
|
|
return MSG_OPTIMIZED_LOCATIONS;
|
|
case OPTINFO_KIND_FAILURE:
|
|
return MSG_MISSED_OPTIMIZATION;
|
|
case OPTINFO_KIND_NOTE:
|
|
case OPTINFO_KIND_SCOPE:
|
|
return MSG_NOTE;
|
|
}
|
|
}
|
|
|
|
/* Re-emit this optinfo, both to the "non-immediate" destinations,
|
|
*and* to the "immediate" destinations. */
|
|
|
|
void
|
|
optinfo::emit_for_opt_problem () const
|
|
{
|
|
dump_flags_t dump_kind = optinfo_kind_to_dump_flag (get_kind ());
|
|
dump_kind |= MSG_PRIORITY_REEMITTED;
|
|
|
|
/* Re-emit to "immediate" destinations, without creating a new optinfo. */
|
|
dump_context::get ().dump_loc_immediate (dump_kind, get_dump_location ());
|
|
unsigned i;
|
|
optinfo_item *item;
|
|
FOR_EACH_VEC_ELT (m_items, i, item)
|
|
dump_context::get ().emit_item (item, dump_kind);
|
|
|
|
/* Re-emit to "non-immediate" destinations. */
|
|
emit ();
|
|
}
|
|
|
|
/* Emit the optinfo to all of the "non-immediate" destinations
|
|
(emission to "immediate" destinations is done by
|
|
dump_context::emit_item). */
|
|
|
|
void
|
|
optinfo::emit () const
|
|
{
|
|
/* -fsave-optimization-record. */
|
|
optimization_records_maybe_record_optinfo (this);
|
|
}
|
|
|
|
/* Update the optinfo's kind based on DUMP_KIND. */
|
|
|
|
void
|
|
optinfo::handle_dump_file_kind (dump_flags_t dump_kind)
|
|
{
|
|
if (dump_kind & MSG_OPTIMIZED_LOCATIONS)
|
|
m_kind = OPTINFO_KIND_SUCCESS;
|
|
else if (dump_kind & MSG_MISSED_OPTIMIZATION)
|
|
m_kind = OPTINFO_KIND_FAILURE;
|
|
else if (dump_kind & MSG_NOTE)
|
|
m_kind = OPTINFO_KIND_NOTE;
|
|
}
|
|
|
|
/* Should optinfo instances be created?
|
|
All creation of optinfos should be guarded by this predicate.
|
|
Return true if any optinfo destinations are active. */
|
|
|
|
bool optinfo_enabled_p ()
|
|
{
|
|
return (dump_context::get ().forcibly_enable_optinfo_p ()
|
|
|| optimization_records_enabled_p ());
|
|
}
|
|
|
|
/* Return true if any of the active optinfo destinations make use
|
|
of inlining information.
|
|
(if true, then the information is preserved). */
|
|
|
|
bool optinfo_wants_inlining_info_p ()
|
|
{
|
|
return optimization_records_enabled_p ();
|
|
}
|