Jyotsna Verma
2012-Aug-17 17:02 UTC
[LLVMdev] TableGen related question for the Hexagon backend
Hi Jacob, Thanks for the suggestions. I have a few questions here.> You are on to something here, but you don't need to define a 'Relations'class> on top of the tablegen records. They are already relations, you just needthe> proper query language to match the instructions you want.Are you saying that the mechanism is already present which allows us to relate instructions with each other? What do you mean by a proper query language?> You don't want to be limited to a single 'IFormat' as a column > identifier, there can be many different types of relationships between > instructions.We do have different type of relationships between instructions. I define multiple IFormat objects one per relationship which finally translates into a unique column into the mapping table. def Format_rr : IFormat<1>; def Format_ri : IFormat<2>; def Format_predt : IFormat<3>; def Format_predf : IFormat<4>; Addrr : { Addrr, Addri, Addrr_pt, Addrr_pf, .. , ..} Addri : { Addrr, Addri, Addri_pt, Addri_pf,..> Do something like this: > > def getPredicatedOpcode : InstrMapping { > // Only include instructions form the PredRel class. > let FilterClass = "PredRel"; > > // Instructions with the same BaseOpcode field form a row. > let RowFields = ["BaseOpcode"]; > > // Instructions with the same predicate sense form a column. > let ColFields = ["PredSense"]; > > // The key column is the unpredicated instructions. > let KeyCol = ["nopred"]; > > // Value columns are predicate=true and predicate=false > let ValueCols = [["true"], ["false"]]; };Can you please elaborate it more? It seems interesting but I coundn't understand it completely. Also, how do I get the table from the definition above? For the table, I need to know the name of the predicated-true and false instructions.> That should be enough to generate a table: > > // key , PredSense=true, PredSense=false > { ADD , ADDtrue, ADDfalse, // BaseOpcode="ADD" > { SUB , SUBtrue, SUBfalse, // BaseOpcode="SUB"> > > 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. > > The tablegen parser is definitely not the right place to implement this.I didn't want to modify the tablegen parser either. But, I couldn't think of a way around it. Once instructions are expended by the TableGen parser, there is no way to relate them. Since I wanted to encode this formation within the instruction itself while they are being expanded, parser appeared to be the only place to do it. Thanks, Jyotsna
Jakob Stoklund Olesen
2012-Aug-17 17:55 UTC
[LLVMdev] TableGen related question for the Hexagon backend
On Aug 17, 2012, at 10:02 AM, "Jyotsna Verma" <jverma at codeaurora.org> wrote:> > Hi Jacob, > > Thanks for the suggestions. I have a few questions here. > >> You are on to something here, but you don't need to define a 'Relations' > class >> on top of the tablegen records. They are already relations, you just need > the >> proper query language to match the instructions you want. > > Are you saying that the mechanism is already present which allows us to > relate instructions with each other? What do you mean by a proper query > language?Yes, in the very simple sense that you can relate instructions that have the same value in a field: def ADD { let BaseOpcode = "ADD"; let PredSense = "nopred"; } def ADDtrue { let BaseOpcode = "ADD"; let PredSense = "true"; } Inside a multiclass, the NAME variable is set to the base name of the defm. You can use that to relate your instructions.>> You don't want to be limited to a single 'IFormat' as a column >> identifier, there can be many different types of relationships between >> instructions. > > We do have different type of relationships between instructions. I define > multiple IFormat objects one per relationship which finally translates into > a unique column into the mapping table.My point is that you don't need to define additional structure when you can just use the record fields.>> def getPredicatedOpcode : InstrMapping { >> // Only include instructions form the PredRel class. >> let FilterClass = "PredRel"; >> >> // Instructions with the same BaseOpcode field form a row. >> let RowFields = ["BaseOpcode"]; >> >> // Instructions with the same predicate sense form a column. >> let ColFields = ["PredSense"]; >> >> // The key column is the unpredicated instructions. >> let KeyCol = ["nopred"]; >> >> // Value columns are predicate=true and predicate=false >> let ValueCols = [["true"], ["false"]]; }; > > Can you please elaborate it more? It seems interesting but I coundn't > understand it completely. > Also, how do I get the table from the definition above? For the table, I > need to know the name of the predicated-true and false instructions.It's similar to an SQL self join: select * from PredRel as Key left outer join PredRel as Val1 on Val1.BaseOpcode = Key.BaseOpcode and Val1.PredSense = 'true' left outer join PredRel as Val2 on Val2.BaseOpcode = Key.BaseOpcode and Val2.PredSense = 'false' where Key.PredSense = 'nopred' Basically, RowFields is a list of record fields that are used to identify a row in your table. All the instructions in a row has identical row fields. Similarly, ColFields identifies instructions in a column of your table. All instructions in a column have identical column fields. KeyCol specifies the value of the column fields in your key column. ValueCols identifies the other columns in the table. It should be an error if there are multiple instructions that fit a table entry because both row and column fields are identical. You don't need to change the parser. Simply start from RecordKeeper::getAllDerivedDefinitions(FilterClass). Identify the row and column (if any) of each instruction, and build your table from that. /jakob
Jyotsna Verma
2012-Aug-20 20:32 UTC
[LLVMdev] TableGen related question for the Hexagon backend
Hi Jacob, Your suggestion worked for the simple relations between instructions as you've included in your example. With one small change, I am able to represent more complex relations as well. In the Hexagon backend, a predicated instruction can translate into another form called 'predicate new'. So, in our example of 'ADD', we can have another transformation like this - ADD--- ---> ADDtrue -----> ADDtru_new (predicate new form of true) \-----> ADDfalse -----> ADDfalse_new (predicate new form of false) // Define Predicate New relation def getPredNewOpcode : InstrMapping { let FilterClass = "PredNewRel"; let RowFields = ["BaseOpcode"]; // ColFields is a list of flags/attributes of the instructions. let ColFields = ["DotNewType", "PredSense"]; // Here 'DotNewType' of the KeyCol is "" and Predsense can be either 'true' or 'false' let KeyCol = ["", "-"]; // Value Column has DotNewType= "new" and predsense same as KeyCol. // '-' is used to indicate the "PredSense" value to be same as KeyCol. let ValueCols = ["new", "-"]; } def ADDtrue_new { let BaseOpcode = "ADD"; let PredSense = "true"; let DotNewType = "new"; } This allows me to list all the attributes that must remain same between the Key column and the related instructions. Let me know what you think about this. Thanks, Jyotsna> > Are you saying that the mechanism is already present which allows us > > to relate instructions with each other? What do you mean by a proper > > query language? > > Yes, in the very simple sense that you can relate instructions that havethe> same value in a field: > > def ADD { > let BaseOpcode = "ADD"; > let PredSense = "nopred"; > } > > def ADDtrue { > let BaseOpcode = "ADD"; > let PredSense = "true"; > } > > Inside a multiclass, the NAME variable is set to the base name of thedefm.> You can use that to relate your instructions.I found 'NAME' variable very difficult to use.> >> You don't want to be limited to a single 'IFormat' as a column > >> identifier, there can be many different types of relationships > >> between instructions. > > > > We do have different type of relationships between instructions. I > > define multiple IFormat objects one per relationship which finally > > translates into a unique column into the mapping table. > > My point is that you don't need to define additional structure when youcan> just use the record fields. > > >> def getPredicatedOpcode : InstrMapping { // Only include > >> instructions form the PredRel class. > >> let FilterClass = "PredRel"; > >> > >> // Instructions with the same BaseOpcode field form a row. > >> let RowFields = ["BaseOpcode"]; > >> > >> // Instructions with the same predicate sense form a column. > >> let ColFields = ["PredSense"]; > >> > >> // The key column is the unpredicated instructions. > >> let KeyCol = ["nopred"]; > >> > >> // Value columns are predicate=true and predicate=false let > >> ValueCols = [["true"], ["false"]]; }; > > > > Can you please elaborate it more? It seems interesting but I coundn't > > understand it completely. > > Also, how do I get the table from the definition above? For the table, > > I need to know the name of the predicated-true and false instructions. > > It's similar to an SQL self join: > > select * from PredRel as Key > left outer join PredRel as Val1 on Val1.BaseOpcode = Key.BaseOpcode and > Val1.PredSense = 'true' > left outer join PredRel as Val2 on Val2.BaseOpcode = Key.BaseOpcode and > Val2.PredSense = 'false' > where Key.PredSense = 'nopred' > > Basically, RowFields is a list of record fields that are used to identifya row in> your table. All the instructions in a row has identical row fields. > > Similarly, ColFields identifies instructions in a column of your table.All> instructions in a column have identical column fields. > > KeyCol specifies the value of the column fields in your key column.ValueCols> identifies the other columns in the table. > > It should be an error if there are multiple instructions that fit a tableentry> because both row and column fields are identical. > > You don't need to change the parser. Simply start from > RecordKeeper::getAllDerivedDefinitions(FilterClass). Identify the row and > column (if any) of each instruction, and build your table from that. > > /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
- [LLVMdev] TableGen related question for the Hexagon backend