[LLVMdev] TableGen related question for the Hexagon backend

Jyotsna Verma
Mon, 20 Aug 2012 20:32:40 -0000

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