diff options
author | Yuri Rumyantsev <ysrumyan@gmail.com> | 2012-10-26 12:07:58 +0000 |
---|---|---|
committer | Kirill Yukhin <kyukhin@gcc.gnu.org> | 2012-10-26 12:07:58 +0000 |
commit | 39aada703b3852c373ad5b7c9f8d9bf9e73f40ad (patch) | |
tree | 11a288bab4b4bbe0e90e25ac2982aea931308bbe /gcc | |
parent | 9037dcc6adff20ba865674388e5ab9b70ba817e3 (diff) | |
download | gcc-39aada703b3852c373ad5b7c9f8d9bf9e73f40ad.zip gcc-39aada703b3852c373ad5b7c9f8d9bf9e73f40ad.tar.gz gcc-39aada703b3852c373ad5b7c9f8d9bf9e73f40ad.tar.bz2 |
i386.c (insn_is_function_arg): Add check on CALL instruction.
* config/i386/i386.c (insn_is_function_arg) : Add check on CALL
instruction.
(ix86_dependencies_evaluation_hook): Insert dependencies in all
predecessors of call block for non-trivial region avoiding creation
of loop-carried dependency to avoid cross-block motion of HW registers.
From-SVN: r192842
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 33 |
2 files changed, 30 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96e6045..5f3c8ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-10-23 Yuri Rumyantsev <ysrumyan@gmail.com> + + * config/i386/i386.c (insn_is_function_arg) : Add check on CALL + instruction. + (ix86_dependencies_evaluation_hook): Insert dependencies in all + predecessors of call block for non-trivial region avoiding creation + of loop-carried dependency to avoid cross-block motion of HW registers. + 2012-10-26 Richard Biener <rguenther@suse.de> PR middle-end/54824 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 2a9db18..b575dc2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -24454,6 +24454,9 @@ insn_is_function_arg (rtx insn, bool* is_spilled) if (!NONDEBUG_INSN_P (insn)) return false; + /* Call instructions are not movable, ignore it. */ + if (CALL_P (insn)) + return false; insn = PATTERN (insn); if (GET_CODE (insn) == PARALLEL) insn = XVECEXP (insn, 0, 0); @@ -24586,18 +24589,26 @@ ix86_dependencies_evaluation_hook (rtx head, rtx tail) first_arg = add_parameter_dependencies (insn, head); if (first_arg) { - /* Check if first argument has dependee out of its home block. */ - sd_iterator_def sd_it1; - dep_t dep1; - FOR_EACH_DEP (first_arg, SD_LIST_BACK, sd_it1, dep1) + /* Add dependee for first argument to predecessors if only + region contains more than one block. */ + basic_block bb = BLOCK_FOR_INSN (insn); + int rgn = CONTAINING_RGN (bb->index); + int nr_blks = RGN_NR_BLOCKS (rgn); + /* Skip trivial regions and region head blocks that can have + predecessors outside of region. */ + if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0) { - rtx dee; - dee = DEP_PRO (dep1); - if (!NONDEBUG_INSN_P (dee)) - continue; - if (BLOCK_FOR_INSN (dee) != BLOCK_FOR_INSN (first_arg)) - /* Must add dependee for first argument in dee's block. */ - add_dependee_for_func_arg (first_arg, BLOCK_FOR_INSN (dee)); + edge e; + edge_iterator ei; + /* Assume that region is SCC, i.e. all immediate predecessors + of non-head block are in the same region. */ + FOR_EACH_EDGE (e, ei, bb->preds) + { + /* Avoid creating of loop-carried dependencies through + using topological odering in region. */ + if (BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index)) + add_dependee_for_func_arg (first_arg, e->src); + } } insn = first_arg; } |