[Beignet] [Printf][PATCH 04/11] Add the implementation of printf ir instruction.

Yan Wang yan.wang at linux.intel.com
Wed Jan 20 19:29:41 PST 2016


Contributor: Junyan He <junyan.he at linux.intel.com>
Signed-off-by: Yan Wang <yan.wang at linux.intel.com>
---
 backend/src/ir/function.hpp    |  8 ++++++
 backend/src/ir/instruction.cpp | 57 +++++++++++++++++++++++++++++++++++++++++-
 backend/src/ir/instruction.hpp | 13 ++++++++++
 backend/src/ir/instruction.hxx |  1 +
 backend/src/ir/register.cpp    |  8 ++++++
 backend/src/ir/register.hpp    | 21 ++++++++++++++++
 6 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp
index 78250cf..5785bee 100644
--- a/backend/src/ir/function.hpp
+++ b/backend/src/ir/function.hpp
@@ -341,6 +341,14 @@ namespace ir {
     INLINE void setRegister(Tuple ID, uint32_t which, Register reg) {
       file.set(ID, which, reg);
     }
+    /*! Get the type from the tuple vector */
+    INLINE uint8_t getType(Tuple ID, uint32_t which) const {
+      return file.getType(ID, which);
+    }
+    /*! Set the type into the tuple vector */
+    INLINE void setType(Tuple ID, uint32_t which, uint8_t type) {
+      file.setType(ID, which, type);
+    }
     /*! Get the register file */
     INLINE const RegisterFile &getRegisterFile(void) const { return file; }
     /*! Get the given value ie immediate from the function */
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index bb5aac5..652c1fb 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -994,6 +994,40 @@ namespace ir {
         Register dst[1];
     };
 
+    class ALIGNED_INSTRUCTION PrintfInstruction :
+      public BasePolicy,
+      public TupleSrcPolicy<PrintfInstruction>,
+      public NDstPolicy<PrintfInstruction, 1>
+    {
+      public:
+        INLINE PrintfInstruction(Register dst, Tuple srcTuple, Tuple typeTuple,
+                                 uint8_t srcNum, uint8_t bti, uint16_t num) {
+          this->opcode = OP_PRINTF;
+          this->dst[0] = dst;
+          this->src = srcTuple;
+          this->type = typeTuple;
+          this->srcNum = srcNum;
+          this->bti = bti;
+          this->num = num;
+        }
+        INLINE bool wellFormed(const Function &fn, std::string &whyNot) const;
+        INLINE void out(std::ostream &out, const Function &fn) const;
+
+        uint32_t getNum(void) const { return this->num; }
+        uint32_t getBti(void) const { return this->bti; }
+        Type getType(const Function& fn, uint32_t ID) const {
+          GBE_ASSERTM(ID < this->srcNum, "Out-of-bound types");
+          return (Type)fn.getType(type, ID);
+        }
+
+        uint32_t srcNum:8;    //!< Source Number
+        uint32_t bti:8;       //!< The BTI
+        uint32_t num:16;      //!< The printf statement number of one kernel.
+        Tuple src;
+        Tuple type;
+        Register dst[1];
+    };
+
 #undef ALIGNED_INSTRUCTION
 
     /////////////////////////////////////////////////////////////////////////
@@ -1473,6 +1507,10 @@ namespace ir {
       return true;
     }
 
+    INLINE bool PrintfInstruction::wellFormed(const Function &fn, std::string &whyNot) const {
+      return true;
+    }
+
 #undef CHECK_TYPE
 
     /////////////////////////////////////////////////////////////////////////
@@ -1702,6 +1740,11 @@ namespace ir {
 
       out << "TheadID Map at SLM: " << this->slmAddr;
     }
+
+    INLINE void PrintfInstruction::out(std::ostream &out, const Function &fn) const {
+      this->outOpcode(out);
+    }
+
   } /* namespace internal */
 
   std::ostream &operator<< (std::ostream &out, AddressSpace addrSpace) {
@@ -1862,6 +1905,10 @@ START_INTROSPECTION(WorkGroupInstruction)
 #include "ir/instruction.hxx"
 END_INTROSPECTION(WorkGroupInstruction)
 
+START_INTROSPECTION(PrintfInstruction)
+#include "ir/instruction.hxx"
+END_INTROSPECTION(PrintfInstruction)
+
 #undef END_INTROSPECTION
 #undef START_INTROSPECTION
 #undef DECL_INSN
@@ -2008,7 +2055,8 @@ END_FUNCTION(Instruction, Register)
            opcode == OP_ATOMIC ||
            opcode == OP_CALC_TIMESTAMP ||
            opcode == OP_STORE_PROFILING ||
-           opcode == OP_WAIT;
+           opcode == OP_WAIT ||
+           opcode == OP_PRINTF;
   }
 
 #define DECL_MEM_FN(CLASS, RET, PROTOTYPE, CALL) \
@@ -2071,6 +2119,9 @@ DECL_MEM_FN(StoreProfilingInstruction, uint32_t, getBTI(void), getBTI())
 DECL_MEM_FN(WorkGroupInstruction, Type, getType(void), getType())
 DECL_MEM_FN(WorkGroupInstruction, WorkGroupOps, getWorkGroupOpcode(void), getWorkGroupOpcode())
 DECL_MEM_FN(WorkGroupInstruction, uint32_t, getSlmAddr(void), getSlmAddr())
+DECL_MEM_FN(PrintfInstruction, uint32_t, getNum(void), getNum())
+DECL_MEM_FN(PrintfInstruction, uint32_t, getBti(void), getBti())
+DECL_MEM_FN(PrintfInstruction, Type, getType(const Function& fn, uint32_t ID), getType(fn, ID))
 
 #undef DECL_MEM_FN
 
@@ -2369,6 +2420,10 @@ DECL_MEM_FN(MemInstruction, void,     setBtiReg(Register reg), setBtiReg(reg))
     return internal::WorkGroupInstruction(opcode, slmAddr, dst, srcTuple, srcNum, type).convert();
   }
 
+  Instruction PRINTF(Register dst, Tuple srcTuple, Tuple typeTuple, uint8_t srcNum, uint8_t bti, uint16_t num) {
+    return internal::PrintfInstruction(dst, srcTuple, typeTuple, srcNum, bti, num).convert();
+  }
+
   std::ostream &operator<< (std::ostream &out, const Instruction &insn) {
     const Function &fn = insn.getFunction();
     const BasicBlock *bb = insn.getParent();
diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
index ec7b9b5..9cc926d 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -611,6 +611,17 @@ namespace ir {
     uint32_t getSlmAddr(void) const;
   };
 
+  /*! Printf instruction. */
+  class PrintfInstruction : public Instruction {
+  public:
+    uint32_t getNum(void) const;
+    uint32_t getBti(void) const;
+    Type getType(const Function& fn, uint32_t ID) const;
+    Type getType(uint32_t ID) const { return this->getType(this->getFunction(), ID); };
+    /*! Return true if the given instruction is an instance of this class */
+    static bool isClassOf(const Instruction &insn);
+  };
+
   /*! Specialize the instruction. Also performs typechecking first based on the
    *  opcode. Crashes if it fails
    */
@@ -839,6 +850,8 @@ namespace ir {
 
   /*! work group */
   Instruction WORKGROUP(WorkGroupOps opcode, uint32_t slmAddr, Register dst, Tuple srcTuple, uint8_t srcNum, Type type);
+  /*! printf */
+  Instruction PRINTF(Register dst, Tuple srcTuple, Tuple typeTuple, uint8_t srcNum, uint8_t bti, uint16_t num);
 } /* namespace ir */
 } /* namespace gbe */
 
diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx
index 498861c..651ed64 100644
--- a/backend/src/ir/instruction.hxx
+++ b/backend/src/ir/instruction.hxx
@@ -112,3 +112,4 @@ DECL_INSN(CALC_TIMESTAMP, CalcTimestampInstruction)
 DECL_INSN(STORE_PROFILING, StoreProfilingInstruction)
 DECL_INSN(WAIT, WaitInstruction)
 DECL_INSN(WORKGROUP, WorkGroupInstruction)
+DECL_INSN(PRINTF, PrintfInstruction)
diff --git a/backend/src/ir/register.cpp b/backend/src/ir/register.cpp
index 48d6875..8200c31 100644
--- a/backend/src/ir/register.cpp
+++ b/backend/src/ir/register.cpp
@@ -62,6 +62,14 @@ namespace ir {
     return index;
   }
 
+  Tuple RegisterFile::appendArrayTypeTuple(const uint8_t *types, uint32_t num) {
+    const Tuple index = Tuple(typeTuples.size());
+    for (uint32_t id = 0; id < num; id++) {
+      typeTuples.push_back(types[id]);
+    }
+    return index;
+  }
+
 } /* namespace ir */
 } /* namespace gbe */
 
diff --git a/backend/src/ir/register.hpp b/backend/src/ir/register.hpp
index d64304e..11ab756 100644
--- a/backend/src/ir/register.hpp
+++ b/backend/src/ir/register.hpp
@@ -179,6 +179,18 @@ namespace ir {
     }
     /*! To terminate variadic recursion */
     INLINE void appendTuple(void) {}
+    /*! Make a tuple from an array of Type */
+    Tuple appendArrayTypeTuple(const uint8_t *types, uint32_t num);
+    /*! Make a tuple and return the index to the first element of the tuple */
+    template <typename First, typename... Rest>
+    INLINE Tuple appendTypeTuple(First first, Rest... rest) {
+      const Tuple index = Tuple(typeTuples.size());
+      typeTuples.push_back(first);
+      appendTuple(rest...);
+      return index;
+    }
+    /*! To terminate variadic recursion */
+    INLINE void appendTypeTuple(void) {}
     /*! Return a copy of the register at index */
     INLINE RegisterData get(Register index) const { return regs[index]; }
     /*! Return true if the specified register is uniform type. */
@@ -205,6 +217,14 @@ namespace ir {
     INLINE void set(Tuple index, uint32_t which, Register reg) {
       regTuples[index.value() + which] = reg;
     }
+    /*! Get the type from the tuple */
+    INLINE uint8_t getType(Tuple index, uint32_t which) const {
+      return typeTuples[index.value() + which];
+    }
+    /*! Set the type to the tuple */
+    INLINE void setType(Tuple index, uint32_t which, uint8_t type) {
+      typeTuples[index.value() + which] = type;
+    }
     /*! Number of registers in the register file */
     INLINE uint32_t regNum(void) const { return regs.size(); }
     /*! Number of tuples in the register file */
@@ -214,6 +234,7 @@ namespace ir {
   private:
     vector<RegisterData> regs;   //!< All the registers together
     vector<Register> regTuples;  //!< Tuples are used for many src / dst
+    vector<uint8_t> typeTuples;  //!< Tuples are used for one instruction has multi src/dst types.
     GBE_CLASS(RegisterFile);
   };
 
-- 
2.4.3



More information about the Beignet mailing list