Go to file
Aldy Hernandez 5485bbebb3 Refactor jump_thread_path_registry.
In an attempt to refactor thread_through_all_blocks(), I've realized
that there is a mess of code dealing with coexisting forward and
backward thread types.  However, this is an impossible scenario, as
the registry contains either forward/old-style threads, or backward
threads (EDGE_FSM_THREADs), never both.

The fact that both types of threads cannot coexist, simplifies the
code considerably.  For that matter, it splits things up nicely
because there are some common bits that can go into a base class, and
some differing code that can go into derived classes.

Diving things in this way makes it very obvious which parts belong in
the old-style copier and which parts belong to the generic copier.
Doing all this provided some nice cleanups, as well as fixing a latent
bug in adjust_paths_after_duplication.

The diff is somewhat hard to read, so perhaps looking at the final
output would be easier.

A general overview of what this patch achieves can be seen by just
looking at this simplified class layout:

// Abstract class for the jump thread registry.

class jt_path_registry
{
public:
  jt_path_registry ();
  virtual ~jt_path_registry ();
  bool register_jump_thread (vec<jump_thread_edge *> *);
  bool thread_through_all_blocks (bool peel_loop_headers);
  jump_thread_edge *allocate_thread_edge (edge e, jump_thread_edge_type t);
  vec<jump_thread_edge *> *allocate_thread_path ();
protected:
  vec<vec<jump_thread_edge *> *> m_paths;
  unsigned long m_num_threaded_edges;
private:
  virtual bool update_cfg (bool peel_loop_headers) = 0;
};

// Forward threader path registry using a custom BB copier.

class fwd_jt_path_registry : public jt_path_registry
{
public:
  fwd_jt_path_registry ();
  ~fwd_jt_path_registry ();
  void remove_jump_threads_including (edge);
private:
  bool update_cfg (bool peel_loop_headers) override;
  void mark_threaded_blocks (bitmap threaded_blocks);
  bool thread_block_1 (basic_block, bool noloop_only, bool joiners);
  bool thread_block (basic_block, bool noloop_only);
  bool thread_through_loop_header (class loop *loop,
                                   bool may_peel_loop_headers);
  class redirection_data *lookup_redirection_data (edge e, enum insert_option);
  hash_table<struct removed_edges> *m_removed_edges;
  hash_table<redirection_data> *m_redirection_data;
};

// Backward threader path registry using a generic BB copier.

class back_jt_path_registry : public jt_path_registry
{
private:
  bool update_cfg (bool peel_loop_headers) override;
  void adjust_paths_after_duplication (unsigned curr_path_num);
  bool duplicate_thread_path (edge entry, edge exit, basic_block *region,
                              unsigned n_region, unsigned current_path_no);
  bool rewire_first_differing_edge (unsigned path_num, unsigned edge_num);
};

That is, the forward and backward bits have been completely split,
while deriving from a base class for the common functionality.

Most everything is mechanical, but there are a few gotchas:

a) back_jt_path_registry::update_cfg(), which contains the backward
threading specific bits, is rather simple, since most of the code in
the original thread_through_all_blocks() only applied to the forward
threader: removed edges, mark_threaded_blocks,
thread_through_loop_header, the copy tables (*).

(*) The back threader has its own copy tables in
duplicate_thread_path.

b) In some cases, adjust_paths_after_duplication() was commoning out
so many blocks that it was removing the initial EDGE_FSM_THREAD
marker.  I've fixed this.

c) AFAICT, when run from the forward threader,
thread_through_all_blocks() attempts to remove threads starting with
an edge already seen, but it would never see anything because the loop
doing the checking only has a visited_starting_edges.contains(), and
no corresponding visited_starting_edges.add().  The add() method in
thread_through_all_blocks belongs to the backward threading bits, and
as I've explained, both types cannot coexist.  I've removed the checks
in the forward bits since they don't appear to do anything.  If this
was an oversight, and we want to avoid threading already seen edges in
the forward threader, I can move this functionality to the base class.

Ultimately I would like to move all the registry code to
tree-ssa-threadregistry.*.  I've avoided this in this patch to aid in
review.

My apologies for this longass explanation, but I want to make sure
we're covering all of our bases.

Tested on x86-64 Linux by a very tedious process of moving chunks
around, running "make check-gcc RUNTESTFLAGS=tree-ssa.exp", and
repeating ad-nauseum.  And of course, by running a full bootstrap and
tests.

OK?

p.s. In a follow-up patch I will rename the confusing EDGE_FSM_THREAD
type.

