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
Maybe Matching 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.