确定memset/memcpy指令之前没有AllocaInst的user
局部变量处理
算法:
(1)首先对Function的函数指针参数做标记,函数参数是否在Function内部进行内存操作 。(目前觉得指针传进function,必然会对其memory操作)
(2)其次遍历Alloca的直接、间接的load、store、memset、memcpy操作,记录所在BasicBlock含有内存操作。
(3)最后从当前的memset、memcpy的basicblock内部查看在其之前是否有内存操作标记,如果没有,顺着br指令查看前面是否有内存操作BasicBlock。
全局变量处理
1、调用void getFunctionList(list<Function*> &func_list)
,得到以main为入口函数的function_list,与main无联系的函数则被排除在外(一个缺点)。这个list排列是以遇到CallInst为先后顺序排列。
1、遍历一遍IR,对Function排序:以main为头的Function List。
2、遍历globalvariable的user,标记其所在的Function和BasicBlock。
3、判断memset之前是否存在memory操作。
(1)先看memset的BasicBlock中,其之前指令是否存在memory操作。如果有返回true;
(2)再看memset的function中,所在BasicBlock之前是否存在memory操作。如果有返回true;
(2)最后看memset所在function之前是否存在memory操作。
全局、局部统一处理
bool ProcessMemIntrinsic::InitialMemIntrinsic (Value *inst_dest, Instruction *inst) {
//flag 是memset/memcpy是否需要初始化的标志
bool flag = true;
if (isa<llvm::AllocaInst>(inst_dest)) {
//MarkMemoryAccessOperation will mark all of the memory access operation using by inst_dest(直接或间接的user)
//这是一个递归函数,如果user是一个LoadInst或StoreInst或者callInst(Lifetime的callInst排除在外),都将其所在的BasicBlock加入memory_bb_,
//如果user与memset/memcpy同在一个BasicBlock,还需将user这条指令加入memory_inst_
MarkMemoryAccessOperation(inst_dest, inst->getParent());
assert(memory_func_.size() == 1);
//判断memset/memcpy前面没有inst_dest的memory user
flag = isFirstMemoryInstruction(inst);
} else {
assert(isa<GlobalVariable>(inst_dest));
MarkMemoryAccessOperation(inst_dest, inst->getParent());
flag = isFirstMemoryInstruction(inst);
}
memory_bb_.clear();
memory_inst_.clear();
memory_func_.clear();
return flag;
}
bool ProcessMemIntrinsic::isFirstMemoryInstruction(llvm::Instruction *inst) {
assert(memory_inst_.size() > 0);
// firstly consider in the memset/memcpy's BasicBlock
if (memory_inst_.size() == 1) {
//Just check that only one user(memset/memcpy) of AllocaInst in the BB
auto it = memory_inst_.begin();
Instruction *temp = *it;
assert(temp == inst);
} else {
//遍历这个BasicBlock,判断user是否在memset/memcpy之前。
if (isFirstUserInBasicBlock(inst) == false) {
return false;
}
}
// secondly consider the prev BasicBlock of memset/memcpy's BasicBlock
BasicBlock *mem_bb = inst->getParent();
std::unordered_set<llvm::BasicBlock*> visited;
visited.clear();
visited.insert(mem_bb);
//递归函数,检查mem_bb的前面是否存在user的bb,通过predBB前驱查找,
if (isFirstBasicBlock(mem_bb, visited) == false) {
return false;
}
// thirdly consider the prev function of memset/memcpy's function
if (memory_func_.size() > 1) {
Function *func = inst->getFunction();
for (std::list<Function *>::iterator it = func_list_.begin(); it != func_list_.end(); ++it) {
Function *temp = *it;
if (temp == func) {
return true;
} else {
if (memory_func_.find(temp) != memory_func_.end()) {
return false;
}
}
}
}
return true;
}
memcpy