aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYuri Rumyantsev <ysrumyan@gmail.com>2012-10-26 12:07:58 +0000
committerKirill Yukhin <kyukhin@gcc.gnu.org>2012-10-26 12:07:58 +0000
commit39aada703b3852c373ad5b7c9f8d9bf9e73f40ad (patch)
tree11a288bab4b4bbe0e90e25ac2982aea931308bbe /gcc
parent9037dcc6adff20ba865674388e5ab9b70ba817e3 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/config/i386/i386.c33
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;
}