[Beignet] [PATCH] Use a separate pattern for simd shuffle instead of binary pattern

Song, Ruiling ruiling.song at intel.com
Wed Jul 15 20:10:15 PDT 2015


> +  class SimdShuffleInstructionPattern : public SelectionPattern  {
> +  public:
> +    SimdShuffleInstructionPattern(void) : SelectionPattern(1,1) {
> +      this->opcodes.push_back(ir::OP_SIMD_SHUFFLE);
> +    }
> +    INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const {
> +      using namespace ir;
> +      const ir::SimdShuffleInstruction &insn =
> cast<SimdShuffleInstruction>(dag.insn);
> +      assert(insn.getOpcode() == OP_SIMD_SHUFFLE);
> +      const Type type = insn.getType();
> +      GenRegister dst  = sel.selReg(insn.getDst(0), type);
> +
> +      sel.push();
> +
> +      GenRegister src0, src1;
> +      bool inverse = false;
> +      sel.getSrcGenRegImm(dag, src0, src1, type, inverse);

getSrcGenRegImm is for binary instruction, you'd better refine the function naming,
And write a new piece of code to do the imm optimization for simd-shuffle.

> +
> +      if (src1.file == GEN_IMMEDIATE_VALUE)
> +        sel.SIMD_SHUFFLE(dst, src0, src1);
> +      else {
 sel.selReg() should be enough for here, we should try to avoid using xxxgrf directly.

> +        GenRegister shiftL = GenRegister::udxgrf(sel.curr.execWidth,
> sel.reg(FAMILY_DWORD));
> +        sel.SHL(shiftL, src1, GenRegister::immud(0x2));
> +        sel.SIMD_SHUFFLE(dst, src0, shiftL);
> +      }
> +
> +      sel.pop();
> +      return true;
> +    }
> +  };
> +
>    /*! Get a region of a register */
>    class RegionInstructionPattern : public SelectionPattern
>    {
> @@ -5247,6 +5277,7 @@ namespace gbe
>      this->insert<GetImageInfoInstructionPattern>();
>      this->insert<ReadARFInstructionPattern>();
>      this->insert<RegionInstructionPattern>();
> +    this->insert<SimdShuffleInstructionPattern>();
>      this->insert<IndirectMovInstructionPattern>();
>      this->insert<NullaryInstructionPattern>();
> 
> diff --git a/backend/src/backend/gen_insn_selection.hxx
> b/backend/src/backend/gen_insn_selection.hxx
> index 79f2ce1..adbb137 100644
> --- a/backend/src/backend/gen_insn_selection.hxx
> +++ b/backend/src/backend/gen_insn_selection.hxx
> @@ -26,7 +26,7 @@ DECL_SELECTION_IR(SHL, BinaryInstruction)
> DECL_SELECTION_IR(RSR, BinaryInstruction)  DECL_SELECTION_IR(RSL,
> BinaryInstruction)  DECL_SELECTION_IR(ASR, BinaryInstruction)
> -DECL_SELECTION_IR(SIMD_SHUFFLE, BinaryInstruction)
> +DECL_SELECTION_IR(SIMD_SHUFFLE, SimdShuffleInstruction)
>  DECL_SELECTION_IR(I64SHR, I64ShiftInstruction)
> DECL_SELECTION_IR(I64SHL, I64ShiftInstruction)
> DECL_SELECTION_IR(I64ASR, I64ShiftInstruction) diff --git
> a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index
> 12d70a6..a31d04c 100644
> --- a/backend/src/ir/instruction.cpp
> +++ b/backend/src/ir/instruction.cpp
> @@ -741,6 +741,21 @@ namespace ir {
>        Register src[0];
>      };
> 
> +    class ALIGNED_INSTRUCTION SimdShuffleInstruction : public
> NaryInstruction<2>
> +    {
> +    public:
> +      SimdShuffleInstruction(Type type,
> +                        Register dst,
> +                        Register src0,
> +                        Register src1) {
> +        this->opcode = OP_SIMD_SHUFFLE;
> +        this->type = type;
> +        this->dst[0] = dst;
> +        this->src[0] = src0;
> +        this->src[1] = src1;
> +      }
> +    };
> +

Seems like you missed SimdShuffleInstruction::wellformed()?

>      class ALIGNED_INSTRUCTION RegionInstruction :
>        public BasePolicy,
>        public NSrcPolicy<RegionInstruction, 1>, @@ -1461,6 +1476,10
> @@ START_INTROSPECTION(RegionInstruction)
>  #include "ir/instruction.hxx"
>  END_INTROSPECTION(RegionInstruction)
> 
> +START_INTROSPECTION(SimdShuffleInstruction)
> +#include "ir/instruction.hxx"
> +END_INTROSPECTION(SimdShuffleInstruction)
> +
>  START_INTROSPECTION(IndirectMovInstruction)
>  #include "ir/instruction.hxx"
>  END_INTROSPECTION(IndirectMovInstruction)
> @@ -1652,6 +1671,7 @@ DECL_MEM_FN(BranchInstruction, LabelIndex,
> getLabelIndex(void), getLabelIndex())  DECL_MEM_FN(SyncInstruction,
> uint32_t, getParameters(void), getParameters())
> DECL_MEM_FN(ReadARFInstruction, Type, getType(void), getType())
> DECL_MEM_FN(ReadARFInstruction, ARFRegister, getARFRegister(void),
> getARFRegister())
> +DECL_MEM_FN(SimdShuffleInstruction, Type, getType(void), getType())
>  DECL_MEM_FN(RegionInstruction, uint32_t, getOffset(void), getOffset())
> DECL_MEM_FN(IndirectMovInstruction, uint32_t, getOffset(void),
> getOffset())  DECL_MEM_FN(IndirectMovInstruction, Type, getType(void),
> getType()) @@ -1751,7 +1771,6 @@
> DECL_MEM_FN(GetImageInfoInstruction, uint8_t, getImageIndex(void),
> getImageIndex
>    DECL_EMIT_FUNCTION(RHADD)
>    DECL_EMIT_FUNCTION(I64HADD)
>    DECL_EMIT_FUNCTION(I64RHADD)
> -  DECL_EMIT_FUNCTION(SIMD_SHUFFLE)
> 
>  #undef DECL_EMIT_FUNCTION
> 
> @@ -1881,6 +1900,9 @@ DECL_MEM_FN(GetImageInfoInstruction, uint8_t,
> getImageIndex(void), getImageIndex
>    Instruction REGION(Register dst, Register src, uint32_t offset) {
>      return internal::RegionInstruction(dst, src, offset).convert();
>    }
> +  Instruction SIMD_SHUFFLE(Type type, Register dst, Register src0,
> Register src1) {
> +    return internal::SimdShuffleInstruction(type, dst, src0,
> + src1).convert();  }
> 
>    Instruction INDIRECT_MOV(Type type, Register dst, Register src0,
> Register src1, uint32_t offset) {
>      return internal::IndirectMovInstruction(type, dst, src0, src1,
> offset).convert(); diff --git a/backend/src/ir/instruction.hpp
> b/backend/src/ir/instruction.hpp index ec4d00d..cf8d839 100644
> --- a/backend/src/ir/instruction.hpp
> +++ b/backend/src/ir/instruction.hpp
> @@ -522,6 +522,14 @@ namespace ir {
>      static bool isClassOf(const Instruction &insn);
>    };
> 
> +  /*! simd shuffle */
> +  class SimdShuffleInstruction : public Instruction {
> +  public:
> +    Type getType(void) const;
> +    /*! Return true if the given instruction is an instance of this class */
> +    static bool isClassOf(const Instruction &insn);  };
> +
>    /*! return a region of a register, make sure the offset does not exceed
> the register size */
>    class RegionInstruction : public Instruction {
>    public:
> diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx
> index 1001837..81548c9 100644
> --- a/backend/src/ir/instruction.hxx
> +++ b/backend/src/ir/instruction.hxx
> @@ -59,7 +59,7 @@ DECL_INSN(BSB, BinaryInstruction)  DECL_INSN(OR,
> BinaryInstruction)  DECL_INSN(XOR, BinaryInstruction)  DECL_INSN(AND,
> BinaryInstruction) -DECL_INSN(SIMD_SHUFFLE, BinaryInstruction)
> +DECL_INSN(SIMD_SHUFFLE, SimdShuffleInstruction)
>  DECL_INSN(SEL, SelectInstruction)
>  DECL_INSN(EQ, CompareInstruction)
>  DECL_INSN(NE, CompareInstruction)
> --
> 1.9.1
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list