![]() Extend range query done by loop-ch to also support basic blocks that are not headers of the loop. This is easy to do, since we already do path specific query so we only need to extend the path by headers we decided to dulicate earlier. This makes it possible to track situations where exit that is always false in the first iteration (wihch is a common case) is not in the first iteration of the loop. Doing so lets us to update profile better and do better heuristics. In particular I changed logic as follows 1) should_duplicate_loop_header_p counts size of duplicated region. When we know that a given conditional will be constant true or constant false either in the duplicated region, by range query, or in the loop body after duplication (since it is loop invariant), we do not account it to code size costs 2) don't need account loop invariant compuations that will be duplicated as they will become fully invariant (maybe we want to have some cap for register pressure eventually?) 3) optimize_size logic is now different. Originally we started duplicating iff the first conditional was known to be true by ranger query, but then we used same limits as for -O2. I now simply lower limits to 0. This means that every conditional in duplicated sequence must be either loop invariant or constant when duplicated and we only duplicate statements computing loop invariants and those we account to 0 size anyway, This makes code IMO more logical, but makes little difference in practice. The problem is that in loop: void test2(); void test(int n) { for (int i = 0; n && i < 10; i++) test2(); } We produce: <bb 4> [local count: 1073741824 freq: 9.090909]: # i_4 = PHI <0(2), i_9(3)> _1 = n_7(D) != 0; _2 = i_4 <= 9; _3 = _1 & _2; if (_3 != 0) goto <bb 3>; [89.00%] else goto <bb 5>; [11.00%] and do not understand that the final conditional is a combination of a conditional that is always true in first iteration and a conditional that is loop invariant. This is also the case of void test2(); void test(int n) { for (int i = 0; n; i++) { if (i > 10) break; test2(); } } Which we turn to the earlier case in ifcombine. With disabled ifcombine things however works as exepcted. This is something I plan to handle incrementally. However extending loop-ch and peeling passes to understand such combined conditionals is still not good enough: at the time ifcombine merged the two conditionals we lost profile information on how often n is 0, so we can't recover correct profile or know what is expected number of iterations after the transofrm. gcc/ChangeLog: * tree-ssa-loop-ch.cc (edge_range_query): Take loop argument; be ready for queries not in headers. (static_loop_exit): Add basic blck parameter; update use of edge_range_query (should_duplicate_loop_header_p): Add ranger and static_exits parameter. Do not account statements that will be optimized out after duplicaiton in overall size. Add ranger query to find static exits. (update_profile_after_ch): Take static_exits has set instead of single eliminated_edge. (ch_base::copy_headers): Do all analysis in the first pass; remember invariant_exits and static_exits. |
||
---|---|---|
c++tools | ||
config | ||
contrib | ||
fixincludes | ||
gcc | ||
gnattools | ||
gotools | ||
include | ||
INSTALL | ||
intl | ||
libada | ||
libatomic | ||
libbacktrace | ||
libcc1 | ||
libcody | ||
libcpp | ||
libdecnumber | ||
libffi | ||
libgcc | ||
libgfortran | ||
libgm2 | ||
libgo | ||
libgomp | ||
libiberty | ||
libitm | ||
libobjc | ||
libphobos | ||
libquadmath | ||
libsanitizer | ||
libssp | ||
libstdc++-v3 | ||
libvtv | ||
lto-plugin | ||
maintainer-scripts | ||
zlib | ||
.dir-locals.el | ||
.gitattributes | ||
.gitignore | ||
ABOUT-NLS | ||
ar-lib | ||
ChangeLog | ||
ChangeLog.jit | ||
ChangeLog.tree-ssa | ||
compile | ||
config-ml.in | ||
config.guess | ||
config.rpath | ||
config.sub | ||
configure | ||
configure.ac | ||
COPYING | ||
COPYING.LIB | ||
COPYING.RUNTIME | ||
COPYING3 | ||
COPYING3.LIB | ||
depcomp | ||
install-sh | ||
libtool-ldflags | ||
libtool.m4 | ||
ltgcc.m4 | ||
ltmain.sh | ||
ltoptions.m4 | ||
ltsugar.m4 | ||
ltversion.m4 | ||
lt~obsolete.m4 | ||
MAINTAINERS | ||
Makefile.def | ||
Makefile.in | ||
Makefile.tpl | ||
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.