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]

Re: FW: [avr-libc-dev] Fwd: Testresults for [PATCH]: Rewrite AVRbackend's rtx_costs (take 3)

My setup now doesn't give the reload failure on the testcase.

I have not tested code!!

As per last message, the block move scoops up the pointer registers. As this is a stack move, we also have frame pointer involved to calculate addresses. Net result, we run out of pointer registers when reload is not smart enough to juggle that much. Same as bug 18251.

As to what causes the regression, I cannot be sure but it might be change in constant costs. gcc still seems to be saving them in registers. On the otherhand it could equally be that we got lucky when code got rearranged!

The attached code replaces the patterns in and now only allows non-pointer registers "al" as a counter for *movmemqi_insn. As any register can be used, that restriction is not significant.

I also took the liberty of using r0 as the asm down counter thus preserving the count value. This helps where the count is required again to readjust the stack or perform an identically sized move. It adds a word (mov r0, Rcount) but I think overall it makes the compile more robust and a possible win (the test case wins).

The other block *movmemhi pattern has similar risk. This version is used when count >255 or varaible. I changed "d" constaint to "a" constraint - again that prevents pattern choosing pointer regsister. The first alternative !w still allows pointers but "!" means only if the register does not need a reload. Not perfect but should be safer than what we have. (A slightly better version could add 3rd alternative of general register "r" as a counter with a couple of extra asm words to handle the 16 bit decrement.)

There are other block clear instrcutions, but these require one less pointer register - so should not be a problem.

I did notice a couple of other things with this testcase

1) that gcc is putting out long (SImode) loop counters in this testcase, where C is using int. I have seen this before in 4.0. but now I think I can extract testcase and report as bug. I might need help to verify on "clean" 4.0

2) Gcc forgets that it has SP value in register after loading SP and reads it back out of SP. This may be cost related but should be nothing to do with rtx costs. Add that to the list!

Anyway put this in and "make install" ans see how the testing comes out.

(define_insn "*movmemqi_insn" [(set (mem:BLK (match_operand:HI 0 "register_operand" "e")) (mem:BLK (match_operand:HI 1 "register_operand" "e"))) (use (match_operand:QI 2 "register_operand" "al")) (use (match_operand:QI 3 "const_int_operand" "i")) (clobber (match_scratch:HI 4 "=0")) (clobber (match_scratch:HI 5 "=1"))] "" "mov __zero_reg__,%2 ld __tmp_reg__,%a1+ st %a0+,__tmp_reg__ dec __zero_reg__ brne .-8" [(set_attr "length" "5") (set_attr "cc" "clobber")])

(define_insn "*movmemhi"
  [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
   (mem:BLK (match_operand:HI 1 "register_operand" "e,e")))
   (use (match_operand:HI 2 "register_operand" "!w,a"))
   (use (match_operand:HI 3 "const_int_operand" ""))
   (clobber (match_scratch:HI 4 "=0,0"))
   (clobber (match_scratch:HI 5 "=1,1"))
   (clobber (match_scratch:HI 6 "=2,2"))]
     if (which_alternative==0)
       return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
          AS2 (st,%a0+,__tmp_reg__)  CR_TAB
          AS2 (sbiw,%A2,1) CR_TAB
          AS1 (brne,.-8));
       return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
          AS2 (st,%a0+,__tmp_reg__)  CR_TAB
          AS2 (subi,%A2,1) CR_TAB
          AS2 (sbci,%B2,0) CR_TAB
          AS1 (brne,.-10));
  [(set_attr "length" "4,5")
   (set_attr "cc" "clobber,clobber")])

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