This is the mail archive of the gcc@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]
Other format: [Raw text]

Re: Extending constraints using register subclasses


> >> On Mon, May 11, 2009 at 4:45 PM, Jamie Prescott wrote:

> >> 
> >>> Hi!
> >>> I wanted to add finer (one per) register subclasses, so that I can more 
> finely 
> >> control
> >>> the register placement inside the inline assembly.
> >> 
> >> You don't need that.
> >> You can just use asm("registername") on variables.
> >> like so:
> >> 
> >> int f(int a)
> >> {
> >>  register int r0 __asm__("r0");
> >>  asm("use %0": "+r"(r0) );
> >> }
> >> 
> >> Thanks,
> >> Andrew Pinski
> 
> That works with gcc 3.x but causes trouble and won't work smooth with gcc 4.x.
> 
> Here are just two examples that will crash for target AVR:
> 
> // ice.c ////////////////////////////////////////////////
> typedef union
> {
>     unsigned char  asByte[2];
>     unsigned short asWord;
> } data16_t;
> 
> data16_t mac10 (data16_t);
> 
> void put_sfrac16 (data16_t q)
> {
>     unsigned char i;
>     for (i=0; i < 2; i++)
>     {
>         register data16_t digit asm ("r24");
>         digit.asByte[1] = 0;
> 
>         digit.asByte[0] = q.asByte[0];
>         digit = mac10 (digit);
>         q.asByte[0] = digit.asByte[0];
>     }
> }
> //////////////////////////////////////////////////
> 
> compiling this with
> > avr-gcc ice.c -Os -S
> rund into ICE in fwprop:
> 
> ice.c: In function 'put_sfrac16':
> ice.c:21: internal compiler error: in propagate_rtx, at fwprop.c:469
> 
> > GNU C (WinAVR 20090313) version 4.3.2 (avr) compiled by GNU C
> > version 3.4.5 (mingw-vista special r3), GMP version 4.2.3,
> > MPFR version 2.4.0.
> 
> 
> The second example shows that global register variables are pretty much useless 
> in gcc 4.x. I am using global registers in gcc 3.4.6 and it work smooth. Without 
> global regs I would have to pay considerable performance penalties, so I am 
> still using avr-gcc 3.4.6 (which produces code that is both faster and smaller 
> than code from any avr-gcc 4.x I tested so far: from 4.1 up to 4.5). Here it is:
> 
> // bug.c ///////////////////////////////////////////////
> // avr-gcc bug.c -Os -S -ffixed-2 -ffixed-3
> 
> register unsigned int currData asm ("r2");
> 
> // from 
> typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
> 
> // from 
> #define PINB (*(volatile uint8_t *)(0x16 + 0x20))
> #define PORTB (*(volatile uint8_t *)(0x18 + 0x20))
> 
> // from 
> void __vector_1 (void) __attribute__ ((signal,used,externally_visible));
> void __vector_1 (void)
> {
>     // Nothing special, just an ISR that depends on currData
>     if (currData & 0x4000)
>         PORTB |= 2;
>     else
>         PORTB &= ~2;
> 
>     currData = currData << 1;
> }
> 
> void foo (void)
> {
>     for (;;)
>     {
>         while (PINB & 1);
>         currData = 0x2123;
>         while (!(PINB & 1));
>     }
> }
> //////////////////////////////////////////////////////
> 
> CSE decides that currData in foo is dead. As everyone can see, the produced 
> assembler does not touch the global register R3:R2. Making global reg vars 
> volatile is iseless (gcc goesn' even warn about that and gcc doesn't even have a 
> flag to tag a global reg volatile).
> 
> There are just (conditional) branches left that jump around and poll SFRs:
> 
> foo:
> /* prologue: function */
> /* frame size = 0 */
> .L13:
>     sbic 54-32,0     ;  12    *sbix_branch    [length = 2]
>     rjmp .L13
> .L10:
>     sbis 54-32,0     ;  22    *sbix_branch    [length = 2]
>     rjmp .L10
>     rjmp .L13     ;  50    jump    [length = 1]
>     .size    foo, .-foo
> 
> Global register variables can boost performance in embedded applications. It's a 
> pitty that this is pretty much useless in "modern" gcc 4.x.

Oh, this is bad news :/
Is the problem only with global register allocations, or even with local ones?
Wouldn't the approach of having register subclasses and handling them with ad-hoc contraints
(like the road I took before) be a more universally working solution?


- Jamie


      


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