[Beignet] [PATCH] Add the support for %s in printf

junyan.he at inbox.com junyan.he at inbox.com
Wed Jun 18 01:55: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/ir/printf.cpp               |  8 ++++-
 backend/src/ir/printf.hpp               | 42 +++++++++-------------
 backend/src/llvm/llvm_printf_parser.cpp | 62 +++++++++++++++++++++++++--------
 kernels/test_printf.cl                  |  2 +-
 4 files changed, 71 insertions(+), 43 deletions(-)

diff --git a/backend/src/ir/printf.cpp b/backend/src/ir/printf.cpp
index 4bd7f2d..2879510 100644
--- a/backend/src/ir/printf.cpp
+++ b/backend/src/ir/printf.cpp
@@ -98,6 +98,12 @@ namespace gbe
                         PRINT_SOMETHING(float, %f);
                       break;
 
+                    case PRINTF_CONVERSION_S:
+                      pf_str = pf_str + "%s";
+                      printf(pf_str.c_str(), slot.state->str.c_str());
+                      pf_str = "";
+                      break;
+
                     default:
                       assert(0);
                       return;
@@ -111,7 +117,7 @@ namespace gbe
             }
           }
         }
-	stmt++;
+        stmt++;
       }
     }
   } /* namespace ir */
diff --git a/backend/src/ir/printf.hpp b/backend/src/ir/printf.hpp
index 7e8027c..0550731 100644
--- a/backend/src/ir/printf.hpp
+++ b/backend/src/ir/printf.hpp
@@ -73,6 +73,7 @@ namespace gbe
       int length_modifier;
       char conversion_specifier;
       int out_buf_sizeof_offset;  // Should *global_total_size to get the full offset.
+      std::string str;            //if %s, the string store here.
     };
 
     enum {
@@ -89,14 +90,12 @@ namespace gbe
         void *ptr;
       };
 
