Again thank you and Denis for your comment.

Here is what I deduce from code and Denis comments - I am sure he (and others) will correct me if wrong :-)


The main issue is that we have one pointer register that cannot take offset and two base pointers with limited offset (0-63).

Reload provides no means to pick the right pointer register. To do so would require a "preffered base pointer" mechanism.

AVR L_R_A sole purpose is substituting POINTER class where there are oppertunities to do so.

BUT as L_R_A is in middle of find_reloads_address, we have a problem in that some normal reload solutions have already been applied and some have not.

This may mean that 1) We never get here - so miss POINTER oppertunity or 2) Miss even better solutions that are applied latter.
3)Have code vulnerable to reload changes.


I have added comment below to explain the parts.
I'll probably need to add some debug hooks to check what parts still contribute.

best regards

Andy



#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \
do {                                        \
 if (1&&(GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC))     \
   {                                       \
push_reload (XEXP (X,0), XEXP (X,0), &XEXP (X,0), &XEXP (X,0), \
              POINTER_REGS, GET_MODE (X),GET_MODE (X) , 0, 0,      \
          OPNUM, RELOAD_OTHER);                    \
     goto WIN;                                 \
   }                                       \


The intent is to use POINTER class registers for INC/DEC so we have one more register available than BASE_POINTER

Has  INC/DEC been handled already making this part redundant?
Are there any other solutions that this code skips?



 if (GET_CODE (X) == PLUS                          \
     && REG_P (XEXP (X, 0))                            \
     && GET_CODE (XEXP (X, 1)) == CONST_INT                    \
     && INTVAL (XEXP (X, 1)) >= 1)                     \
   {                                       \
int fit = INTVAL (XEXP (X, 1)) <= (64 - GET_MODE_SIZE (MODE)); \
     if (fit)                                  \
   {                                   \
         if (reg_equiv_address[REGNO (XEXP (X, 0))] != 0)          \
       {                                   \
         int regno = REGNO (XEXP (X, 0));                  \
         rtx mem = make_memloc (X, regno);                 \
push_reload (XEXP (mem,0), NULL, &XEXP (mem,0), NULL, \
                  POINTER_REGS, Pmode, VOIDmode, 0, 0,         \
                  1, ADDR_TYPE (TYPE));                \
         push_reload (mem, NULL_RTX, &XEXP (X, 0), NULL,           \
                  BASE_POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \
                  OPNUM, TYPE);                    \
         goto WIN;                             \
       }

Im struggling with this part. however, the POINTER class is an advantageous in the first reloading the address from memory - where we would not want to waste BASE POINTER and also create overlap problem.

The implication of using this code is that without it we cannot catch the inner reload POINTER oppertunity if we leave reload to decompose BASE+offset. I think this is correct :-(


                              \
     push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,       \
              BASE_POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0,     \
              OPNUM, TYPE);                        \
         goto WIN;

This part is duplicating reload and should not be here (I have patch pending with maintainer that removes this - for different bug)

                     \
   }                                   \
else if (! (frame_pointer_needed && XEXP (X,0) == frame_pointer_rtx)) \
   {                                   \
     push_reload (X, NULL_RTX, &X, NULL,                   \
              POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0,      \
              OPNUM, TYPE);                        \
         goto WIN;                             \
   }                                   \
   }                                       \

This case is where offset is out of range - so we allow POINTER class on the basis that this is no worse than BASE POINTER. However, we leave frame_pointer to reload.




} while(0)








-----Original Message-----
From: Denis Chertykov <[EMAIL PROTECTED]>
To: Jeff Law <[EMAIL PROTECTED]>
Cc: Andy H <[EMAIL PROTECTED]>; GCC Development <gcc@gcc.gnu.org>; [EMAIL PROTECTED]
Sent: Thu, 29 May 2008 3:23 am
Subject: Re: Help with reload and naked constant sum causing ICE



2008/5/29 Jeff Law <[EMAIL PROTECTED]>:
Richard Sandiford wrote:

Andy H <[EMAIL PROTECTED]> writes:

If L_R_A does nothing with it,
the normal reload handling will first try:

(const:HI (plus:HI (symbol_ref:HI ("chk_fail_buf") (const_int
2))))


This worked just as your described after I added test of
reg_equiv_constant[] inside L_R_A .

So I guess that looks like  the fix for bug I posted.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34641

To summarize

LEGITIMIZE_RELOAD_ADDRESS should now always check reg_equiv_constant
before it trying to do any push_reload of register.

TBH, I still think AVR is doing far too much in L_R_A.  To quote
the current version:

[...]
Not only should there be some comments, those comments should clearly
explain how L_R_A is improving the generated code. That is LRA's
job, to
implement target specific reload strategies which improve the
generated
code. If the AVR port is using L_R_A for *correctness*, then the AVR
port
is broken.

I wrote L_R_A for *correctness*, so in your terms AVR port is broken.
It's because AVR have only 3 pointer registers (X,Y,Z) and only 2 of
them Y and Z are base pointers.
Y is a frame pointer, so only one general base pointer - Z.
Offset also very limited -63 to +63.
In L_R_A I play with POINTER_REGS (X,Y,Z) and BASE_POINTER_REGS (Y,Z).
My experiments with reload show me that reload can't handle all
difficult situations.
Also, Jeff I know that you think that reload can.
GCC havn't something like (define_address ...) and reload can't handle
POINTER_REGS and
BASE_POINTER_REGS differently. In my version of L_R_A I tried to do it.

Denis.

Reply via email to