Difference between revisions of "NaplesPUInstrFormats.td"

From NaplesPU Documentation
Jump to: navigation, search
(Instruction Formats)
(Custom Nodes)
Line 19: Line 19:
 
However, there is also a '''Pseudo''' class which can be used for nodes that cannot be translated into machine nodes through a pattern but require other transformations.
 
However, there is also a '''Pseudo''' class which can be used for nodes that cannot be translated into machine nodes through a pattern but require other transformations.
  
== Custom Nodes ==
+
== Pattern Fragments ==
 +
In the file are also defined custom pattern fragments (the default ones are included in the file ''TargetSelectionDAG.td'') used to help LLVM to match LLVM IR patterns. A '''pattern fragment''', represented by the class '''PatFrag''', can match something on the DAG, from a single node to multiple nested other fragments, by specifying the input '''operands''', the '''dag fragment''' to match that satisfy a '''predicate''' (if applicable, default none) and even the '''transformation''' to perform through a '''SDNodeXForm''' (if applicable, default NOOP_SDNodeXForm).
 +
 
 +
 
 +
<syntaxhighlight lang="c" line='line'>
 +
class PatFrag<dag ops, dag frag, code pred = [{}],
 +
              SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
 +
  dag Operands = ops;
 +
  dag Fragment = frag;
 +
  code PredicateCode = pred;
 +
  code ImmediateCode = [{}];
 +
  SDNodeXForm OperandTransform = xform;
 +
}
 +
</syntaxhighlight>
 +
 
 +
As an example lets consider the nu+ load-store pattern fragments. Since nu+ has two addressing spaces, the '''main memory''' and the '''scratchpad memory''', these pattern fragments are used to detect where loads and stores are directed. This is done specifying a predicate (written in C++) that checks the associated addressing space.
 +
 
 +
<syntaxhighlight lang="c" line='line'>
 +
def MemStore : PatFrag<(ops node:$val, node:$ptr),
 +
                      (store node:$val, node:$ptr), [{
 +
              if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
 +
                  return !cast<StoreSDNode>(N)->isTruncatingStore();
 +
              else
 +
                  return false;}]>;
 +
 
 +
def ScratchpadStore : PatFrag<(ops node:$val, node:$ptr),
 +
                              (store node:$val, node:$ptr), [{
 +
              if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
 +
                return !cast<StoreSDNode>(N)->isTruncatingStore();
 +
              else
 +
                return false;}]>;
 +
</syntaxhighlight>
 +
 
 +
Starting from the PatFrag class, other useful classes are derived such as the '''OutPatFrag''' class and the '''PatLeaf''' class. The '''OutPatFrag''' class is pattern fragment but do not have predicates or transforms, used to avoid repeated subexpressions in output patterns.
 +
The '''PatLeaf''' class is a pattern fragments that have no operands and is used as a helper.
 +
 
 +
<syntaxhighlight lang="c" line='line'>
 +
class OutPatFrag<dag ops, dag frag>
 +
        : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>;
 +
 
 +
class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
 +
        : PatFrag<(ops), frag, pred, xform>;
 +
</syntaxhighlight>
 +
 
 +
In the nu+ backend '''OutPatFrag''' class is used to help with the extraction and insertion of sub-registers.
 +
 
 +
<syntaxhighlight lang="c" line='line'>
 +
def GetEvenReg: OutPatFrag<(ops node:$Rs),
 +
                          (EXTRACT_SUBREG (i64 $Rs), sub_even)>;
 +
 
 +
def GetOddReg: OutPatFrag<(ops node:$Rs),
 +
                          (EXTRACT_SUBREG (i64 $Rs), sub_odd)>;
 +
 
 +
def SetEvenReg: OutPatFrag<(ops node:$Rs),
 +
                          (i64 (SUBREG_TO_REG (i64 0), (i32 $Rs), sub_even))>;
 +
 
 +
def SetOddReg: OutPatFrag<(ops node:$Rs),
 +
                          (i64 (SUBREG_TO_REG (i64 0), (i32 $Rs), sub_odd))>;
 +
</syntaxhighlight>
 +
 
 +
In the nu+ backend '''PatLeaf''' is used to define 16-bit and 9-bit immediates.
 +
 
 +
<syntaxhighlight lang="c" line='line'>
 +
 
 +
def simm16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
 +
 
 +
def simm9 : PatLeaf<(imm), [{ return isInt<9>(N->getSExtValue()); }]>;</syntaxhighlight>

Revision as of 09:51, 1 October 2017

