diff options
Diffstat (limited to 'backend/src')
-rw-r--r-- | backend/src/backend/gen_program_elf.cpp | 47 | ||||
-rw-r--r-- | backend/src/backend/program.hpp | 6 | ||||
-rw-r--r-- | backend/src/ir/printf.hpp | 37 | ||||
-rw-r--r-- | backend/src/llvm/llvm_printf_parser.cpp | 16 |
4 files changed, 95 insertions, 11 deletions
diff --git a/backend/src/backend/gen_program_elf.cpp b/backend/src/backend/gen_program_elf.cpp index 69294281..453bdcb1 100644 --- a/backend/src/backend/gen_program_elf.cpp +++ b/backend/src/backend/gen_program_elf.cpp @@ -214,14 +214,30 @@ using namespace ELFIO; /* The format for Compiler info is: ------------------------------- | GEN_NOTE_TYPE_COMPILER_INFO | - ---------------------------------------- + -------------------------------------- | Compiler name (GBE_Compiler e.g.) | - ---------------------------------------- + -------------------------------------- | LLVM version major:4 | ------------------------ | LLVM version minor:4 | ------------------------ */ +/* The format for printf is: + --------------------------- + | GEN_NOTE_TYPE_CL_PRINTF | + --------------------------- + | The Kernel name | + ------------------------------- + | CL printf bti:4 | + ---------------------- + | CL printf number:4 | + ------------------------------------------- + | CL printf id for one printf statement:4 | + ------------------------------------------- + | printf format string | + ------------------------ + */ + class GenProgramElfContext { public: @@ -232,6 +248,7 @@ public: GEN_NOTE_TYPE_CL_INFO = 4, GEN_NOTE_TYPE_CL_DEVICE_ENQUEUE_INFO = 5, GEN_NOTE_TYPE_COMPILER_INFO = 6, + GEN_NOTE_TYPE_CL_PRINTF = 7, }; struct KernelInfoHelper { @@ -394,6 +411,32 @@ void GenProgramElfContext::emitOneKernelCLInfo(GenKernel &kernel) uint32_t wg_sz_size = 0; uint32_t arg_info_size = 0; + /* Add printf info for this kernel */ + if (kernel.getPrintfNum() != 0) { + std::map<uint32_t, std::string> all_printf; + uint32_t printf_n = kernel.collectPrintfStr(all_printf); + assert(printf_n == kernel.getPrintfNum()); + std::ostringstream oss; + size_t sz = 0; + + uint32_t bti = kernel.getPrintfBufBTI(); + oss.write((char *)(&bti), sizeof(uint32_t)); + sz += sizeof(uint32_t); + oss.write((char *)(&printf_n), sizeof(uint32_t)); + sz += sizeof(uint32_t); + + for (auto iter = all_printf.begin(); iter != all_printf.end(); iter++) { + uint32_t id = iter->first; + oss.write((char *)(&id), sizeof(uint32_t)); + sz += sizeof(uint32_t); + oss.write(iter->second.c_str(), strlen(iter->second.c_str()) + 1); + sz += strlen(iter->second.c_str()) + 1; + } + + this->cl_note_writer->add_note(GenProgramElfContext::GEN_NOTE_TYPE_CL_PRINTF, + kernel.getName(), oss.str().c_str(), sz); + } + if ((kernel.getFunctionAttributes())[0] != 0) attr_size = ::strlen(kernel.getFunctionAttributes()) + 1; all_str_len = ALIGN(attr_size, 4); diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp index 85411b58..62fecf13 100644 --- a/backend/src/backend/program.hpp +++ b/backend/src/backend/program.hpp @@ -168,7 +168,11 @@ namespace gbe { uint32_t getPrintfNum() const { return printfSet ? printfSet->getPrintfNum() : 0; } - + uint32_t collectPrintfStr(std::map<uint32_t, std::string>& all_printf) const { + if (printfSet) + return printfSet->collectPrintfStr(all_printf); + return 0; + } void * dupPrintfSet() const { void* ptr = printfSet ? (void *)(new ir::PrintfSet(*printfSet)) : NULL; return ptr; diff --git a/backend/src/ir/printf.hpp b/backend/src/ir/printf.hpp index 728aa683..28944c71 100644 --- a/backend/src/ir/printf.hpp +++ b/backend/src/ir/printf.hpp @@ -123,7 +123,7 @@ namespace gbe type = PRINTF_SLOT_TYPE_STRING; } - PrintfSlot(PrintfState& st) { + PrintfSlot(PrintfState& st, std::string& s) : str(s) { type = PRINTF_SLOT_TYPE_STATE; state = st; } @@ -135,6 +135,7 @@ namespace gbe } else if (other.type == PRINTF_SLOT_TYPE_STATE) { type = PRINTF_SLOT_TYPE_STATE; state = other.state; + str = other.str; } else { type = PRINTF_SLOT_TYPE_NONE; } @@ -245,6 +246,40 @@ namespace gbe void outputPrintf(void* buf_addr); + uint32_t collectPrintfStr(std::map<uint32_t, std::string>& all_printf) const { + uint32_t n = 0; + for (auto iter = fmts.begin(); iter != fmts.end(); iter++) { + std::string s; + const PrintfFmt& fmt = iter->second; + for (auto &m : fmt) { + if (m.type == PRINTF_SLOT_TYPE_STATE && m.state.conversion_specifier == PRINTF_CONVERSION_S) { + std::string ss = m.state.str; + if (m.state.precision > 0 && (static_cast<size_t>(m.state.precision) < ss.size())) { + ss.resize(m.state.precision); + } + if (m.state.min_width > 0 && (static_cast<size_t>(m.state.min_width) > ss.size())) { + std::string spaces; + spaces.resize(static_cast<size_t>(m.state.min_width) - ss.size(), ' '); + if (m.state.left_justified) { + ss = ss + spaces; + } else { + ss = spaces + ss; + } + } + + s += ss; + } else { + s += m.str; + } + } + + all_printf.insert(std::pair<uint32_t, std::string>(iter->first, s)); + n++; + } + + return n; + } + private: std::map<uint32_t, PrintfFmt> fmts; friend struct LockOutput; diff --git a/backend/src/llvm/llvm_printf_parser.cpp b/backend/src/llvm/llvm_printf_parser.cpp index 6bb7c52a..b8c6114e 100644 --- a/backend/src/llvm/llvm_printf_parser.cpp +++ b/backend/src/llvm/llvm_printf_parser.cpp @@ -245,16 +245,18 @@ again: /* Now parse the % start conversion_specifier. */ ret_char = __parse_printf_state(p, end, &rend, &state); - if (ret_char < 0) + if (ret_char < 0) { goto error; + } else { + std::string s(p, size_t(rend - p)); + printf_fmt->push_back(PrintfSlot(state, s)); + num++; - printf_fmt->push_back(state); - num++; - - if (rend == end) - break; + if (rend == end) + break; - begin = rend; + begin = rend; + } } #if 0 |