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]; } Refer to below functions in ScheduleDAGEmit.cpp: ----------------------------------------------- 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; } /// getSuperRegisterRegClass - Returns the register class of a superreg A whose /// "SubIdx"'th sub-register class is the specified register class and whose /// type matches the specified type. static const TargetRegisterClass* getSuperRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx, MVT VT) { // Pick the register class of the superegister for this type for (TargetRegisterInfo::regclass_iterator I TRC->superregclasses_begin(), E = TRC->superregclasses_end(); I != E; ++I) if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC) return *I; assert(false && "Couldn't find the register class"); return 0; } ----------------------------------------------------------------- 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. But then INSERT_SUBREG (AX, AH, 2) will not work because getSubRegisterRegClass will fail again. (GR16_ does not have a SubRegClass at index 1.) 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
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> > > > 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
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