This is the main substance of this patch series. Instead of doing all of the prologue and epilogue in one spot, it often is better to do components of it at different places, so that they are executed less frequently. What exactly is a component is completely up to the target; this code treats it all abstractly, and uses hooks for the target to handle the more concrete things. Commonly there is one component for each callee- saved register, for example. Components can be executed more than once per function execution. This pass makes sure that a component's epilogue is not called more often than the corresponding prologue has been, at any point in time; that the prologue is called more often, wherever the prologue's effect is needed; and that the epilogue is called as often as the prologue has been, when the function exits. It does this by first deciding which blocks need which components active, and then placing prologue and epilogue components to make that exactly true. Deciding what blocks should run with a certain component active so that the total cost of executing the prologues (and epilogues) is optimal, is not a computationally feasible problem. Instead, for each basic block, we estimate the cost of putting a prologue right before the block, and if that is cheaper than the total cost of putting prologues optimally (according to the estimated cost) in the dominator subtrees strictly dominated by this first block, place it at the first block instead. This simple procedure places the components optimally for any dominator sub tree where the root node's cost does not depend on anything outside its subtree. The cost is the execution frequency of all edges into the block coming from blocks that do not have this component active. The estimated cost is the execution frequency of the block, minus the execution frequency of any backedges (which by definition are coming from subtrees, so if the "head" block gets a prologue, the source block of any backedge has that component active as well). Currently, the epilogues are placed as late as possible, given the constraints. This does not matter for execution cost, but we could save a little bit of code size by placing the epilogues in a smarter way. This is a possible future optimisation. Now all that is left is inserting prologues and epilogues on all edges that jump into resp. out of the "active" set of blocks. Often we need to insert some components' prologues (or epilogues) on all edges into (or out of) a block. In theory cross-jumping can unify all such, but in practice that often fails; besides, that is a lot of work. So in this case we insert the prologue and epilogue components at the "head" or "tail" of a block, instead. As a final optimisation, if a block needs a prologue and its immediate dominator has the block as a post-dominator, that immediate dominator gets the prologue as well. * function.c (thread_prologue_and_epilogue_insns): Call try_shrink_wrapping_separate. Compute the prologue_seq afterwards, if it has possibly changed. Compute the split_prologue_seq and epilogue_seq later, too. * shrink-wrap.c: #include cfgbuild.h and insn-config.h. (dump_components): New function. (struct sw): New struct. (SW): New function. (init_separate_shrink_wrap): New function. (fini_separate_shrink_wrap): New function. (place_prologue_for_one_component): New function. (spread_components): New function. (disqualify_problematic_components): New function. (emit_common_heads_for_components): New function. (emit_common_tails_for_components): New function. (insert_prologue_epilogue_for_components): New function. (try_shrink_wrapping_separate): New function. * shrink-wrap.h: Declare try_shrink_wrapping_separate. From-SVN: r241063
Name |
Last commit
|
Last update |
---|---|---|
INSTALL | Loading commit data... | |
boehm-gc | Loading commit data... | |
config | Loading commit data... | |
contrib | Loading commit data... | |
fixincludes | Loading commit data... | |
gcc | Loading commit data... | |
gnattools | Loading commit data... | |
gotools | Loading commit data... | |
include | Loading commit data... | |
intl | Loading commit data... | |
libada | Loading commit data... | |
libatomic | Loading commit data... | |
libbacktrace | Loading commit data... | |
libcc1 | Loading commit data... | |
libcilkrts | Loading commit data... | |
libcpp | Loading commit data... | |
libdecnumber | Loading commit data... | |
libffi | Loading commit data... | |
libgcc | Loading commit data... | |
libgfortran | Loading commit data... | |
libgo | Loading commit data... | |
libgomp | Loading commit data... | |
libiberty | Loading commit data... | |
libitm | Loading commit data... | |
libmpx | Loading commit data... | |
libobjc | Loading commit data... | |
liboffloadmic | Loading commit data... | |
libquadmath | Loading commit data... | |
libsanitizer | Loading commit data... | |
libssp | Loading commit data... | |
libstdc++-v3 | Loading commit data... | |
libvtv | Loading commit data... | |
lto-plugin | Loading commit data... | |
maintainer-scripts | Loading commit data... | |
zlib | Loading commit data... | |
.dir-locals.el | Loading commit data... | |
.gitattributes | Loading commit data... | |
.gitignore | Loading commit data... | |
ABOUT-NLS | Loading commit data... | |
COPYING | Loading commit data... | |
COPYING.LIB | Loading commit data... | |
COPYING.RUNTIME | Loading commit data... | |
COPYING3 | Loading commit data... | |
COPYING3.LIB | Loading commit data... | |
ChangeLog | Loading commit data... | |
ChangeLog.jit | Loading commit data... | |
ChangeLog.tree-ssa | Loading commit data... | |
MAINTAINERS | Loading commit data... | |
Makefile.def | Loading commit data... | |
Makefile.in | Loading commit data... | |
Makefile.tpl | Loading commit data... | |
README | Loading commit data... | |
compile | Loading commit data... | |
config-ml.in | Loading commit data... | |
config.guess | Loading commit data... | |
config.rpath | Loading commit data... | |
config.sub | Loading commit data... | |
configure | Loading commit data... | |
configure.ac | Loading commit data... | |
depcomp | Loading commit data... | |
install-sh | Loading commit data... | |
libtool-ldflags | Loading commit data... | |
libtool.m4 | Loading commit data... | |
ltgcc.m4 | Loading commit data... | |
ltmain.sh | Loading commit data... | |
ltoptions.m4 | Loading commit data... | |
ltsugar.m4 | Loading commit data... | |
ltversion.m4 | Loading commit data... | |
lt~obsolete.m4 | Loading commit data... | |
missing | Loading commit data... | |
mkdep | Loading commit data... | |
mkinstalldirs | Loading commit data... | |
move-if-change | Loading commit data... | |
symlink-tree | Loading commit data... | |
ylwrap | Loading commit data... |