gcc/ChangeLog:

	* tree-ssa-threadbackward.c (class back_threader_registry): Use
	back_jt_path_registry.
	* tree-ssa-threadedge.c (jump_threader::jump_threader): Use
	fwd_jt_path_registry.
	* tree-ssa-threadedge.h (class jump_threader): Same..
	* tree-ssa-threadupdate.c
	(jump_thread_path_registry::jump_thread_path_registry): Rename...
	(jt_path_registry::jt_path_registry): ...to this.
	(jump_thread_path_registry::~jump_thread_path_registry): Rename...
	(jt_path_registry::~jt_path_registry): ...this.
	(fwd_jt_path_registry::fwd_jt_path_registry): New.
	(fwd_jt_path_registry::~fwd_jt_path_registry): New.
	(jump_thread_path_registry::allocate_thread_edge): Rename...
	(jt_path_registry::allocate_thread_edge): ...to this.
	(jump_thread_path_registry::allocate_thread_path): Rename...
	(jt_path_registry::allocate_thread_path): ...to this.
	(jump_thread_path_registry::lookup_redirection_data): Rename...
	(fwd_jt_path_registry::lookup_redirection_data): ...to this.
	(jump_thread_path_registry::thread_block_1): Rename...
	(fwd_jt_path_registry::thread_block_1): ...to this.
	(jump_thread_path_registry::thread_block): Rename...
	(fwd_jt_path_registry::thread_block): ...to this.
	(jt_path_registry::thread_through_loop_header): Rename...
	(fwd_jt_path_registry::thread_through_loop_header): ...to this.
	(jump_thread_path_registry::mark_threaded_blocks): Rename...
	(fwd_jt_path_registry::mark_threaded_blocks): ...to this.
	(jump_thread_path_registry::debug_path): Rename...
	(jt_path_registry::debug_path): ...to this.
	(jump_thread_path_registry::dump): Rename...
	(jt_path_registry::debug): ...to this.
	(jump_thread_path_registry::rewire_first_differing_edge): Rename...
	(back_jt_path_registry::rewire_first_differing_edge): ...to this.
	(jump_thread_path_registry::adjust_paths_after_duplication): Rename...
	(back_jt_path_registry::adjust_paths_after_duplication): ...to this.
	(jump_thread_path_registry::duplicate_thread_path): Rename...
	(back_jt_path_registry::duplicate_thread_path): ...to this.  Also,
	drop ill-formed candidates.
	(jump_thread_path_registry::remove_jump_threads_including): Rename...
	(fwd_jt_path_registry::remove_jump_threads_including): ...to this.
	(jt_path_registry::thread_through_all_blocks): New.
	(back_jt_path_registry::update_cfg): New.
	(fwd_jt_path_registry::update_cfg): New.
	(jump_thread_path_registry::register_jump_thread): Rename...
	(jt_path_registry::register_jump_thread): ...to this.
	* tree-ssa-threadupdate.h (class jump_thread_path_registry):
	Abstract to...
	(class jt_path_registry): ...here.
	(class fwd_jt_path_registry): New.
	(class back_jt_path_registry): New.
2021-09-11 19:51:30 +02:00
c++tools Daily bump. 2021-07-22 00:16:46 +00:00
config Daily bump. 2021-08-19 00:16:42 +00:00
contrib Daily bump. 2021-09-07 00:16:34 +00:00
fixincludes Daily bump. 2021-08-31 00:16:50 +00:00
gcc Refactor jump_thread_path_registry. 2021-09-11 19:51:30 +02:00
gnattools
gotools
include Daily bump. 2021-08-24 00:17:00 +00:00
INSTALL
intl
libada
libatomic Daily bump. 2021-07-22 00:16:46 +00:00
libbacktrace Daily bump. 2021-08-14 00:16:29 +00:00
libcc1 Daily bump. 2021-08-18 00:16:48 +00:00
libcody
libcpp Daily bump. 2021-09-02 00:16:59 +00:00
libdecnumber
libffi Daily bump. 2021-08-31 00:16:50 +00:00
libgcc Daily bump. 2021-09-09 00:16:32 +00:00
libgfortran Daily bump. 2021-09-08 00:16:23 +00:00
libgo runtime: use hash32, not hash64, for amd64p32, mips64p32, mips64p32le 2021-09-07 15:05:11 -07:00
libgomp Daily bump. 2021-09-11 00:16:27 +00:00
libiberty Daily bump. 2021-09-02 00:16:59 +00:00
libitm
libobjc
liboffloadmic
libphobos Daily bump. 2021-09-02 00:16:59 +00:00
libquadmath
libsanitizer Daily bump. 2021-08-12 00:16:28 +00:00
libssp
libstdc++-v3 Daily bump. 2021-09-11 00:16:27 +00:00
libvtv
lto-plugin
maintainer-scripts
zlib
.dir-locals.el dir-locals: Use https for bug references 2021-07-20 11:40:34 +01:00
.gitattributes
.gitignore
ABOUT-NLS
ar-lib
ChangeLog Daily bump. 2021-09-11 00:16:27 +00:00
ChangeLog.jit
ChangeLog.tree-ssa
compile
config-ml.in
config.guess
config.rpath
config.sub
configure
configure.ac
COPYING
COPYING3
COPYING3.LIB
COPYING.LIB
COPYING.RUNTIME
depcomp
install-sh
libtool-ldflags
libtool.m4
lt~obsolete.m4
ltgcc.m4
ltmain.sh
ltoptions.m4
ltsugar.m4
ltversion.m4
MAINTAINERS MAINTAINERS: Adding myself to to DCO and write after approval 2021-09-10 21:43:10 +02:00
Makefile.def gdb: Add a dependency between gdb and libbacktrace 2021-08-31 10:00:22 +01:00
Makefile.in gdb: Add a dependency between gdb and libbacktrace 2021-08-31 10:00:22 +01:00
Makefile.tpl configure: Allow host fragments to react to --enable-host-shared. 2021-08-18 19:46:32 +01:00
missing
mkdep
mkinstalldirs
move-if-change
multilib.am
README
symlink-tree
test-driver
ylwrap

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.