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: Machine description question


Yes, we use this instead of unspec_volatile out of performance concern.
Our target is a VLIW processor, so there is more opportunities to move
instructions around. Did you observe any instruction that should be
moved but not? 

Cheers,
Bingfeng

> -----Original Message-----
> From: Hariharan Sandanagobalane [mailto:hariharans@picochip.com] 
> Sent: 14 May 2010 12:26
> To: Bingfeng Mei
> Cc: gcc@gcc.gnu.org
> Subject: Re: Machine description question
> 
> Hi Bengfeng,
> Changing my instruction patterns similar to the ones that you 
> sent does 
> get over the correctness issue. Setting the imaginary register 
> explicitly this way and adding those extra unspec patterns 
> does seem to 
> work. But, performance-wise, it still doesn't give me 
> anything. Did you 
> decide to use these patterns (instead of the simpler unspec_volatile 
> ones) for performance reasons? Does using these patterns give 
> you anything?
> 
> Cheers
> Hari
> 
> Bingfeng Mei wrote:
> > Hari,
> >
> > Here are some patterns similar to yours. 
> >
> > (define_insn "putbx"
> >   [(set (reg:BXBC R_BX) (unspec:BXBC [(match_operand:QI 0 
> "firepath_register" "vr")] UNSPEC_BXM)) 
> >    (unspec:BXBC [(reg:BXBC R_BX)] UNSPEC_BX)]   <---  
> Important to avoid some wrong optimization (Maybe DCE, I 
> couldn't remember clearly)
> >
> >
> > define_insn "getbx"
> >   [(set (reg:BXBC R_BX) (unspec:BXBC [(reg:BXBC R_BX)] 
> UNSPEC_BX))  <---- Artifical dependency
> >    (set (match_operand:SI 0 "register_operand" "=r")
> >         (unspec:SI [(reg:BXBC R_BX)]UNSPEC_BXM))
> >    (unspec:BXBC [(reg:BXBC R_BX)] UNSPEC_BX)]  <---- 
> Important to avoid some optimization. 
> >
> > Our port is still porivate and not in mainline. 
> >
> > Cheers,
> > Bingfeng
> >
> >   
> >> -----Original Message-----
> >> From: Hariharan Sandanagobalane [mailto:hariharans@picochip.com] 
> >> Sent: 13 May 2010 10:17
> >> To: Bingfeng Mei
> >> Cc: gcc@gcc.gnu.org
> >> Subject: Re: Machine description question
> >>
> >> The patterns for PUT/GET were
> >>
> >> ; Scalar Put instruction.
> >> (define_insn "commsPut"
> >>   [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "")
> >>                      (match_operand:SI 1 "register_operand" "r")]
> >>                     UNSPEC_PUT)]
> >>   ""
> >>   "PUT %R1,%0\t// PORT(%0) := %R1"
> >>   [(set_attr "type" "comms")
> >>    (set_attr "length" "2")])
> >>
> >>
> >> (define_insn "commsGet"
> >>   [(set (match_operand:SI             0 "register_operand" "=r")
> >>         (unspec_volatile:SI
> >>          [(match_operand:HI 1 "immediate_operand" "n")]
> >>          UNSPEC_GET))]
> >>   ""
> >>   "GET %1,%R0\t// %R0 := PORT(%1)"
> >>   [(set_attr "type" "comms")
> >>    (set_attr "length" "2")])
> >>
> >>
> >> I changed them to
> >>
> >> ; Scalar Put instruction.
> >> (define_insn "commsPut"
> >>   [(unspec [(match_operand:HI 0 "const_int_operand" "")
> >>                      (match_operand:SI 1 "register_operand" "r")]
> >>                     UNSPEC_PUT)
> >>     (use (reg:HI DUMMY_COMMN_REGNUM))
> >>     (clobber (reg:HI DUMMY_COMMN_REGNUM))]
> >>   ""
> >>   "PUT %R1,%0\t// PORT(%0) := %R1"
> >>   [(set_attr "type" "comms")
> >>    (set_attr "length" "2")])
> >>
> >> ; Simple scalar get.
> >> (define_insn "commsGet"
> >>   [(set (match_operand:SI             0 "register_operand" "=r")
> >>         (unspec:SI
> >>          [(match_operand:HI 1 "immediate_operand" "n")]
> >>          UNSPEC_GET))
> >>     (use (reg:HI DUMMY_COMMN_REGNUM))
> >>     (clobber (reg:HI DUMMY_COMMN_REGNUM))]
> >>   ""
> >>   "GET %1,%R0\t// %R0 := PORT(%1)"
> >>   [(set_attr "type" "comms")
> >>    (set_attr "length" "2")])
> >>
> >>
> >> As for the DUMMY_COMMN_REGNUM, I just defined this as a 
> >> FIXED_REGISTER 
> >> and bumped up FIRST_PSUEDO_REG.
> >>
> >> Actually, there is one more problem i faced (other than 
> performance). 
> >> The code generated using unspec's was just plain wrong. The unspec 
> >> pattern that i was using for GET, which was inside a loop, 
> was being 
> >> hoisted out of the loop by the loop optimizer. I guess i 
> should have 
> >> seen this coming, since unspec is just "machine-specific" 
> >> operation and 
> >> the optimizer probably rightly assumes that multiple 
> >> execution of this 
> >> with same parameters would result in same value being 
> produced. This 
> >> obviously is not the case for these communication instructions.
> >>
> >> Do you have your code to do this using unspec in gcc 
> >> mainline? Can you 
> >> point me to that, please?
> >>
> >> Thanks
> >> Hari
> >>
> >> Bingfeng Mei wrote:
> >>     
> >>> How do you define your imaginary register in target.h? 
> Can you post
> >>> one example of your instruction pattern? 
> >>>
> >>> Bingfeng
> >>>
> >>>   
> >>>       
> >>>> -----Original Message-----
> >>>> From: Hariharan Sandanagobalane [mailto:hariharans@picochip.com] 
> >>>> Sent: 12 May 2010 16:40
> >>>> To: Bingfeng Mei
> >>>> Cc: gcc@gcc.gnu.org
> >>>> Subject: Re: Machine description question
> >>>>
> >>>> Thanks for your help BingFeng.
> >>>>
> >>>> I gave this a go and ended up with worse code (and worse 
> >>>> memory usage) 
> >>>> than before. I started with this experiment because of the 
> >>>>         
> >> compilers 
> >>     
> >>>> "All virtual registers are assumed to be used and clobbered by 
> >>>> unspec_volatile" rule. The get/put instructions read/write to 
> >>>> registers 
> >>>> and the virtual register assigned for them interferes 
> with all the 
> >>>> virtual registers in the function. So, they were highly 
> >>>>         
> >> likely to be 
> >>     
> >>>> spilled and use stack instead. I wanted to try to avoid 
> >>>>         
> >> this by the 
> >>     
> >>>> introduction of unspec's and use of imaginary registers.
> >>>>
> >>>> But, the virtual registers that are involved in unspec 
> >>>>         
> >> patterns with 
> >>     
> >>>> these imaginary registers still seem to be marked to 
> >>>> interfere with all 
> >>>> the virtual registers. Is that to be expected? Am i 
> >>>>         
> >> missing something 
> >>     
> >>>> obvious here?
> >>>>
> >>>> Regards
> >>>> Hari
> >>>>
> >>>> Bingfeng Mei wrote:
> >>>>     
> >>>>         
> >>>>> Our architecture has the similar resource, and we use the 
> >>>>>       
> >>>>>           
> >>>> first approach
> >>>>     
> >>>>         
> >>>>> by creating an imaginary register and dependency between 
> >>>>>       
> >>>>>           
> >>>> these instructions,
> >>>>     
> >>>>         
> >>>>> i.e., every such instruction reads and write to the special 
> >>>>>       
> >>>>>           
> >>>> register to
> >>>>     
> >>>>         
> >>>>> create artificial dependency. You may need to add a 
> >>>>>       
> >>>>>           
> >>>> (unspec:..) as an 
> >>>>     
> >>>>         
> >>>>> independent expression in your pattern to prevent some 
> >>>>>       
> >>>>>           
> >>>> wrong optimizations. 
> >>>>     
> >>>>         
> >>>>> Cheers,
> >>>>> Bingfeng
> >>>>>
> >>>>>   
> >>>>>       
> >>>>>           
> >>>>>> -----Original Message-----
> >>>>>> From: gcc-owner@gcc.gnu.org [mailto:gcc-owner@gcc.gnu.org] On 
> >>>>>> Behalf Of Hariharan
> >>>>>> Sent: 12 May 2010 11:18
> >>>>>> To: gcc@gcc.gnu.org
> >>>>>> Subject: Machine description question
> >>>>>>
> >>>>>> Hello all,
> >>>>>> Picochip has communication instructions that allow one array 
> >>>>>> element to 
> >>>>>> pass data to another. There are 3 such instructions 
> >>>>>>         
> >>>>>>             
> >>>> PUT/GET/TSTPORT. 
> >>>>     
> >>>>         
> >>>>>> Currently, all three of these use UNSPEC_VOLATILE side-effect 
> >>>>>> expressions to make sure they don't get reordered. But, i 
> >>>>>> wonder if it 
> >>>>>> is an overkill to use UNSPEC_VOLATILE for this purpose and 
> >>>>>>         
> >>>>>>             
> >>>> whether i 
> >>>>     
> >>>>         
> >>>>>> should use UNSPEC instead. The only thing we care here is 
> >>>>>>         
> >>>>>>             
> >>>> that they 
> >>>>     
> >>>>         
> >>>>>> don't reordered with respect to each other. It is okay 
> for other 
> >>>>>> instructions to move around the communication instructions 
> >>>>>> (as long as 
> >>>>>> normal scheduler dependencies are taken care of). There are 
> >>>>>> possibly one 
> >>>>>> of two things i can do.
> >>>>>>
> >>>>>> 1. Introduce an implicit dependency between all communication 
> >>>>>> instructions by adding a use/clobber of an imaginary register.
> >>>>>> 2. Introduce explicit dependency between them by using some 
> >>>>>> target hook 
> >>>>>> to add dependency links. I have not found any appropriate 
> >>>>>> target hook to 
> >>>>>> do this.
> >>>>>>
> >>>>>> Can you tell me which one i should try? Has anyone tried 
> >>>>>> doing anything 
> >>>>>> similar? Any pointers/suggestions on this will be greatly 
> >>>>>>         
> >>>>>>             
> >>>> appreciated.
> >>>>     
> >>>>         
> >>>>>> Thanks
> >>>>>> Hari
> >>>>>>
> >>>>>>
> >>>>>>     
> >>>>>>         
> >>>>>>             
> >>>>     
> >>>>         
> >>     
> 
> 


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