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:harihar...@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:harihar...@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-ow...@gcc.gnu.org [mailto:gcc-ow...@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 > >>>> > >>>> > >>>> > >>>> > >> > >