This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add extensive commentary to sparc's "U" constraint.

Vlad, I wanted to make you aware of the following because it's
a major barrier for using LRA on sparc at this time.  I therefore
do not think moving to LRA on this target is possible in the 4.8
timeframe, which is fine.  The situation is described completely
in the comment I am adding in the patch below.

The most alarming aspect of this to me was discovering that IRA could
allocate registers to a pseudo that did not pass HARD_REGNO_MODE_OK,
and this anomaly is completely masked because reload and our splitters
end up fixing things up.

I wanted to explicitly thank you for your work on LRA because without
it we would never have discovered these inconsistencies in the sparc

One idea that occurred to me was perhaps to extend
define_register_constraint such that an extra condition can be
specified.  So for sparc's constraint "U" it would evaluate to
GENERAL_REGS but also express the condition that the hard register
must be even.  Then we could make the implementation of the macro
REG_CLASS_FROM_CONSTRAINT test the extra condition specified in
define_register_constraint, and return NO_REGS if that condition does
not pass.

But it would be much nicer if register classes could do what we need
them to.  Such a solution would be both cleaner, and significantly
more efficient.

	* config/sparc/ ("U"): Document, in detail,
	which this constraint is necessary.
 gcc/ChangeLog                   |  5 +++++
 gcc/config/sparc/ | 38 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 24d9845..64e7596 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-11-07  David S. Miller  <>
+	* config/sparc/ ("U"): Document, in detail,
+	which this constraint is necessary.
 2012-11-07  Richard Henderson  <>
 	* trans-mem.c (pass_ipa_tm): Don't use TODO_update_ssa.
diff --git a/gcc/config/sparc/ b/gcc/config/sparc/
index 2f8c6ad..440dc57 100644
--- a/gcc/config/sparc/
+++ b/gcc/config/sparc/
@@ -130,7 +130,43 @@
       (match_code "mem")
       (match_test "memory_ok_for_ldd (op)")))
-;; Not needed in 64-bit mode
+;; This awkward register constraint is necessary because it is not
+;; possible to express the "must be even numbered regsiter" condition
+;; using register classes.  The problem is that membership in a
+;; register class requires that all registers of a multi-regno
+;; register be included in the set.  It is add_to_hard_reg_set
+;; and in_hard_reg_set_p which populate and test regsets with these
+;; semantics.
+;; So this means that we would have to put both the even and odd
+;; register into the register class, which would not restrict things
+;; at all.
+;; Using a combination of GENERAL_REGS and HARD_REGNO_MODE_OK is not a
+;; full solution either.  In fact, even though IRA uses the macro
+;; HARD_REGNO_MODE_OK to calculate which registers are prohibited from
+;; use in certain modes, it still can allocate an odd hard register
+;; for DImode values.  This is due to how IRA populates the table
+;; ira_useful_class_mode_regs[][].  It suffers from the same problem
+;; as using a register class to describe this restriction.  Namely, it
+;; sets both the odd and even part of an even register pair in the
+;; regset.  Therefore IRA can and will allocate odd registers for
+;; DImode values on 32-bit.
+;; There are legitimate cases where DImode values can end up in odd
+;; hard registers, the most notable example is argument passing.
+;; What saves us is reload and the DImode splitters.  Both are
+;; necessary.  The odd register splitters cannot match if, for
+;; example, we have a non-offsetable MEM.  Reload will notice this
+;; case and reload the address into a single hard register.
+;; The real downfall of this awkward register constraint is that it does
+;; not evaluate to a true register class like a bonafide use of
+;; define_register_constraint would.  This currently means that we cannot
+;; use LRA on Sparc, since the constraint processing of LRA really depends
+;; upon whether an extra constraint is for registers or not.  It uses
+;; REG_CLASS_FROM_CONSTRAINT, and checks it against NO_REGS.
 (define_constraint "U"
  "Pseudo-register or hard even-numbered integer register"
  (and (match_test "TARGET_ARCH32")

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]