aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2013-05-30 20:30:38 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2013-05-30 20:30:38 +0000
commit3b9ceb4b4fd657faf031cc5fc47acc4ecae0ad88 (patch)
tree16088611f26652c55d7f6a9b476049876bd2cdc8 /gcc
parentcc059bdd149ced1b66f912c54c8f435379abb4ad (diff)
downloadgcc-3b9ceb4b4fd657faf031cc5fc47acc4ecae0ad88.zip
gcc-3b9ceb4b4fd657faf031cc5fc47acc4ecae0ad88.tar.gz
gcc-3b9ceb4b4fd657faf031cc5fc47acc4ecae0ad88.tar.bz2
target.def (register_usage_leveling_p): New hook.
2013-05-30 Vladimir Makarov <vmakarov@redhat.com> * target.def (register_usage_leveling_p): New hook. * targhooks.c (default_register_usage_leveling_p): New. * targhooks.h (default_register_usage_leveling_p): New prototype. * lra-assigns.c (register_usage_leveling_p): Use the hook. * doc/tm.texi.in (TARGET_REGISTER_USAGE_LEVELING_P): New hook. * doc/tm.texi: Update. * config/i386/i386.c (TARGET_REGISTER_USAGE_LEVELING_P): Define. From-SVN: r199459
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/i386/i386.c3
-rw-r--r--gcc/doc/tm.texi4
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/lra-assigns.c6
-rw-r--r--gcc/target.def15
-rw-r--r--gcc/targhooks.c6
-rw-r--r--gcc/targhooks.h1
8 files changed, 42 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f73640a..ddd2a30 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2013-05-30 Vladimir Makarov <vmakarov@redhat.com>
+
+ * target.def (register_usage_leveling_p): New hook.
+ * targhooks.c (default_register_usage_leveling_p): New.
+ * targhooks.h (default_register_usage_leveling_p): New prototype.
+ * lra-assigns.c (register_usage_leveling_p): Use the hook.
+ * doc/tm.texi.in (TARGET_REGISTER_USAGE_LEVELING_P): New hook.
+ * doc/tm.texi: Update.
+ * config/i386/i386.c (TARGET_REGISTER_USAGE_LEVELING_P): Define.
+
2013-05-30 Ian Bolton <ian.bolton@arm.com>
* config/aarch64/aarch64.md (insv<mode>): New define_expand.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c37108b..e8f47c9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -42812,6 +42812,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
#undef TARGET_REGISTER_PRIORITY
#define TARGET_REGISTER_PRIORITY ix86_register_priority
+#undef TARGET_REGISTER_USAGE_LEVELING_P
+#define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
+
#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cfde14a..f840481 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2898,6 +2898,10 @@ A target hook which returns true if we use LRA instead of reload pass. It means
A target hook which returns the register priority number to which the register @var{hard_regno} belongs to. The bigger the number, the more preferable the hard register usage (when all other conditions are the same). This hook can be used to prefer some hard register over others in LRA. For example, some x86-64 register usage needs additional prefix which makes instructions longer. The hook can return lower priority number for such registers make them less favorable and as result making the generated code smaller. The default version of this target hook returns always zero.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_REGISTER_USAGE_LEVELING_P (void)
+A target hook which returns true if we need register usage leveling. That means if a few hard registers are equally good for the assignment, we choose the least used hard register. The register usage leveling may be profitable for some targets. Don't use the usage leveling for targets with conditional execution or targets with big register files as it hurts if-conversion and cross-jumping optimizations. The default version of this target hook returns always false.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_DIFFERENT_ADDR_DISPLACEMENT_P (void)
A target hook which returns true if an address with the same structure can have different maximal legitimate displacement. For example, the displacement can depend on memory mode or on operand combinations in the insn. The default version of this target hook returns always false.
@end deftypefn
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 611d681..b08dece 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2870,6 +2870,8 @@ as below:
@hook TARGET_REGISTER_PRIORITY
+@hook TARGET_REGISTER_USAGE_LEVELING_P
+
@hook TARGET_DIFFERENT_ADDR_DISPLACEMENT_P
@hook TARGET_SPILL_CLASS
diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index 78bc2e7..9719f0d 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -603,11 +603,7 @@ find_hard_regno_for (int regno, int *cost, int try_only_hard_regno)
if (best_hard_regno < 0 || hard_regno_costs[hard_regno] < best_cost
|| (hard_regno_costs[hard_regno] == best_cost
&& (priority > best_priority
- /* Hard register usage leveling actually results
- in bigger code for targets with conditional
- execution like ARM because it reduces chance
- of if-conversion after LRA. */
- || (! targetm.have_conditional_execution ()
+ || (targetm.register_usage_leveling_p ()
&& priority == best_priority
&& best_usage > lra_hard_reg_usage[hard_regno]))))
{
diff --git a/gcc/target.def b/gcc/target.def
index f4776a8..3ba3e0a 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2444,6 +2444,21 @@ DEFHOOK
int, (int),
default_register_priority)
+/* Return true if we need register usage leveling. */
+DEFHOOK
+(register_usage_leveling_p,
+ "A target hook which returns true if we need register usage leveling.\
+ That means if a few hard registers are equally good for the\
+ assignment, we choose the least used hard register. The register\
+ usage leveling may be profitable for some targets. Don't use the\
+ usage leveling for targets with conditional execution or targets\
+ with big register files as it hurts if-conversion and cross-jumping\
+ optimizations.\
+ \
+ The default version of this target hook returns always false.",
+ bool, (void),
+ default_register_usage_leveling_p)
+
/* Return true if maximal address displacement can be different. */
DEFHOOK
(different_addr_displacement_p,
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 80b4aa6..d3a3f5f 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -859,6 +859,12 @@ default_register_priority (int hard_regno ATTRIBUTE_UNUSED)
}
extern bool
+default_register_usage_leveling_p (void)
+{
+ return false;
+}
+
+extern bool
default_different_addr_displacement_p (void)
{
return false;
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ce10ebc..2da6fb8 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -135,6 +135,7 @@ extern int default_return_pops_args (tree, tree, int);
extern reg_class_t default_branch_target_register_class (void);
extern bool default_lra_p (void);
extern int default_register_priority (int);
+extern bool default_register_usage_leveling_p (void);
extern bool default_different_addr_displacement_p (void);
extern reg_class_t default_secondary_reload (bool, rtx, reg_class_t,
enum machine_mode,