HowTo: Add arbitrary properties to instructions

From LLVM

Jump to: navigation, search

Use the TSFlags field to add custom properties to target instructions.

1. Define your enum in your Target's instruction namespace in MT.h (MT ^= my target)

namespace MTII {
  enum {
    /* Mask for Prop (5 bits) */
    PropMask = 0x1F,
    /* shift for ctrlLine 
     * I think it is a good idea to always define a masd and shift
     * to be able to reorganize the TSFlags later without goint
     * through the entire backend code.
     */
    PropShift = 0,
 
    PropNone = 0,
    PropX    = 1,
    PropY    = 2,
    PropZ    = 3
  };
}


2. Define the properties in InstrInfo.td

<class PropClass<bits<5> val > {
  bits<5> Value = val;
}
 
def  PropX : PropClass <0>;
def  PropY : PropClass <1>;
def  PropZ : PropClass <2>;


3. use the properties in the instruction class in InstrInfo.td

// Instruction base class
class InstMT<dag outs, dag ins,
             string asmstr,
             list<dag> pattern > : Instruction {
 
  // for TSFlag
  PropClass Prop;
  bits<5> bitsProp = Prop.Value;
}


4. Define instruction classes for the properties Alternatively, use a template parameter or the 'let Prop=PropX in {}' syntax when defining instructions in MTInstrInfo.td

class InstPropX<dag outs, dag ins, string asmstr, list<dag> pattern>
   : InstMT<outs, ins, asmstr, pattern> {
  let Prop = PropX;
}


5. tell Tablegen to use all that stuff for the TSFlags in MT.td

def MTInstrInfo : InstrInfo {
  // Define how we want to layout our target-specific information field.
  let TSFlagsFields = [
                       // 5 bits for instruction props
                       "bitsCtrlLine"
  ];
  let TSFlagsShifts = [
                       // "Props" is bit 0..4
                       // Q: what can (or does) 'TSFlagsShifts' do for us?
                       0
  ];
}


6. use the TSFlags in the backend code, for example:

const MachineInstr *MI = SU->getInstr();
const TargetInstrDesc Desc = MI->getDesc();
if (((Desc.TSFlags & MTII::PropMask) >> MT::PropShift)  == OCII::PropX)
{
// do fancy stuff
}
Personal tools