Add the support for %s in printf
authorJunyan He <junyan.he@linux.intel.com>
Fri, 20 Jun 2014 09:41:26 +0000 (17:41 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Mon, 23 Jun 2014 02:33:49 +0000 (10:33 +0800)
Signed-off-by: Junyan He <junyan.he@linux.intel.com>
Reviewed-by: Yang Rong <rong.r.yang@intel.com>
backend/src/ir/printf.cpp
backend/src/ir/printf.hpp
backend/src/llvm/llvm_printf_parser.cpp

index d59b990..d919f78 100644 (file)
@@ -98,6 +98,12 @@ namespace gbe
                         PRINT_SOMETHING(float, %f);
                       break;
 
+                    case PRINTF_CONVERSION_S:
+                      pf_str = pf_str + "%s";
+                      printf("%s%s", 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 */
index 1845223..18bdd6e 100644 (file)
@@ -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:
@@ -201,7 +189,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;
         }
index 1b72e82..c99913d 100644 (file)
@@ -221,7 +221,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
@@ -349,7 +349,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";
@@ -472,10 +472,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;
       }
 
@@ -495,7 +502,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++;
     }
@@ -605,7 +612,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);
@@ -619,22 +626,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;
@@ -651,26 +661,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;