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


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]