NuPlusInstrFormats.td and NuPlusInstrInfo.td describe the nu+ instructions and the patterns to transform LLVM IR into machine code. The NuPlusInstrFormats.td contains the classes that describe the nu+ instruction formats, support classes that facilitates the instructions definition and also the definition nodes which make the pattern recognition easier.

The files "compiler/include/llvm/Target/Target.td" and "compiler/include/llvm/Target/TargetSelectionDAG.td" contain the Tablegen classes used for the decription.

Instruction Formats

An instruction is specified in TableGen by the class Instruction, which contains the following fields:

  • Output operands, this contains the output value(s) defined by the instruction as a result of its computation;
  • Input operands, this holds all the input value(s) used by the instruction as its input operands;
  • Assembly string,this stores the string that is recognized by the assembler or that is printed by the disassembler;
  • DAG pattern, this is the DAG pattern of machine-independent SelectionDAG nodes that is matched by the instruction selector to produce an instance of the corresponding target-specific instruction.

To handle the nu+ ISA complexity, a hierarchy of classes has been created. Each level of the hierarchy refines an aspect of the nu+ instruction formats. For example the FR_TwoOp_Unmasked_32 class refines the FR class providing an easy way to define unmasked instructions of type R that takes two 32-bit operands.

The instruction formats classes are then used to create instruction multiclasses. In this way all the possible variants are generated with a single instruction definition. An example is the FArithInt_TwoOp multiclass. It is used with arithmetic instructions with two integer operands. When FArithInt_TwoOp instrcution is defined, Talbegen automatically instantiate all the possible variations according to the classes contained in the multiclass definition.

However, there is also a Pseudo class which can be used for nodes that cannot be translated into machine nodes through a pattern but require other transformations.

Pattern Fragments

In the file are also defined custom pattern fragments (the default ones are included in the file TargetSelectionDAG.td) used to help LLVM to match LLVM IR patterns. A pattern fragment, represented by the class PatFrag, can match something on the DAG, from a single node to multiple nested other fragments, by specifying the input operands, the dag fragment to match that satisfy a predicate (if applicable, default none) and even the transformation to perform through a SDNodeXForm (if applicable, default NOOP_SDNodeXForm).


class PatFrag<dag ops, dag frag, code pred = [{}],
              SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
  dag Operands = ops;
  dag Fragment = frag;
  code PredicateCode = pred;
  code ImmediateCode = [{}];
  SDNodeXForm OperandTransform = xform;
}

As an example lets consider the nu+ load-store pattern fragments. Since nu+ has two addressing spaces, the main memory and the scratchpad memory, these pattern fragments are used to detect where loads and stores are directed. This is done specifying a predicate (written in C++) that checks the associated addressing space.

def MemStore : PatFrag<(ops node:$val, node:$ptr),
                       (store node:$val, node:$ptr), [{
               if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
                  return !cast<StoreSDNode>(N)->isTruncatingStore();
               else
                  return false;}]>;

def ScratchpadStore : PatFrag<(ops node:$val, node:$ptr),
                              (store node:$val, node:$ptr), [{
               if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
                 return !cast<StoreSDNode>(N)->isTruncatingStore();
               else
                 return false;}]>;

Starting from the PatFrag class, other useful classes are derived such as the OutPatFrag class and the PatLeaf class. The OutPatFrag class is pattern fragment but do not have predicates or transforms, used to avoid repeated subexpressions in output patterns.

The PatLeaf class is a pattern fragments that have no operands and is used as a helper.
class OutPatFrag<dag ops, dag frag>
        : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>;

class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
        : PatFrag<(ops), frag, pred, xform>;

In the nu+ backend OutPatFrag class is used to help with the extraction and insertion of sub-registers.

def GetEvenReg: OutPatFrag<(ops node:$Rs),
                           (EXTRACT_SUBREG (i64 $Rs), sub_even)>;

def GetOddReg: OutPatFrag<(ops node:$Rs),
                          (EXTRACT_SUBREG (i64 $Rs), sub_odd)>;

def SetEvenReg: OutPatFrag<(ops node:$Rs),
                           (i64 (SUBREG_TO_REG (i64 0), (i32 $Rs), sub_even))>;

def SetOddReg: OutPatFrag<(ops node:$Rs),
                           (i64 (SUBREG_TO_REG (i64 0), (i32 $Rs), sub_odd))>;

In the nu+ backend PatLeaf is used to define 16-bit and 9-bit immediates.

def simm16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;

def simm9 : PatLeaf<(imm), [{ return isInt<9>(N->getSExtValue()); }]>;