summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYan Wang <yan.wang@linux.intel.com>2016-02-01 15:37:49 +0800
committerYang Rong <rong.r.yang@intel.com>2016-04-27 16:17:43 +0800
commit1548feb801b52c525e67206df2f79e06798d7025 (patch)
tree2220329047b424b0b3ad11956e0115bac2be1fe9
parent9c79c05cb3e88adee17943d9e24969d20ab91d2d (diff)
Reconstruct printf parser.
Contributor: Junyan He <junyan.he@linux.intel.com> Signed-off-by: Yan Wang <yan.wang@linux.intel.com> Reviewed-by: Yan Wang <yan.wang@linux.intel.com> Reviewed-by: Junyan He <junyan.he@linux.intel.com>
-rw-r--r--backend/src/ir/unit.cpp1
-rw-r--r--backend/src/ir/unit.hpp3
-rw-r--r--backend/src/llvm/llvm_gen_backend.cpp4
-rw-r--r--backend/src/llvm/llvm_printf_parser.cpp115
4 files changed, 56 insertions, 67 deletions
diff --git a/backend/src/ir/unit.cpp b/backend/src/ir/unit.cpp
index 26d3fb95..a2a1096a 100644
--- a/backend/src/ir/unit.cpp
+++ b/backend/src/ir/unit.cpp
@@ -30,7 +30,6 @@ namespace ir {
Unit::Unit(PointerSize pointerSize) : pointerSize(pointerSize), valid(true) {}
Unit::~Unit(void) {
for (const auto &pair : functions) GBE_DELETE(pair.second);
- for (const auto &pair : printfs) GBE_DELETE(pair.second);
}
Function *Unit::getFunction(const std::string &name) const {
auto it = functions.find(name);
diff --git a/backend/src/ir/unit.hpp b/backend/src/ir/unit.hpp
index b69ba8b4..8d1af704 100644
--- a/backend/src/ir/unit.hpp
+++ b/backend/src/ir/unit.hpp
@@ -91,8 +91,7 @@ namespace ir {
{
public:
typedef map<std::string, Function*> FunctionSet;
- /*! Moved from printf pass */
- map<llvm::CallInst*, PrintfSet::PrintfFmt*> printfs;
+ map<llvm::CallInst*, PrintfSet::PrintfFmt> printfs;
/*! Create an empty unit */
Unit(PointerSize pointerSize = POINTER_32_BITS);
/*! Release everything (*including* the function pointers) */
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index cd586699..2b479ff2 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -751,8 +751,8 @@ namespace gbe
void emitAtomicInstHelper(const ir::AtomicOps opcode,const ir::Type type, const ir::Register dst, llvm::Value* llvmPtr, const ir::Tuple payloadTuple);
void* getPrintfInfo(CallInst* inst)
{
- if (unit.printfs[inst])
- return (void*)unit.printfs[inst];
+ if (&unit.printfs[inst])
+ return (void*)&unit.printfs[inst];
return NULL;
}
private:
diff --git a/backend/src/llvm/llvm_printf_parser.cpp b/backend/src/llvm/llvm_printf_parser.cpp
index 49316881..8fc6e74e 100644
--- a/backend/src/llvm/llvm_printf_parser.cpp
+++ b/backend/src/llvm/llvm_printf_parser.cpp
@@ -293,41 +293,21 @@ error:
public:
static char ID;
typedef std::pair<Instruction*, bool> PrintfInst;
- std::vector<PrintfInst> deadprintfs;
Module* module;
IRBuilder<>* builder;
Type* intTy;
- Value* pbuf_ptr;
- Value* index_buf_ptr;
- Value* g1Xg2Xg3;
- Value* wg_offset;
- int out_buf_sizeof_offset;
ir::Unit &unit;
- int printf_num;
- int totalSizeofSize;
-
- struct PrintfParserInfo {
- llvm::CallInst* call;
- PrintfSet::PrintfFmt* printf_fmt;
- };
PrintfParser(ir::Unit &unit) : FunctionPass(ID),
- unit(unit)
+ unit(unit)
{
module = NULL;
builder = NULL;
intTy = NULL;
- out_buf_sizeof_offset = 0;
- pbuf_ptr = NULL;
- index_buf_ptr = NULL;
- g1Xg2Xg3 = NULL;
- wg_offset = NULL;
- printf_num = 0;
- totalSizeofSize = 0;
}
- bool parseOnePrintfInstruction(CallInst * call, PrintfParserInfo& info, int& sizeof_size);
- bool generateOneParameterInst(PrintfSlot& slot, Value*& arg, Type*& dst_type, int& sizeof_size);
+ bool parseOnePrintfInstruction(CallInst * call);
+ bool generateOneParameterInst(PrintfSlot& slot, Value* arg, Value*& new_arg);
virtual const char *getPassName() const
{
@@ -337,7 +317,7 @@ error:
virtual bool runOnFunction(llvm::Function &F);
};
- bool PrintfParser::parseOnePrintfInstruction(CallInst * call, PrintfParserInfo& info, int& sizeof_size)
+ bool PrintfParser::parseOnePrintfInstruction(CallInst * call)
{
CallSite CS(call);
CallSite::arg_iterator CI_FMT = CS.arg_begin();
@@ -355,20 +335,50 @@ error:
}
std::string fmt = fmt_arg->getAsCString();
+ if (fmt.size() == 0)
+ return false;
PrintfSet::PrintfFmt* printf_fmt = NULL;
if (!(printf_fmt = parser_printf_fmt((char *)fmt.c_str(), param_num))) {//at lease print something
+ printf("Warning: Parse the printf inst %s failed, no output for it\n", fmt.c_str());
return false;
}
/* iff parameter more than %, error. */
/* str_fmt arg0 arg1 ... NULL */
- if (param_num + 2 < static_cast<int>(call->getNumOperands())) {
+ if (param_num + 2 != static_cast<int>(call->getNumOperands())) {
delete printf_fmt;
+ printf("Warning: Parse the printf inst %s failed, parameters do not match the %% number, no output for it\n",
+ fmt.c_str());
return false;
}
+ /* Insert some conversion if types do not match. */
+ builder->SetInsertPoint(call);
+ int i = 1;
+ for (auto &s : *printf_fmt) {
+ if (s.type == PRINTF_SLOT_TYPE_STRING)
+ continue;
+
+ assert(i < static_cast<int>(call->getNumOperands()) - 1);
+ Value* new_arg = NULL;
+ Value *arg = call->getOperand(i);
+ if (generateOneParameterInst(s, arg, new_arg) == false) {
+ delete printf_fmt;
+ printf("Warning: Parse the printf inst %s failed, the %d parameter format is wrong, no output for it\n",
+ fmt.c_str(), i);
+ return false;
+ }
+
+ if (new_arg) { // replace the according argument.
+ call->setArgOperand(i, new_arg);
+ }
+ ++i;
+ }
+
+ GBE_ASSERT(unit.printfs.find(call) == unit.printfs.end());
+ unit.printfs.insert(std::pair<llvm::CallInst*, PrintfSet::PrintfFmt>(call, *printf_fmt));
return true;
}
@@ -429,14 +439,20 @@ error:
if (fnName != "__gen_ocl_printf_stub" && fnName != "__gen_ocl_puts_stub")
continue;
+ if (!parseOnePrintfInstruction(call)) {
+ // Just skip this printf instruction.
+ continue;
+ }
+
hasPrintf = true;
}
}
+ delete builder;
return hasPrintf;
}
- bool PrintfParser::generateOneParameterInst(PrintfSlot& slot, Value*& arg, Type*& dst_type, int& sizeof_size)
+ bool PrintfParser::generateOneParameterInst(PrintfSlot& slot, Value* arg, Value*& new_arg)
{
assert(slot.type == PRINTF_SLOT_TYPE_STATE);
assert(builder);
@@ -456,27 +472,19 @@ error:
case PRINTF_CONVERSION_X:
if (slot.state.length_modifier == PRINTF_LM_L) { /* we would rather print long. */
if (arg->getType() != Type::getInt64Ty(module->getContext())) {
- arg = builder->CreateIntCast(arg, Type::getInt64Ty(module->getContext()), sign);
+ new_arg = builder->CreateIntCast(arg, Type::getInt64Ty(module->getContext()), sign);
}
- dst_type = Type::getInt64PtrTy(module->getContext(), 1);
- sizeof_size = sizeof(int64_t);
} else {
/* If the bits change, we need to consider the signed. */
if (arg->getType() != Type::getInt32Ty(module->getContext())) {
- arg = builder->CreateIntCast(arg, Type::getInt32Ty(module->getContext()), sign);
+ new_arg = builder->CreateIntCast(arg, Type::getInt32Ty(module->getContext()), sign);
}
-
- /* Int to Int, just store. */
- dst_type = Type::getInt32PtrTy(module->getContext(), 1);
- 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);
- sizeof_size = sizeof(char);
+ new_arg = builder->CreateIntCast(arg, Type::getInt8Ty(module->getContext()), false);
return true;
case PRINTF_CONVERSION_F:
@@ -488,14 +496,11 @@ error:
case PRINTF_CONVERSION_A:
case PRINTF_CONVERSION_a:
printf("Warning: Have a float parameter for %%d like specifier, take care of it\n");
- arg = builder->CreateSIToFP(arg, Type::getFloatTy(module->getContext()));
- dst_type = Type::getFloatPtrTy(module->getContext(), 1);
- sizeof_size = sizeof(float);
+ new_arg = builder->CreateSIToFP(arg, Type::getFloatTy(module->getContext()));
return true;
case PRINTF_CONVERSION_S:
/* Here, the case is printf("xxx%s", 0); we should output the null. */
- sizeof_size = 0;
slot.state.str = "(null)";
return true;
@@ -511,7 +516,7 @@ error:
/* llvm 3.6 will give a undef value for NAN. */
if (dyn_cast<llvm::UndefValue>(arg)) {
APFloat nan = APFloat::getNaN(APFloat::IEEEsingle, false);
- arg = ConstantFP::get(module->getContext(), nan);
+ new_arg = ConstantFP::get(module->getContext(), nan);
}
/* Because the printf is a variable parameter function, it does not have the
@@ -522,9 +527,7 @@ error:
case PRINTF_CONVERSION_D:
/* Float to Int, add a conversion. */
printf("Warning: Have a int parameter for %%f like specifier, take care of it\n");
- arg = builder->CreateFPToSI(arg, Type::getInt32Ty(module->getContext()));
- dst_type = Type::getInt32PtrTy(module->getContext(), 1);
- sizeof_size = sizeof(int);
+ new_arg = builder->CreateFPToSI(arg, Type::getInt32Ty(module->getContext()));
return true;
case PRINTF_CONVERSION_O:
@@ -533,9 +536,7 @@ error:
case PRINTF_CONVERSION_X:
/* Float to uint, add a conversion. */
printf("Warning: Have a uint parameter for %%f like specifier, take care of it\n");
- arg = builder->CreateFPToUI(arg, Type::getInt32Ty(module->getContext()));
- dst_type = Type::getInt32PtrTy(module->getContext(), 1);
- sizeof_size = sizeof(int);
+ new_arg = builder->CreateFPToUI(arg, Type::getInt32Ty(module->getContext()));
return true;
case PRINTF_CONVERSION_F:
@@ -546,9 +547,7 @@ error:
case PRINTF_CONVERSION_g:
case PRINTF_CONVERSION_A:
case PRINTF_CONVERSION_a:
- arg = builder->CreateFPCast(arg, Type::getFloatTy(module->getContext()));
- dst_type = Type::getFloatPtrTy(module->getContext(), 1);
- sizeof_size = sizeof(float);
+ new_arg = builder->CreateFPCast(arg, Type::getFloatTy(module->getContext()));
return true;
default:
@@ -572,14 +571,11 @@ error:
if (!fmt_arg || !fmt_arg->isCString()) {
return false;
}
- sizeof_size = 0;
slot.state.str = fmt_arg->getAsCString();
return true;
}
case PRINTF_CONVERSION_P: {
- arg = builder->CreatePtrToInt(arg, Type::getInt32Ty(module->getContext()));
- dst_type = arg->getType()->getPointerTo(1);
- sizeof_size = sizeof(int);
+ new_arg = builder->CreatePtrToInt(arg, Type::getInt32Ty(module->getContext()));
return true;
}
default:
@@ -629,12 +625,9 @@ error:
Value *cvt = builder->CreateIntCast(org, elt_dst_type, sign);
II = builder->CreateInsertElement(vec, cvt, cv);
}
- arg = II;
+ new_arg = II;
}
- dst_type = arg->getType()->getPointerTo(1);
- sizeof_size = (elt_dst_type == Type::getInt32Ty(elt_type->getContext()) ?
- sizeof(int) * vec_num : sizeof(int64_t) * vec_num);
return true;
}
@@ -660,11 +653,9 @@ error:
Value* cvt = builder->CreateFPCast(org, Type::getFloatTy(module->getContext()));
II = builder->CreateInsertElement(vec, cvt, cv);
}
- arg = II;
+ new_arg = II;
}
- dst_type = arg->getType()->getPointerTo(1);
- sizeof_size = sizeof(int) * vec_num;
return true;
default: