[Beignet] [PATCH 2/4 opencl 1.2] Add the llvm info to the function for later usage.

junyan.he at inbox.com junyan.he at inbox.com
Sun Jun 8 23:38:52 PDT 2014


From: Junyan He <junyan.he at linux.intel.com>

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/context.cpp       |  1 +
 backend/src/ir/context.cpp            |  5 +-
 backend/src/ir/context.hpp            |  3 +-
 backend/src/ir/function.hpp           | 15 +++++-
 backend/src/llvm/llvm_gen_backend.cpp | 86 ++++++++++++++++++++++++-----------
 5 files changed, 78 insertions(+), 32 deletions(-)

diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
index db968c3..5dff573 100644
--- a/backend/src/backend/context.cpp
+++ b/backend/src/backend/context.cpp
@@ -468,6 +468,7 @@ namespace gbe
       const auto &arg = fn.getArg(argID);
 
       kernel->args[argID].align = arg.align;
+      kernel->args[argID].info = arg.info;
       switch (arg.type) {
         case ir::FunctionArgument::VALUE:
         case ir::FunctionArgument::STRUCTURE:
diff --git a/backend/src/ir/context.cpp b/backend/src/ir/context.cpp
index 256002b..bfbe825 100644
--- a/backend/src/ir/context.cpp
+++ b/backend/src/ir/context.cpp
@@ -107,10 +107,11 @@ namespace ir {
     return index;
   }
 
-  void Context::input(const std::string &name, FunctionArgument::Type type, Register reg, uint32_t elementSize, uint32_t align) {
+  void Context::input(const std::string &name, FunctionArgument::Type type, Register reg,
+                      FunctionArgument::InfoFromLLVM& info, uint32_t elementSize, uint32_t align) {
     GBE_ASSERTM(fn != NULL, "No function currently defined");
     GBE_ASSERTM(reg < fn->file.regNum(), "Out-of-bound register");
-    FunctionArgument *arg = GBE_NEW(FunctionArgument, type, reg, elementSize, name, align);
+    FunctionArgument *arg = GBE_NEW(FunctionArgument, type, reg, elementSize, name, align, info);
     fn->args.push_back(arg);
   }
 
diff --git a/backend/src/ir/context.hpp b/backend/src/ir/context.hpp
index ae5783a..27ff4e9 100644
--- a/backend/src/ir/context.hpp
+++ b/backend/src/ir/context.hpp
@@ -109,7 +109,8 @@ namespace ir {
     /*! Create a new label for the current function */
     LabelIndex label(void);
     /*! Append a new input register for the function */
-    void input(const std::string &name, FunctionArgument::Type type, Register reg, uint32_t elemSz = 0u, uint32_t align = 0);
+    void input(const std::string &name, FunctionArgument::Type type, Register reg,
+               FunctionArgument::InfoFromLLVM& info, uint32_t elemSz = 0u, uint32_t align = 0);
     /*! Append a new output register for the function */
     void output(Register reg);
     /*! Get the immediate value */
diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp
index 266e652..a59fbec 100644
--- a/backend/src/ir/function.hpp
+++ b/backend/src/ir/function.hpp
@@ -107,14 +107,25 @@ namespace ir {
       IMAGE             = 5,  // image*d_t
       SAMPLER           = 6
     };
+
+    struct InfoFromLLVM { // All the info about passed by llvm, using -cl-kernel-arg-info
+      uint32_t addrSpace;
+      std::string typeName;
+      std::string accessQual;
+      std::string typeQual;
+      std::string argName; // My different from arg->getName()
+    };
+
     /*! Create a function input argument */
-    INLINE FunctionArgument(Type type, Register reg, uint32_t size, const std::string &name, uint32_t align) :
-      type(type), reg(reg), size(size), align(align), name(name) {}
+    INLINE FunctionArgument(Type type, Register reg, uint32_t size, const std::string &name, uint32_t align, InfoFromLLVM& info) :
+      type(type), reg(reg), size(size), align(align), name(name), info(info) { }
+
     Type type;     //!< Gives the type of argument we have
     Register reg;  //!< Holds the argument
     uint32_t size; //!< == sizeof(void*) for ptr, sizeof(elem) for the rest
     uint32_t align; //!< address alignment for the argument
     const std::string name; //!< Holds the function name for IR output
+    InfoFromLLVM info;  //!< Holds the llvm passed info
     GBE_STRUCT(FunctionArgument); // Use custom allocator
   };
 
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index e8fa673..71be380 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1096,28 +1096,54 @@ namespace gbe
     // Loop over the kernel metadatas to set the required work group size.
     NamedMDNode *clKernelMetaDatas = TheModule->getNamedMetadata("opencl.kernels");
     size_t reqd_wg_sz[3] = {0, 0, 0};
-    for(uint i = 0; i < clKernelMetaDatas->getNumOperands(); i++)
-    {
-      MDNode *node = clKernelMetaDatas->getOperand(i);
-      if (node->getOperand(0) != &F) continue;
-      for(uint j = 0; j < node->getNumOperands() - 1; j++)
-      {
-        MDNode *attrNode = dyn_cast_or_null<MDNode>(node->getOperand(1 + j));
-        if (attrNode == NULL) break;
-        MDString *attrName = dyn_cast_or_null<MDString>(attrNode->getOperand(0));
-        if (attrName && attrName->getString() == "reqd_work_group_size") {
-          GBE_ASSERT(attrNode->getNumOperands() == 4);
-          ConstantInt *x = dyn_cast<ConstantInt>(attrNode->getOperand(1));
-          ConstantInt *y = dyn_cast<ConstantInt>(attrNode->getOperand(2));
-          ConstantInt *z = dyn_cast<ConstantInt>(attrNode->getOperand(3));
-          GBE_ASSERT(x && y && z);
-          reqd_wg_sz[0] = x->getZExtValue();
-          reqd_wg_sz[1] = y->getZExtValue();
-          reqd_wg_sz[2] = z->getZExtValue();
-          break;
-        }
+    ir::FunctionArgument::InfoFromLLVM llvmInfo;
+    MDNode *node = NULL;
+    MDNode *addrSpaceNode = NULL;
+    MDNode *typeNameNode = NULL;
+    MDNode *accessQualNode = NULL;
+    MDNode *typeQualNode = NULL;
+    MDNode *argNameNode = NULL;
+
+    /* First find the meta data belong to this function. */
+    for(uint i = 0; i < clKernelMetaDatas->getNumOperands(); i++) {
+      node = clKernelMetaDatas->getOperand(i);
+      if (node->getOperand(0) == &F) break;
+      node = NULL;
+    }
+
+    /* because "-cl-kernel-arg-info", should always have meta data. */
+    if (!F.arg_empty())
+      assert(node);
+
+    for(uint j = 0; j < node->getNumOperands() - 1; j++) {
+      MDNode *attrNode = dyn_cast_or_null<MDNode>(node->getOperand(1 + j));
+      if (attrNode == NULL) break;
+      MDString *attrName = dyn_cast_or_null<MDString>(attrNode->getOperand(0));
+      if (!attrName) continue;
+
+      if (attrName->getString() == "reqd_work_group_size") {
+        GBE_ASSERT(attrNode->getNumOperands() == 4);
+        ConstantInt *x = dyn_cast<ConstantInt>(attrNode->getOperand(1));
+        ConstantInt *y = dyn_cast<ConstantInt>(attrNode->getOperand(2));
+        ConstantInt *z = dyn_cast<ConstantInt>(attrNode->getOperand(3));
+        GBE_ASSERT(x && y && z);
+        reqd_wg_sz[0] = x->getZExtValue();
+        reqd_wg_sz[1] = y->getZExtValue();
+        reqd_wg_sz[2] = z->getZExtValue();
+        break;
+      } else if (attrName->getString() == "kernel_arg_addr_space") {
+        addrSpaceNode = attrNode;
+      } else if (attrName->getString() == "kernel_arg_access_qual") {
+        accessQualNode = attrNode;
+      } else if (attrName->getString() == "kernel_arg_type") {
+        typeNameNode = attrNode;
+      } else if (attrName->getString() == "kernel_arg_type_qual") {
+        typeQualNode = attrNode;
+      } else if (attrName->getString() == "kernel_arg_name") {
+        argNameNode = attrNode;
       }
     }
+
     ctx.getFunction().setCompileWorkGroupSize(reqd_wg_sz[0], reqd_wg_sz[1], reqd_wg_sz[2]);
     // Loop over the arguments and output registers for them
     if (!F.arg_empty()) {
@@ -1132,6 +1158,12 @@ namespace gbe
         const std::string &argName = I->getName().str();
         Type *type = I->getType();
 
+        llvmInfo.addrSpace = (cast<ConstantInt>(addrSpaceNode->getOperand(1 + argID)))->getZExtValue();
+        llvmInfo.typeName = (cast<MDString>(typeNameNode->getOperand(1 + argID)))->getString();
+        llvmInfo.accessQual = (cast<MDString>(accessQualNode->getOperand(1 + argID)))->getString();
+        llvmInfo.typeQual = (cast<MDString>(typeQualNode->getOperand(1 + argID)))->getString();
+        llvmInfo.argName = (cast<MDString>(argNameNode->getOperand(1 + argID)))->getString();
+
         // function arguments are uniform values.
         this->newRegister(I, NULL, true);
         // add support for vector argument.
@@ -1142,7 +1174,7 @@ namespace gbe
           const uint32_t elemSize = getTypeByteSize(unit, elemType);
           const uint32_t elemNum = vectorType->getNumElements();
           //vector's elemType always scalar type
-          ctx.input(argName, ir::FunctionArgument::VALUE, reg, elemNum*elemSize, getAlignmentByte(unit, type));
+          ctx.input(argName, ir::FunctionArgument::VALUE, reg, llvmInfo, elemNum*elemSize, getAlignmentByte(unit, type));
 
           ir::Function& fn = ctx.getFunction();
           for(uint32_t i=1; i < elemNum; i++) {
@@ -1157,7 +1189,7 @@ namespace gbe
                     "vector type in the function argument is not supported yet");
         const ir::Register reg = getRegister(I);
         if (type->isPointerTy() == false)
-          ctx.input(argName, ir::FunctionArgument::VALUE, reg, getTypeByteSize(unit, type), getAlignmentByte(unit, type));
+          ctx.input(argName, ir::FunctionArgument::VALUE, reg, llvmInfo, getTypeByteSize(unit, type), getAlignmentByte(unit, type));
         else {
           PointerType *pointerType = dyn_cast<PointerType>(type);
           Type *pointed = pointerType->getElementType();
@@ -1168,7 +1200,7 @@ namespace gbe
           if (I->hasByValAttr()) {
 #endif /* LLVM_VERSION_MINOR <= 1 */
             const size_t structSize = getTypeByteSize(unit, pointed);
-            ctx.input(argName, ir::FunctionArgument::STRUCTURE, reg, structSize, getAlignmentByte(unit, type));
+            ctx.input(argName, ir::FunctionArgument::STRUCTURE, reg, llvmInfo, structSize, getAlignmentByte(unit, type));
           }
           // Regular user provided pointer (global, local or constant)
           else {
@@ -1178,17 +1210,17 @@ namespace gbe
             const uint32_t align = getAlignmentByte(unit, pointed);
               switch (addrSpace) {
               case ir::MEM_GLOBAL:
-                ctx.input(argName, ir::FunctionArgument::GLOBAL_POINTER, reg, ptrSize, align);
+                ctx.input(argName, ir::FunctionArgument::GLOBAL_POINTER, reg, llvmInfo, ptrSize, align);
               break;
               case ir::MEM_LOCAL:
-                ctx.input(argName, ir::FunctionArgument::LOCAL_POINTER, reg, ptrSize, align);
+                ctx.input(argName, ir::FunctionArgument::LOCAL_POINTER, reg,  llvmInfo, ptrSize, align);
                 ctx.getFunction().setUseSLM(true);
               break;
               case ir::MEM_CONSTANT:
-                ctx.input(argName, ir::FunctionArgument::CONSTANT_POINTER, reg, ptrSize, align);
+                ctx.input(argName, ir::FunctionArgument::CONSTANT_POINTER, reg,  llvmInfo, ptrSize, align);
               break;
               case ir::IMAGE:
-                ctx.input(argName, ir::FunctionArgument::IMAGE, reg, ptrSize, align);
+                ctx.input(argName, ir::FunctionArgument::IMAGE, reg, llvmInfo, ptrSize, align);
                 ctx.getFunction().getImageSet()->append(reg, &ctx);
               break;
               default: GBE_ASSERT(addrSpace != ir::MEM_PRIVATE);
-- 
1.8.3.2



More information about the Beignet mailing list