-      PrintfSlot(void)
-      {
+      PrintfSlot(void) {
         type = PRINTF_SLOT_TYPE_NONE;
         ptr = NULL;
       }
 
-      PrintfSlot(const char * s)
-      {
+      PrintfSlot(const char * s) {
         type = PRINTF_SLOT_TYPE_STRING;
         int len = strlen(s);
         str = (char*)malloc((len + 1) * sizeof(char));
@@ -104,15 +103,13 @@ namespace gbe
         str[len] = 0;
       }
 
-      PrintfSlot(PrintfState * st)
-      {
+      PrintfSlot(PrintfState * st) {
         type = PRINTF_SLOT_TYPE_STATE;
         state = (PrintfState *)malloc(sizeof(PrintfState));
         memcpy(state, st, sizeof(PrintfState));
       }
 
-      PrintfSlot(const PrintfSlot & other)
-      {
+      PrintfSlot(const PrintfSlot & other) {
         if (other.type == PRINTF_SLOT_TYPE_STRING) {
           int len = strlen(other.str);
           str = (char*)malloc((len + 1) * sizeof(char));
@@ -129,17 +126,14 @@ namespace gbe
         }
       }
 
-      PrintfSlot(PrintfSlot && other)
-      {
+      PrintfSlot(PrintfSlot && other) {
         void *p = other.ptr;
         type = other.type;
         other.ptr = ptr;
         ptr = p;
-
       }
 
-      ~PrintfSlot(void)
-      {
+      ~PrintfSlot(void) {
         if (ptr)
           free(ptr);
       }
@@ -150,8 +144,7 @@ namespace gbe
     class PrintfSet //: public Serializable
     {
     public:
-      PrintfSet(const PrintfSet& other)
-      {
+      PrintfSet(const PrintfSet& other) {
         for (auto &f : other.fmts) {
           fmts.push_back(f);
         }
@@ -166,13 +159,11 @@ namespace gbe
       PrintfSet(void) = default;
 
       struct LockOutput {
-        LockOutput(void)
-        {
+        LockOutput(void) {
           pthread_mutex_lock(&lock);
         }
 
-        ~LockOutput(void)
-        {
+        ~LockOutput(void) {
           pthread_mutex_unlock(&lock);
         }
       };
@@ -180,18 +171,15 @@ namespace gbe
       typedef vector<PrintfSlot> PrintfFmt;
       uint32_t append(PrintfFmt* fmt, Unit &unit);
 
-      uint32_t getPrintfNum(void) const
-      {
+      uint32_t getPrintfNum(void) const {
         return fmts.size();
       }
 
-      uint32_t getPrintfSizeOfSize(void) const
-      {
+      uint32_t getPrintfSizeOfSize(void) const {
         return sizeOfSize;
       }
 
-      uint32_t getPrintfBufferElementSize(uint32_t i)
-      {
+      uint32_t getPrintfBufferElementSize(uint32_t i) {
         PrintfSlot* slot = slots[i];
         switch (slot->state->conversion_specifier) {
           case PRINTF_CONVERSION_I:
@@ -200,7 +188,9 @@ namespace gbe
             return (uint32_t)sizeof(int);
           case PRINTF_CONVERSION_F:
           case PRINTF_CONVERSION_f:
-		  return (uint32_t)sizeof(float);
+            return (uint32_t)sizeof(float);
+          case PRINTF_CONVERSION_S:
+            return (uint32_t)0;
           default:
             break;
         }
diff --git a/backend/src/llvm/llvm_printf_parser.cpp b/backend/src/llvm/llvm_printf_parser.cpp
index 2ea72d9..bd5cd3e 100644
--- a/backend/src/llvm/llvm_printf_parser.cpp
+++ b/backend/src/llvm/llvm_printf_parser.cpp
@@ -214,7 +214,7 @@ namespace gbe
         CONVERSION_SPEC_AND_RET('a', a)
         CONVERSION_SPEC_AND_RET('A', A)
         CONVERSION_SPEC_AND_RET('c', C)
-        CONVERSION_SPEC_AND_RET('s', A)
+        CONVERSION_SPEC_AND_RET('s', S)
         CONVERSION_SPEC_AND_RET('p', P)
 
         // %% has been handled
@@ -342,7 +342,7 @@ error:
 
 
     bool parseOnePrintfInstruction(CallInst *& call);
-    int generateOneParameterInst(PrintfSlot& slot, Value*& arg, Type*& dst_type);
+    bool generateOneParameterInst(PrintfSlot& slot, Value*& arg, Type*& dst_type, int& sizeof_size);
 
     virtual const char *getPassName() const {
       return "Printf Parser";
@@ -465,10 +465,17 @@ error:
 
       Value *out_arg = call->getOperand(i);
       Type *dst_type = NULL;
-      int sizeof_size = generateOneParameterInst(s, out_arg, dst_type);
-      if (!sizeof_size) {
+      int sizeof_size = 0;
+      if (!generateOneParameterInst(s, out_arg, dst_type, sizeof_size)) {
         printf("Printf: %d, parameter %d may have no result because some error\n",
                printf_num, i - 1);
+        i++;
+        continue;
+      }
+
+      s.state->out_buf_sizeof_offset = out_buf_sizeof_offset;
+      if (!sizeof_size) {
+        i++;
         continue;
       }
 
@@ -488,7 +495,7 @@ error:
       op0 = builder->CreateAdd(op0, val);
       data_addr = builder->CreateIntToPtr(op0, dst_type);
       builder->CreateStore(out_arg, data_addr);
-      s.state->out_buf_sizeof_offset = out_buf_sizeof_offset;
+
       out_buf_sizeof_offset += ((sizeof_size + 3) / 4) * 4;
       i++;
     }
@@ -598,7 +605,7 @@ error:
     return changed;
   }
 
-  int PrintfParser::generateOneParameterInst(PrintfSlot& slot, Value*& arg, Type*& dst_type)
+  bool PrintfParser::generateOneParameterInst(PrintfSlot& slot, Value*& arg, Type*& dst_type, int& sizeof_size)
   {
     assert(slot.type == PRINTF_SLOT_TYPE_STATE);
     assert(builder);
@@ -612,22 +619,25 @@ error:
           case PRINTF_CONVERSION_D:
             /* Int to Int, just store. */
             dst_type = Type::getInt32PtrTy(module->getContext(), 1);
-            return sizeof(int);
+            sizeof_size = sizeof(int);
+            return true;
 
           case PRINTF_CONVERSION_C:
             /* Int to Char, add a conversion. */
             arg = builder->CreateIntCast(arg, Type::getInt8Ty(module->getContext()), false);
             dst_type = Type::getInt8PtrTy(module->getContext(), 1);
-            return sizeof(char);
+            sizeof_size = sizeof(char);
+            return true;
 
           case PRINTF_CONVERSION_F:
           case PRINTF_CONVERSION_f:
             arg = builder->CreateSIToFP(arg, Type::getFloatTy(module->getContext()));
             dst_type = Type::getFloatPtrTy(module->getContext(), 1);
-            return sizeof(float);
+            sizeof_size = sizeof(float);
+            return true;
 
           default:
-            return 0;
+            return false;
         }
 
         break;
@@ -644,26 +654,48 @@ error:
             /* Float to Int, add a conversion. */
             arg = builder->CreateFPToSI(arg, Type::getInt32Ty(module->getContext()));
             dst_type = Type::getInt32PtrTy(module->getContext(), 1);
-            return sizeof(int);
+            sizeof_size = sizeof(int);
+            return true;
 
           case PRINTF_CONVERSION_F:
           case PRINTF_CONVERSION_f:
             arg = builder->CreateFPCast(arg, Type::getFloatTy(module->getContext()));
             dst_type = Type::getFloatPtrTy(module->getContext(), 1);
-            return sizeof(float);
+            sizeof_size = sizeof(float);
+            return true;
 
           default:
-            return 0;
+            return false;
         }
 
         break;
       }
 
+      /* %p and %s */
+      case Type::PointerTyID:
+        switch (slot.state->conversion_specifier) {
+          case PRINTF_CONVERSION_S: {
+            llvm::Constant* arg0 = dyn_cast<llvm::ConstantExpr>(arg);
+            llvm::Constant* arg0_ptr = dyn_cast<llvm::Constant>(arg0->getOperand(0));
+            if (!arg0_ptr) {
+              return false;
+            }
+
+            ConstantDataSequential* fmt_arg = dyn_cast<ConstantDataSequential>(arg0_ptr->getOperand(0));
+            if (!fmt_arg || !fmt_arg->isCString()) {
+              return false;
+            }
+            sizeof_size = 0;
+            slot.state->str = fmt_arg->getAsCString();
+            return true;
+          }
+        }
+
       default:
-        return 0;
+        return false;
     }
 
-    return 0;
+    return false;
   }
 
   map<CallInst*, PrintfSet::PrintfFmt*> PrintfParser::printfs;
diff --git a/kernels/test_printf.cl b/kernels/test_printf.cl
index 1629b37..9ed8fbb 100644
--- a/kernels/test_printf.cl
+++ b/kernels/test_printf.cl
@@ -8,7 +8,7 @@ test_printf(void)
   float f = 5.0;
 
   if (x == 0 && y == 0 && z == 0) {
-    printf("--- Welcome to the printf test ---\n");
+    printf("--- Welcome to the printf test of %s ---\n", "Intel Beignet");
 
     printf("### output a char is %c\n", a);
   }
-- 
1.8.3.2



More information about the Beignet mailing list