This is the mail archive of the gcc-patches@gcc.gnu.org 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]

Re: PATCH: Use PLUS instead of HIGH/LO_SUM for large constants


  In message <200109221911.f8MJBCM1023599@hiauly1.hia.nrc.ca>you write:
  > Because the semantics of HIGH/LO_SUM are not well determined, it is prefera
  > ble
  > to use PLUS to load large constants which need to be split into high and lo
  > w
  > parts.  This allows the constant's value to be recocognized during jump
  > expansion and thereby improves deadcode elimination.  As a result, other
  > optimisers shouldn't have to work as hard.  There is the further advantage
  > that the "high" part may be common for several constants and pulled out
  > of loops, etc.
  > 
  > This patch adds the capability to use PLUS on the PA if the constant
  > can be loaded into a register with a ldil/ldo instruction sequence.
  > This is the most common situation.  Really large values are still handled
  > with the old code.
  > 
  > Bootstrap checked with no regressions on hppa1.1-hp-hpux10.20.
  > 
  > OK?
  > 
  > Dave
  > -- 
  > J. David Anglin                                  dave.anglin@nrc.ca
  > National Research Council of Canada              (613) 990-0752 (FAX: 952-6
  > 605)
  > 
  > 2001-09-15  John David Anglin  <dave@hiauly1.hia.nrc.ca>
  > 
  > 	* pa.c (cint_split_ok): New function.
  > 	(emit_move_sequence): When loading a constant into a register, use
  > 	PLUS instead of HIGH/LO_SUM if the constant can be split and loaded
  > 	with a ldil/ldo instruction sequence.
  > 	* pa.md: New addmove pattern for adding constant_int to HImode
  > 	register and moving result to HImode register.
What I would suggest is to avoid HIGH and LO_SUM completely for constants.

Let's take 0x12345678 as an example.

Right now we'd generate

(set (reg X) (high (0x12345678)))
(set (reg Y) (lo_sum (reg X) (0x12345678)))

Instead generate

(set (reg X) (0x12344000))
(set (reg Y) (plus (reg X) (const_int 0x1678))


ie, take the original constant C.

Mask off the low 14 bits to generate C1.
Mask off the high 18 bits to generate C2.

And generate
(set (reg X) (C1)
(set (reg Y) (plus (reg X) (C2)))


I don't think you would need to add any new patterns since the first
insn should already be matched by movsi (ldil case) and the second insn
should be matched by the existing addsi pattern.

jeff


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