public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Bitfields problem
@ 2009-12-11 16:57 Jean Christophe Beyler
  2009-12-11 20:10 ` Jean Christophe Beyler
  0 siblings, 1 reply; 2+ messages in thread
From: Jean Christophe Beyler @ 2009-12-11 16:57 UTC (permalink / raw)
  To: gcc

As I continue my work on the machine description file, I currently
worked on the bitfields again to try to get a good code generation
working. Right now, I've followed what was done in the ia64 for signed
extractions :

(define_insn "extv"
  [(set (match_operand:DI 0 "gr_register_operand" "=r")
    (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
             (match_operand:DI 2 "extr_len_operand" "n")
             (match_operand:DI 3 "shift_count_operand" "M")))]
  ""
  "extr %0 = %1, %3, %2"
  [(set_attr "itanium_class" "ishf")])


now this works for me except that I get for this code:

typedef struct sTest {
    int64_t a:1;
    int64_t b:5;
    int64_t c:7;
    int64_t d:15;
}STest;

int64_t bar2 (STest a)
{
    int64_t res = a.d;
    return res;
}

Here is what I get at the final cleanup:

;; Function bar2 (bar2)

bar2 (a)
{
  short unsigned int SR.44;
  short unsigned int SR.43;
  short unsigned int SR.41;
  short unsigned int SR.40;
  short unsigned int SR.22;
  short unsigned int SR.3;

<bb 2>:
  SR.22 = (short unsigned int) (<unnamed-signed:15>) ((short unsigned
int) a.d & 32767);
  SR.43 = SR.22 & 32767;
  SR.44 = SR.43 ^ 16384;
  SR.3 = (short unsigned int) (<unnamed-signed:15>) ((short unsigned
int) (<unnamed-signed:15>) (SR.44 + 49152) & 32767);
  SR.40 = SR.3 & 32767;
  SR.41 = SR.40 ^ 16384;
  return (int64_t) (<unnamed-signed:15>) (SR.41 + 49152);

}

I don't understand why I get all these instructions. I know that
because it's signed, it is more complicated but I would prefer to get
an unsigned extract and the a shift left/shift right. Thus 3
instructions.

Right now, I get so many more instructions that represent what I
showed from the final cleanup.

Any reason for all these instructions or ideas on how to get to my 3
instructions ?

Thank you for your help and time,
Jean Christophe Beyler

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Bitfields problem
  2009-12-11 16:57 Bitfields problem Jean Christophe Beyler
@ 2009-12-11 20:10 ` Jean Christophe Beyler
  0 siblings, 0 replies; 2+ messages in thread
From: Jean Christophe Beyler @ 2009-12-11 20:10 UTC (permalink / raw)
  To: gcc

Interestingly enough, if I do this instead:

typedef struct sTest {
    int a:12;
    int b:20;
    int c:7;
    int d:15;
}STest;


int64_t bar2 (STest *a)
{
    int64_t res = a->b;
    return res;
}

I get at the expand pass :

(insn 6 5 7 3 struct3.c:27 (set (reg:SI 75)
        (mem/s:SI (reg/v/f:DI 73 [ a ]) [0 S4 A32])) -1 (nil))     ->
Actually get the data

(insn 7 6 8 3 struct3.c:27 (set (reg:DI 77)
        (zero_extract:DI (subreg:DI (reg:SI 75) 0)
            (const_int 20 [0x14])
            (const_int 12 [0xc]))) -1 (nil))           -> Extract the
bits we want but this is zero_extracted

(insn 8 7 9 3 struct3.c:27 (set (reg:DI 78)
        (ashift:DI (reg:DI 77)
            (const_int 43 [0x2b]))) -1 (nil))

(insn 9 8 10 3 struct3.c:27 (set (subreg:DI (reg:SI 76) 0)
        (ashiftrt:DI (reg:DI 78)
            (const_int 43 [0x2b]))) -1 (nil))   -> These two
