Jyotsna Verma
2012-Aug-01 20:53 UTC
[LLVMdev] TableGen related question for the Hexagon backend
Hi, I'm looking for some suggestions on a problem related to the Hexagon backend. Hexagon architecture allows instructions in various formats. For example, we have 3 variations of the add instruction as defined below: ADDrr : r1 = add(r2, r3) --> add 2 32-bit registers ADDrr_p : if(p0) r1 add(r2, r3) --> predicated version of ADDrr instruction, executed when p0 is true ADDrr_np : if(!p0) r1 = add(r2, r3) --> predicated version of ADDrr instruction, executed when p0 is false Currently, we rely on switch tables to transform between formats. However, we would like to have a different mechanism to represent these relationships instead of switch tables. I am thinking of modeling these relations in HexagonInstrInfo.td file and use TableGen to generate a table with the information. Idea is to have a new class, say Relations, with some members of type 'Instruction' each representing a specific relation between itself and 'ThisInstr'. For example: class Relations { Instruction ThisInstr; Instruction BaseForm; Instruction TruePred; Instruction FalsePred; } def Rel_ADDrr : Relations<ADDrr, ADDrr, ADDrr_p, ADDrr_np>; def Rel_ADDrr_p : Relations<ADDrr_p, ADDrr, , >; def Rel_ADDrr_np : Relations<ADDrr_np, ADDrr, , >; I wonder if TableGen can parse Relations defs and emit the information into tabular form. I expect to index the resulting table using the instruction opcode and find opcode of the new instruction of the desired format. Any suggestions will be much appreciated. Relationship table layout: HexagonInstrRelations[] = { . {HexagonISD::ADDrr, HexagonISD::ADDrr, HexagonISD:: ADDrr_p, HexagonISD::ADDrr_np}, {HexagonISD::ADDrr_p, HexagonISD::ADDrr, -1, -1}, {HexagonISD::ADDrr_np, HexagonISD::ADDrr, -1, -1}, . }; Each column represents a specific relationship, -1 means 'invalid/nonexistent relation'. Thanks, Jyotsna -----Original Message----- From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Tony Linthicum Sent: Monday, May 14, 2012 11:10 AM To: Jakob Stoklund Olesen Cc: llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [llvm] r156634 - in /llvm/trunk: lib/Target/Hexagon/ lib/Target/Hexagon/InstPrinter/ test/CodeGen/Hexagon/ Hi Jakob, On 5/11/2012 6:47 PM, Jakob Stoklund Olesen wrote:> > On May 11, 2012, at 4:32 PM, "Brendon Cahoon"<bcahoon at codeaurora.org>wrote:> >> Yea, a very ugly file to commit. This is a file that we would >> like/are planning to be generated using Tablegen. > > You will need to come up with a solution. This is just too gross. > > /jakob >As Brendon indicated, we intend to have this generated by tablegen but current internal resource constraints make implementing that now difficult. We are trying to get our backend up to date, and we viewed this as a reasonable interim solution. Our plan is to fix this properly in the late July time frame. If, however, it is unacceptable for this to remain until then we will shift things around and address the proper solution immediately. Thanks for your time and your input. Tony -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum. _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
Jakob Stoklund Olesen
2012-Aug-02 22:23 UTC
[LLVMdev] TableGen related question for the Hexagon backend
On Aug 1, 2012, at 1:53 PM, Jyotsna Verma <jverma at codeaurora.org> wrote:> > Currently, we rely on switch tables to transform between formats. However, > we would like to have a different mechanism to represent these relationships > instead of switch tables. I am thinking of modeling these relations in > HexagonInstrInfo.td file and use TableGen to generate a table with the > information.That would be a good idea. X86 could also use some help with opcode mapping tables.> Idea is to have a new class, say Relations, with some members > of type 'Instruction' each representing a specific relation between itself > and 'ThisInstr'. > > For example: > class Relations { > Instruction ThisInstr; > Instruction BaseForm; > Instruction TruePred; > Instruction FalsePred; > } > > def Rel_ADDrr : Relations<ADDrr, ADDrr, ADDrr_p, ADDrr_np>; > def Rel_ADDrr_p: Relations<ADDrr_p, ADDrr, , >; > def Rel_ADDrr_np : Relations<ADDrr_np,ADDrr, , >;The problem is, this isn't really any better than having a large switch statement. You just moved the table into the .td file. You should be taking advantage of the instruction multiclasses so you don't have to maintain a full table of opcodes. /jakob
Sebastian Pop
2012-Aug-03 06:24 UTC
[LLVMdev] TableGen related question for the Hexagon backend
On Thu, Aug 2, 2012 at 5:23 PM, Jakob Stoklund Olesen <stoklund at 2pi.dk> wrote:> The problem is, this isn't really any better than having a large switch statement. You just moved the table into the .td file. > > You should be taking advantage of the instruction multiclasses so you don't have to maintain a full table of opcodes.We wouldn't need to "maintain" this table of opcodes, as this table is extracted from a higher level representation of the instruction set. In particular, this table would not need to be modified at all for the existing supported processors, and any new version of processors will have its table automatically generated by us. Why wouldn't it be acceptable for the *.td files defining the instructions and the relations between them to be generated and not written by hand? In my opinion, generating parts of the td files is much less error prone and more convenient for us than having to write the insns definitions by hand (that would indeed need "maintenance".) Thanks, Sebastian -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum
Jyotsna Verma
2012-Aug-16 20:39 UTC
[LLVMdev] TableGen related question for the Hexagon backend
Hi Everyone, After some more thoughts to the Jacob's suggestion of using multiclasses for Opcode mapping, this is what I have come up with. Please take a look at the design below and let me know if you have any suggestions/questions. I have tried to keep the design target independent so that other targets could benefit from it. 1) The idea is to add 3 new classes into include/llvm/Target/Target.td which provide the basic infrastructure for relating instructions with each other. Class Relations {} // any target interested in mapping relations, need to define a // class of its own as a subclass of 'Relations'. class IFormat<bits<4> value> { // Used to define basic instruction formats, Ex: register-register, register-immediate bits<4> Value = value; } // class RelationMap is actually used to related instructions with each other. class RelationMap<IFormat pFormat, IFormat iFormat, list<string> ancestors [] > { IFormat ParentFormat = pFormat; IFormat InstrFormat = iFormat; list <string> Ancestors = ancestors; } 2) Include some basic setup in the InstrInfo.td file. Any target interested in mapping relation needs to define a class as a subclass of 'Relations'. This class is primarily used for the recordkeeping and has one string variable for each basic format required for relation modeling. All instructions that want to define relationship mapping, should inherit from this class in addition to RelationMap class. This is explained below using a prototype model for Hexagon. Example from Hexagon backend: class RelHexagon : Relations { string InstFormat0; //prev form string InstFormat1; //rr (register register) string InstFormat2; //ri (register immediate) string InstFormat3; //pred true string InstFormat4; //pred false } Define Instruction formats which are IFormat objects and have a unique integer value associated with them. It is used to access appropriate field within RelHexagon Class. def Format_prev : IFormat<0>; // previous form def Format_rr : IFormat<1>; // register register def Format_ri : IFormat<2>; // register immediate def Format_predt : IFormat<3>; // pred true def Format_predf : IFormat<4>; // pred false 4) Prototype relationship model for a simple 'add' instruction with 6 variants: /---- if (p0) R1 = add(R2, R3) / (Predicate true) Add register register - R1 = add(R2, R3) -- \ \---- if (!p0) R1 = add(R2, R3) (predicate false) /---- if (p0) R1 = add(R2, #12) / (Predicate true) Add register immediate - R1 = add(R2, #12) -- \ \---- if (!p0) R1 = add(R2, #12) (predicate false) multiclass Add_rr < IFormat TransformsFrom> { def #NAME# : V2_A2_add, RelationMap < TransformsFrom, Format_rr>; defm _pt : V2_A2_padd, RelationMap < Format_rr, Format_predt, ["rr"]>; defm _pf : V2_A2_padd, RelationMap < Format_rr, Format_predf, ["rr"] >; } multiclass Add_ri < IFormat TransformsFrom> { def #NAME# : V2_A2_addi, RelationMap < TransformsFrom, Format_ri >; defm _pt : V2_A2_paddi, RelationMap < Format_ri, Format_predt, ["ri"] >; defm _pf : V2_A2_paddi, RelationMap < Format_ri, Format_predf, ["ri"] >; } multiclass Add_base { defm rr : Add_rr < Format_rr>; defm ri : Add_ri < Format_rr>; } defm ADD : Add_base, RelHexagon; <- defm needs to inherit from RelHexagon Class here 5) We need some changes in the TGParser.cpp so that it can use the information specified through the RelationMap and populate relevant fields in the RelHexagon class. This eventually becomes part of the instruction definition (record). bool TGParser::ParseDefm(MultiClass *CurMultiClass) { ... if (InheritFromClass) { // Process all the classes to inherit as if they were part of a // regular 'def' and inherit all record values. SubClassReference SubClass = ParseSubClassReference(0, false); while (1) { // Check for error. if (SubClass.Rec == 0) return true; // Get the expanded definition prototypes and teach them about // the record values the current class to inherit has for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i) { Record *CurRec = NewRecDefs[i]; **** proposed changes -begin ***** if (SubClass.Rec->isSubClassOf("Relations")) { std::vector<Init*> InstrFormats(SubClass.Rec->getValues().size()); 1) Traverse thru all the records to see if CurRec's InstrFormat is same as the ParentFormat for any of the records and they both share same ancestors. If so, insert that record at the appropriate place in the vector using the integer value of the InstrFormat of the children instructions. 2) Use Vector to populate fields of the SubClass.Rec (RelHexagon in our case) Class. } **** proposed changes -end ***** // All the fields from a subclass are eventually added into the instruction record -- existing functionality 6) Add a new command line option into TableGen that will emit this information as a table in a .inc file. 7) Target is required to add its own API to read the table and extract relevant information. Thanks, Jyotsna -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum. -----Original Message----- From: Jakob Stoklund Olesen [mailto:stoklund at 2pi.dk] Sent: Thursday, August 02, 2012 5:24 PM To: Jyotsna Verma Cc: 'Tony Linthicum'; llvmdev at cs.uiuc.edu Subject: Re: TableGen related question for the Hexagon backend On Aug 1, 2012, at 1:53 PM, Jyotsna Verma <jverma at codeaurora.org> wrote:> > Currently, we rely on switch tables to transform between formats. > However, we would like to have a different mechanism to represent > these relationships instead of switch tables. I am thinking of > modeling these relations in HexagonInstrInfo.td file and use TableGen > to generate a table with the information.That would be a good idea. X86 could also use some help with opcode mapping tables.> Idea is to have a new class, say Relations, with some members of type > 'Instruction' each representing a specific relation between itself and > 'ThisInstr'. > > For example: > class Relations { > Instruction ThisInstr; > Instruction BaseForm; > Instruction TruePred; > Instruction FalsePred; > } > > def Rel_ADDrr : Relations<ADDrr, ADDrr, ADDrr_p, ADDrr_np>; def > Rel_ADDrr_p: Relations<ADDrr_p, ADDrr, , >; def Rel_ADDrr_np : > Relations<ADDrr_np,ADDrr, , >;The problem is, this isn't really any better than having a large switch statement. You just moved the table into the .td file. You should be taking advantage of the instruction multiclasses so you don't have to maintain a full table of opcodes. /jakob
Possibly Parallel Threads
- [LLVMdev] TableGen related question for the Hexagon backend
- [LLVMdev] TableGen related question for the Hexagon backend
- [LLVMdev] TableGen related question for the Hexagon backend
- [LLVMdev] TableGen related question for the Hexagon backend
- TargetRegisterInfo::getCommonSubClass bug, perhaps.