This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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
> >>>>
> >>>>
> >>>>
> >>>>
> >>
>
>