instructions actually sign extend it

(insn 10 9 11 3 struct3.c:27 (set (reg:DI 79)
        (ashift:DI (reg:SI 76)
            (const_int 32 [0x20]))) -1 (nil))

(insn 11 10 12 3 struct3.c:27 (set (reg:DI 74)
        (ashiftrt:DI (reg:DI 79)
            (const_int 32 [0x20]))) -1 (expr_list:REG_EQUAL
(sign_extend:DI (reg:SI 76))
        (nil)))   -> Because it's seen as a SI, these last two sign
extend it again...


And I get later on in the passes (the instructions are removed by the
combine pass):

(insn 6 3 7 2 struct3.c:27 (set (reg:SI 75)
        (mem/s:SI (reg:DI 8 r8 [ a ]) [0 S4 A32])) 74
{movsi_internal2} (expr_list:REG_DEAD (reg:DI 8 r8 [ a ])
        (nil)))

(note 7 6 8 2 NOTE_INSN_DELETED)

(note 8 7 9 2 NOTE_INSN_DELETED)

(note 9 8 10 2 NOTE_INSN_DELETED)

(note 10 9 11 2 NOTE_INSN_DELETED)

(note 11 10 16 2 NOTE_INSN_DELETED)

(insn 16 11 22 2 struct3.c:30 (set (reg/i:DI 6 r6)
        (zero_extract:DI (subreg:DI (reg:SI 75) 0)
            (const_int 20 [0x14])
            (const_int 12 [0xc]))) 63 {extzvdi} (expr_list:REG_DEAD (reg:SI 75)
        (nil)))

So now I have two issues that I can't seem to figure out :

- Why can combine remove these 4 instructions ?

- Why do I have such a difference between a local variable that is not
a pointer, a pointer and a global variable ?

I remember having a different behavior if the variable was a global
variable or if it was a parameter. It seems that this is the case also
for here. However, this is worse, since it transforms my signed
extract into a simple zero_extract.

Thanks for your help,
Jc

PS: here is the combine pass debug information:

;; Function bar2 (bar2)

starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
insn_cost 2: 4
insn_cost 6: 4
insn_cost 7: 36
insn_cost 8: 4
insn_cost 9: 4
insn_cost 10: 4
insn_cost 11: 4
insn_cost 16: 4
insn_cost 22: 0
deferring deletion of insn with uid = 2.
modifying insn i3     6 r75:SI=[r8:DI]
      REG_DEAD: r8:DI
deferring rescan insn with uid = 6.
deferring deletion of insn with uid = 8.
modifying insn i3     9 r76:SI#0=r77:DI
      REG_DEAD: r77:DI
deferring rescan insn with uid = 9.
deferring deletion of insn with uid = 7.
modifying insn i3     9 r76:SI#0=zero_extract(r75:SI#0,0x14,0xc)
      REG_DEAD: r75:SI
deferring rescan insn with uid = 9.
deferring deletion of insn with uid = 10.
modifying insn i3    11 r74:DI=r76:SI#0&0xfffff
      REG_DEAD: r76:SI
