aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2017-04-10 14:58:33 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2017-04-10 14:58:33 +0000
commit9b195552ab86ef09b69ddcd3c2243c166c4a8558 (patch)
tree64ff01c322fd901eb7a2fc42fbdd4783ffd41f58
parent1246dc40673aa025027039fbcad61f6100e523ac (diff)
downloadgcc-9b195552ab86ef09b69ddcd3c2243c166c4a8558.zip
gcc-9b195552ab86ef09b69ddcd3c2243c166c4a8558.tar.gz
gcc-9b195552ab86ef09b69ddcd3c2243c166c4a8558.tar.bz2
re PR rtl-optimization/70478 ([LRA] S/390: Performance regression - superfluous stack frame)
2017-04-10 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/70478 * lra-constraints.c (curr_small_class_check): New. (update_and_check_small_class_inputs): New. (process_alt_operands): Update curr_small_class_check. Disfavor alternative insn memory operands. Check available regs for small class operands. From-SVN: r246808
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/lra-constraints.c60
2 files changed, 69 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bf3119a..00b994b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2017-04-10 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/70478
+ * lra-constraints.c (curr_small_class_check): New.
+ (update_and_check_small_class_inputs): New.
+ (process_alt_operands): Update curr_small_class_check. Disfavor
+ alternative insn memory operands. Check available regs for small
+ class operands.
+
2017-03-31 Matthew Fortune <matthew.fortune@imgtec.com>
PR target/80057
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 4d98624..82b1ed0 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1852,6 +1852,42 @@ prohibited_class_reg_set_mode_p (enum reg_class rclass,
(temp, ira_prohibited_class_mode_regs[rclass][mode]));
}
+
+/* Used to check validity info about small class input operands. It
+ should be incremented at start of processing an insn
+ alternative. */
+static unsigned int curr_small_class_check = 0;
+
+/* Update number of used inputs of class OP_CLASS for operand NOP.
+ Return true if we have more such class operands than the number of
+ available regs. */
+static bool
+update_and_check_small_class_inputs (int nop, enum reg_class op_class)
+{
+ static unsigned int small_class_check[LIM_REG_CLASSES];
+ static int small_class_input_nums[LIM_REG_CLASSES];
+
+ if (SMALL_REGISTER_CLASS_P (op_class)
+ /* We are interesting in classes became small because of fixing
+ some hard regs, e.g. by an user through GCC options. */
+ && hard_reg_set_intersect_p (reg_class_contents[op_class],
+ ira_no_alloc_regs)
+ && (curr_static_id->operand[nop].type != OP_OUT
+ || curr_static_id->operand[nop].early_clobber))
+ {
+ if (small_class_check[op_class] == curr_small_class_check)
+ small_class_input_nums[op_class]++;
+ else
+ {
+ small_class_check[op_class] = curr_small_class_check;
+ small_class_input_nums[op_class] = 1;
+ }
+ if (small_class_input_nums[op_class] > ira_class_hard_regs_num[op_class])
+ return true;
+ }
+ return false;
+}
+
/* Major function to choose the current insn alternative and what
operands should be reloaded and how. If ONLY_ALTERNATIVE is not
negative we should consider only this alternative. Return false if
@@ -1952,6 +1988,7 @@ process_alt_operands (int only_alternative)
if (!TEST_BIT (preferred, nalt))
continue;
+ curr_small_class_check++;
overall = losers = addr_losers = 0;
static_reject = reject = reload_nregs = reload_sum = 0;
for (nop = 0; nop < n_operands; nop++)
@@ -2685,6 +2722,21 @@ process_alt_operands (int only_alternative)
}
}
+ /* When we use memory operand, the insn should read the
+ value from memory and even if we just wrote a value
+ into the memory it is costly in comparison with an
+ insn alternative which does not use memory
+ (e.g. register or immediate operand). */
+ if (no_regs_p && offmemok)
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " Using memory insn operand %d: reject+=3\n",
+ nop);
+ reject += 3;
+ }
+
#ifdef SECONDARY_MEMORY_NEEDED
/* If reload requires moving value through secondary
memory, it will need one more insn at least. */
@@ -2747,6 +2799,14 @@ process_alt_operands (int only_alternative)
goto fail;
}
+ if (update_and_check_small_class_inputs (nop, this_alternative))
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " alt=%d, not enough small class regs -- refuse\n",
+ nalt);
+ goto fail;
+ }
curr_alt[nop] = this_alternative;
COPY_HARD_REG_SET (curr_alt_set[nop], this_alternative_set);
curr_alt_win[nop] = this_alternative_win;