[Beignet] [PATCH 3/4 V2] Add the support for %s in printf
junyan.he at inbox.com
junyan.he at inbox.com
Fri Jun 20 02:41:26 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 +++++++++++++++++++++++++--------
3 files changed, 70 insertions(+), 42 deletions(-)
diff --git a/backend/src/ir/printf.cpp b/backend/src/ir/printf.cpp
index d59b990..d919f78 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("%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 */
diff --git a/backend/src/ir/printf.hpp b/backend/src/ir/printf.hpp
index 1845223..18bdd6e 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:
@@ -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;
}
diff --git a/backend/src/llvm/llvm_printf_parser.cpp b/backend/src/llvm/llvm_printf_parser.cpp
index 1b72e82..c99913d 100644
--- a/backend/src/llvm/llvm_printf_parser.cpp
+++ b/backend/src/llvm/llvm_printf_parser.cpp
@@ -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;
--
1.8.3.2
More information about the Beignet
mailing list