deferring rescan insn with uid = 11.
deferring deletion of insn with uid = 9.
modifying insn i3    11 r74:DI=zero_extract(r75:SI#0,0x14,0xc)
      REG_DEAD: r75:SI
deferring rescan insn with uid = 11.
deferring deletion of insn with uid = 11.
modifying insn i3    16 r6:DI=zero_extract(r75:SI#0,0x14,0xc)
      REG_DEAD: r75:SI
deferring rescan insn with uid = 16.
(note 1 0 4 NOTE_INSN_DELETED)

(note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(note 2 4 3 2 NOTE_INSN_DELETED)

(note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)

(insn 6 3 7 2 struct3.c:27 (set (reg:SI 75)
        (mem/s:SI (reg:DI 8 r8 [ a ]) [0 S4 A32])) 74
{movsi_internal2} (expr_list:REG_DEAD (reg:DI 8 r8 [ a ])
        (nil)))

(note 7 6 8 2 NOTE_INSN_DELETED)

(note 8 7 9 2 NOTE_INSN_DELETED)

(note 9 8 10 2 NOTE_INSN_DELETED)

(note 10 9 11 2 NOTE_INSN_DELETED)

(note 11 10 16 2 NOTE_INSN_DELETED)

(insn 16 11 22 2 struct3.c:30 (set (reg/i:DI 6 r6)
        (zero_extract:DI (subreg:DI (reg:SI 75) 0)
            (const_int 20 [0x14])
            (const_int 12 [0xc]))) 63 {extzvdi} (expr_list:REG_DEAD (reg:SI 75)
        (nil)))

(insn 22 16 0 2 struct3.c:30 (use (reg/i:DI 6 r6)) -1 (nil))
starting the processing of deferred insns
deleting insn with uid = 2.
deleting insn with uid = 7.
deleting insn with uid = 8.
deleting insn with uid = 9.
deleting insn with uid = 10.
deleting insn with uid = 11.
rescanning insn with uid = 6.
deleting insn with uid = 6.
rescanning insn with uid = 16.
deleting insn with uid = 16.
ending the processing of deferred insns

;; Combiner totals: 16 attempts, 16 substitutions (2 requiring new space),
;; 6 successes.


On Fri, Dec 11, 2009 at 11:57 AM, Jean Christophe Beyler
<jean.christophe.beyler@gmail.com> wrote:
> As I continue my work on the machine description file, I currently
> worked on the bitfields again to try to get a good code generation
> working. Right now, I've followed what was done in the ia64 for signed
> extractions :
>
> (define_insn "extv"
>  [(set (match_operand:DI 0 "gr_register_operand" "=r")
>    (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
>             (match_operand:DI 2 "extr_len_operand" "n")
>             (match_operand:DI 3 "shift_count_operand" "M")))]
>  ""
>  "extr %0 = %1, %3, %2"
>  [(set_attr "itanium_class" "ishf")])
>
>
> now this works for me except that I get for this code:
>
> typedef struct sTest {
>    int64_t a:1;
>    int64_t b:5;
>    int64_t c:7;
>    int64_t d:15;
> }STest;
>
> int64_t bar2 (STest a)
> {
>    int64_t res = a.d;
>    return res;
> }
>
> Here is what I get at the final cleanup:
>
> ;; Function bar2 (bar2)
>
> bar2 (a)
> {
>  short unsigned int SR.44;
>  short unsigned int SR.43;
>  short unsigned int SR.41;
>  short unsigned int SR.40;
>  short unsigned int SR.22;
>  short unsigned int SR.3;
>
> <bb 2>:
>  SR.22 = (short unsigned int) (<unnamed-signed:15>) ((short unsigned
> int) a.d & 32767);
>  SR.43 = SR.22 & 32767;
>  SR.44 = SR.43 ^ 16384;
>  SR.3 = (short unsigned int) (<unnamed-signed:15>) ((short unsigned
> int) (<unnamed-signed:15>) (SR.44 + 49152) & 32767);
>  SR.40 = SR.3 & 32767;
>  SR.41 = SR.40 ^ 16384;
>  return (int64_t) (<unnamed-signed:15>) (SR.41 + 49152);
>
> }
>
> I don't understand why I get all these instructions. I know that
> because it's signed, it is more complicated but I would prefer to get
> an unsigned extract and the a shift left/shift right. Thus 3
> instructions.
>
> Right now, I get so many more instructions that represent what I
> showed from the final cleanup.
>
> Any reason for all these instructions or ideas on how to get to my 3
> instructions ?
>
> Thank you for your help and time,
> Jean Christophe Beyler
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-12-11 20:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-11 16:57 Bitfields problem Jean Christophe Beyler
2009-12-11 20:10 ` Jean Christophe Beyler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).