* 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).