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]

More x86 left shift improvements

After further discussions with Richard, a few more changes to the x86 left
shift patterns are desirable.

  First, my documentation for the PPro incorrectly listed mov reg,reg as
  generating a P01 and P2 uop.  In reality, it only generates a P01 uop.
  So, the cost/benefit analysis for constant shifts by > 3 bits changes
  with the result that a mov followed by normal shift code is best.

  Second, there's still some concerns about generating too many AGI stalls,
  particularly for the constant shifts by > 3 bits on Pentiums.

  Third, the generic ashlsi3 pattern exposed a 3 operand shift (ie shifts
  that can be profitably done with lea).  However, by doing so, it prevented
  regmove from optimizing the code.

The net result of addressing those issues is actually a simpler ashlsi3
implementation than we currently have in the sources.

The patterns now look like:

(define_expand "ashlsi3"
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
                   (match_operand:SI 2 "nonmemory_operand" "")))]

;; Pattern for shifts which can be encoded into an lea instruction.
;; This is kept as a separate pattern so that regmove can optimize cases
;; where we know the source and destination must match.
;; Do not expose this pattern when optimizing for size since we never want
;; to use lea when optimizing for size since mov+sal is smaller than lea.
(define_insn ""
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
                   (match_operand:SI 2 "small_shift_operand" "M,M")))]
  "! optimize_size"
  "* return output_ashlsi3 (operands);")

;; Generic left shift pattern to catch all cases not handled by the lea
;; shift pattern above.
(define_insn ""
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
                   (match_operand:SI 2 "nonmemory_operand" "cI")))]
  "* return output_ashlsi3 (operands);")

With a couple new functions in i386.c (small_shift_operand and output_ashlsi3).

I'll be doing a test of this code overnight.


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