On Wed, 2008-10-15 at 10:08 -0700, Evan Cheng wrote:> On Oct 15, 2008, at 5:29 AM, sanjiv gupta wrote: > > > On Tue, 2008-10-14 at 10:19 -0700, Evan Cheng wrote: > >> You need to specify sub-register == super-register, idx relationship. > >> See X86RegisterInfo.td: > >> > >> def x86_subreg_8bit : PatLeaf<(i32 1)>; > >> def x86_subreg_16bit : PatLeaf<(i32 2)>; > >> def x86_subreg_32bit : PatLeaf<(i32 3)>; > >> > >> def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, > >> R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], > >> [AL, CL, DL, BL, SPL, BPL, SIL, DIL, > >> R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; > >> > >> I admit the way it's specified is not very elegant. We'll clean it up > >> some day. > >> > >> Evan > >> > > Even in that case you can not have a 0 as a SubIdx. > > e.g. the code below won't work > > > > def x86_subreg_8bit : PatLeaf<(i32 0)>; > > > > > > def : SubRegSet<0, [AX, CX, DX, BX, SP, BP, SI, DI, > > R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], > > [AL, CL, DL, BL, SPL, BPL, SIL, DIL, > > R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; > > > > > > class GR16_ ..... { > > let SubRegClassList = [GR8]; > > } > > Right. Subreg index starts from 1. This ought to be fixed but it's not > (yet). > > > > > > > The getSubRegisterRegClass uses SubIdx - 1; > > > > so INSERT_SUBREG (IMPLICIT_DEF, AL, 0) will not work, because > > getSubRegisterRegClass will fail.(GR16_ does not have a SubRegClass > > at index -1.) > > > > OTOH, if you use SubIdx as 1, both in SubRegSet and x86_subreg_8bit, > > the INSERT_SUBREG (IMPLICIT_DEF, AL, 1) will work. > > Ok. > > > > > > > But then INSERT_SUBREG (AX, AH, 2) will not work because > > getSubRegisterRegClass will fail again. (GR16_ does not have a > > SubRegClass at index 1.) > > Ok. The AX / AH super-reg and sub-reg relationship is not defined. In > general x86 is not making good use of the high 8-bit sub-registers. We > are leaving some performance on the table. We'll probably fix it one > day. However, this doesn't apply to your target, right? There is > nothing preventing you from specifying the sub-registers and making > use of insert_subreg, no? > > Evan >it is, though we have a workaround. We have 16-bit registers class and want to set both the lo and high parts using INSERT_SUBREG. The workaround is to declare the same SubRegClass twice while declaring the SuperRegisterClass. i.e. def FSR16: RegisterClass <"PIC16", [i16], 8, [FSR0, FSR1]> { let SubRegClassList = [FSR8, FSR8]; // HERE. } SubRegSet : <1, [FSR0, FSR1], [FSR0L, FSR0H]>; SubRegSet : <2, [FSR0, FSR1], [FSR0H, FSR0L]>; I think the fundamental problem we have there is that we are using SubIdx for both purposes: 1. to enumerate over subregister classses, 2. To enumerate subregs of the same type of a super reg. - Sanjiv.> > > > > > > > Hope I made it clear. Please write back if they aren't. > > > > > > - Sanjiv > > > > > > > > > > > > > > > >> On Oct 13, 2008, at 11:24 AM, sanjiv gupta wrote: > >> > >>> On Thu, 2008-10-02 at 11:19 -0700, Evan Cheng wrote: > >>>> > >>>> On Oct 2, 2008, at 11:02 AM, Sanjiv.Gupta at microchip.com wrote: > >>>> > >>>>> What’s the value produced by an INSERT_SUBREG node? Is it a chain? > >>>> > >>>> > >>>> No, insert_subreg returns a value: > >>>> > >>>> > >>>> v1 = insert_subreg v2, v3, idx > >>>> > >>>> > >>>> v1 and v2 will have the same type, e.g. i16, and v3 must have a > >>>> sub-register type, e.g. i8. > >>>> > >>>>> > >>>>> Can I use to set a superreg of i16 type with two i8 values, and > >>>>> use > >>>>> the supperreg as an operand somewhere else? > >>>> > >>>> > >>>> Suppose you want to use a pair of i8 v1, v2 to create a i16 v3. The > >>>> way to do it is: > >>>> > >>>> > >>>> v4 = insert_subreg implicit_def, v1, 0 > >>>> v3 = insert_subreg v4, v2, 1 > >>>> > >>>> > >>>> Evan > >>>> > >>> > >>> This is how my register classes look like: > >>> > >>> def FSR0L : Register<"FSR0L">; > >>> def FSR0H : Register<"FSR0H">; > >>> def FSR1L : Register<"FSR1L">; > >>> def FSR1H : Register<"FSR1H">; > >>> > >>> def FSR0 : RegisterWithSubRegs<"FSR0", [FSR0H, FSR0L]>; > >>> def FSR1 : RegisterWithSubRegs<"FSR1", [FSR1H, FSR1L]>; > >>> > >>> def FSR8RC : RegisterClass<"PIC16", [i8], 8, [FSR0L, FSR0H, FSR0L, > >>> FSR1H]>; > >>> > >>> def FSR16RC : RegisterClass<"PIC16", [i16], 8, [FSR0, FSR1]> { > >>> let SubRegClassList = [FSR8RC]; > >>> } > >>> > >>> in my case I want to insert two values, which are available in > >>> register > >>> types of FSR8RC, into a register type of FSR16RC. > >>> > >>> when I use and INSERT_SUBREG with an SubIdx = 0, as you mentioned in > >>> > >>>> v4= insert_subreg implicit_def, v1, 0 > >>> > >>> the following function returns an incorrect subregclass: > >>> > >>> static const TargetRegisterClass* > >>> getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned > >>> SubIdx) > >>> { > >>> // Pick the register class of the subregister > >>> TargetRegisterInfo::regclass_iterator I > >>> TRC->subregclasses_begin() + SubIdx-1; > >>> assert(I < TRC->subregclasses_end() && > >>> "Invalid subregister index for register class"); > >>> return *I; > >>> } > >>> > >>> what does -1 do while initializing I in the above fn? > >>> > >>> TIA, > >>> Sanjiv > >>> > >>> > >>> > >>> _______________________________________________ > >>> LLVM Developers mailing list > >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >> > >> > >> _______________________________________________ > >> LLVM Developers mailing list > >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > > > _______________________________________________ > > LLVM Developers mailing list > > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On Oct 15, 2008, at 11:21 AM, sanjiv gupta wrote:>>> >> >> Ok. The AX / AH super-reg and sub-reg relationship is not defined. In >> general x86 is not making good use of the high 8-bit sub-registers. >> We >> are leaving some performance on the table. We'll probably fix it one >> day. However, this doesn't apply to your target, right? There is >> nothing preventing you from specifying the sub-registers and making >> use of insert_subreg, no? >> >> Evan >> > it is, though we have a workaround. > > We have 16-bit registers class and want to set both the lo and high > parts using INSERT_SUBREG. > > The workaround is to declare the same SubRegClass twice while > declaring > the SuperRegisterClass. i.e. > > def FSR16: RegisterClass <"PIC16", [i16], 8, [FSR0, FSR1]> { > let SubRegClassList = [FSR8, FSR8]; // HERE. > }This is a bug, probably in tablegen. Unfortunately I don't have the time to fix it. But please file a bug about this. Hopefully someone will fix it soon. Thanks, Evan> > > SubRegSet : <1, [FSR0, FSR1], [FSR0L, FSR0H]>; > SubRegSet : <2, [FSR0, FSR1], [FSR0H, FSR0L]>; > > > I think the fundamental problem we have there is that we are using > SubIdx for both purposes: 1. to enumerate over subregister > classses, 2. > To enumerate subregs of the same type of a super reg. > > > - Sanjiv. > >>> >>> >>> >>> Hope I made it clear. Please write back if they aren't. >>> >>> >>> - Sanjiv >>> >>> >>> >>> >>> >>> >>> >>>> On Oct 13, 2008, at 11:24 AM, sanjiv gupta wrote: >>>> >>>>> On Thu, 2008-10-02 at 11:19 -0700, Evan Cheng wrote: >>>>>> >>>>>> On Oct 2, 2008, at 11:02 AM, Sanjiv.Gupta at microchip.com wrote: >>>>>> >>>>>>> What’s the value produced by an INSERT_SUBREG node? Is it a >>>>>>> chain? >>>>>> >>>>>> >>>>>> No, insert_subreg returns a value: >>>>>> >>>>>> >>>>>> v1 = insert_subreg v2, v3, idx >>>>>> >>>>>> >>>>>> v1 and v2 will have the same type, e.g. i16, and v3 must have a >>>>>> sub-register type, e.g. i8. >>>>>> >>>>>>> >>>>>>> Can I use to set a superreg of i16 type with two i8 values, and >>>>>>> use >>>>>>> the supperreg as an operand somewhere else? >>>>>> >>>>>> >>>>>> Suppose you want to use a pair of i8 v1, v2 to create a i16 v3. >>>>>> The >>>>>> way to do it is: >>>>>> >>>>>> >>>>>> v4 = insert_subreg implicit_def, v1, 0 >>>>>> v3 = insert_subreg v4, v2, 1 >>>>>> >>>>>> >>>>>> Evan >>>>>> >>>>> >>>>> This is how my register classes look like: >>>>> >>>>> def FSR0L : Register<"FSR0L">; >>>>> def FSR0H : Register<"FSR0H">; >>>>> def FSR1L : Register<"FSR1L">; >>>>> def FSR1H : Register<"FSR1H">; >>>>> >>>>> def FSR0 : RegisterWithSubRegs<"FSR0", [FSR0H, FSR0L]>; >>>>> def FSR1 : RegisterWithSubRegs<"FSR1", [FSR1H, FSR1L]>; >>>>> >>>>> def FSR8RC : RegisterClass<"PIC16", [i8], 8, [FSR0L, FSR0H, >>>>> FSR0L, >>>>> FSR1H]>; >>>>> >>>>> def FSR16RC : RegisterClass<"PIC16", [i16], 8, [FSR0, FSR1]> { >>>>> let SubRegClassList = [FSR8RC]; >>>>> } >>>>> >>>>> in my case I want to insert two values, which are available in >>>>> register >>>>> types of FSR8RC, into a register type of FSR16RC. >>>>> >>>>> when I use and INSERT_SUBREG with an SubIdx = 0, as you >>>>> mentioned in >>>>> >>>>>> v4= insert_subreg implicit_def, v1, 0 >>>>> >>>>> the following function returns an incorrect subregclass: >>>>> >>>>> static const TargetRegisterClass* >>>>> getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned >>>>> SubIdx) >>>>> { >>>>> // Pick the register class of the subregister >>>>> TargetRegisterInfo::regclass_iterator I >>>>> TRC->subregclasses_begin() + SubIdx-1; >>>>> assert(I < TRC->subregclasses_end() && >>>>> "Invalid subregister index for register class"); >>>>> return *I; >>>>> } >>>>> >>>>> what does -1 do while initializing I in the above fn? >>>>> >>>>> TIA, >>>>> Sanjiv >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On Thu, 2008-10-16 at 08:55 -0700, Evan Cheng wrote:> On Oct 15, 2008, at 11:21 AM, sanjiv gupta wrote: > > >>> > >> > >> Ok. The AX / AH super-reg and sub-reg relationship is not defined. In > >> general x86 is not making good use of the high 8-bit sub-registers. > >> We > >> are leaving some performance on the table. We'll probably fix it one > >> day. However, this doesn't apply to your target, right? There is > >> nothing preventing you from specifying the sub-registers and making > >> use of insert_subreg, no? > >> > >> Evan > >> > > it is, though we have a workaround. > > > > We have 16-bit registers class and want to set both the lo and high > > parts using INSERT_SUBREG. > > > > The workaround is to declare the same SubRegClass twice while > > declaring > > the SuperRegisterClass. i.e. > > > > def FSR16: RegisterClass <"PIC16", [i16], 8, [FSR0, FSR1]> { > > let SubRegClassList = [FSR8, FSR8]; // HERE. > > } > > This is a bug, probably in tablegen. Unfortunately I don't have the > time to fix it. But please file a bug about this. Hopefully someone > will fix it soon. > > Thanks, > > Evan >PR2916 filed. Though I did not quite understand why this could be a tablegen bug? - Sanjiv
Hi Sanjiv, What you have below is the currently expected way of declaring sub registers, I agree that it's somewhat inelegant as well as poorly documented. 1) Yes, sub register sets start with enumeration number 1. I believe this has to do with the layout of some static data structures that reserve entry 0... 2) The "duplicate" class entries in SubRegClassList is not really a duplicate, but specifies for each SubRegSet the register class that is expected for the sub registers in that set. This is needed for registers that have sub registers of many different types. So for your architecture: let SubRegClassList = [ FSR8, // Type of SubRegSet 1 FSR8 // Type of SubRegSet 2 ]; Imagine you have a FSR32 register class, that contains both 16-bit and 8-bit sub registers, you may end up with a class list like: let SubRegClassList = [ FSR8, // Type of SubRegSet 1 FSR8, // Type of SubRegSet 2 FSR16, // Type of SubRegSet 3 FSR16 // Type of SubRegSet 4 ]; I think that there are definitely more clear ways of attaching SubRegSet's to the class of registers they belong to, as well as specifying the sub register type in the set. Perhaps syntax along the lines of this: def FSR16: RegisterClass <"PIC16", [i16], 8, [FSR0, FSR1]> { let SubRegClassList = [ <0, FSR8, [FSR0L, FSR0H]>, <1, FSR8, [FSR0H, FSR0L]> ]; } Unfortunately I have little time for TableGen hacking at the moment. =) On Oct 15, 2008, at 11:21 AM, sanjiv gupta wrote:> We have 16-bit registers class and want to set both the lo and high > parts using INSERT_SUBREG. > > The workaround is to declare the same SubRegClass twice while > declaring > the SuperRegisterClass. i.e. > > def FSR16: RegisterClass <"PIC16", [i16], 8, [FSR0, FSR1]> { > let SubRegClassList = [FSR8, FSR8]; // HERE. > } > > SubRegSet : <1, [FSR0, FSR1], [FSR0L, FSR0H]>; > SubRegSet : <2, [FSR0, FSR1], [FSR0H, FSR0L]>;-- Christopher Lamb