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


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]