我想知道如何在LLVM中获得GetElementInst
或AllocaInst
的左值。
IR如下:
%b15 = **getelementptr** inbounds %class.M* %c, i32 0, i32 2
%b16 = getelementptr inbounds %class.B* %b15, i32 0, i32 1
%6 = **load** i32* %b16, align 4
%add17 = add nsw i32 %6, 10
%b18 = getelementptr inbounds %class.M* %c, i32 0, i32 2
%b19 = getelementptr inbounds %class.B* %b18, i32 0, i32 1
我需要分析IR。我想知道是否有任何方法可以获得GetElementInst
,AllocaInst
或LoadIns
的左值,因为我必须分析所有寄存器值之间的关系。
希望得到你的帮助!
实际上我想跟踪所有对象的存储计数和负载计数。
为此,我遍历所有说明以获得负载&储存信息。但在作为关注者的LLVM IR中,前3条指令仅表示%class.M* %c
的加载操作。
简而言之,对于GetElementPtrInst
这样的%b16 = getelementptr inbounds %class.B* %b15, i32 0, i32 1
,我想得出%b16
属于%b15
的结论。
%b15 = getelementptr inbounds %class.M* %c, i32 0, i32 2
%b16 = getelementptr inbounds %class.B* %b15, i32 0, i32 1
%6 = load i32* %b16, align 4
%add17 = add nsw i32 %6, 10
%b18 = getelementptr inbounds %class.M* %c, i32 0, i32 2
%b19 = getelementptr inbounds %class.B* %b18, i32 0, i32 1
我遍历所有说明的功能:
virtual bool runOnFunction(Function &F) {
//errs() << "Begin" << "\n";
errs() << F.getName() << "\n";
char OpName[256];
char OpType[256];
for (auto &BB : F) {
for (auto &I : BB) {
/* if (auto *op = dyn_cast<AllocaInst>(&I)) {
errs() << "allocaInst" << "\n";
Value *OpV = I.getOperand(1);
strcpy(OpName, OpV->getName().str().c_str());
//get operand type
auto *type = I.getAllocatedType();
std::string typestring;
raw_string_ostream S(typestring);
type->print(S);
S.flush();
strcpy(OpType, typestring.c_str());
createCallForParameterLine(op, 1, OpName, OpType, OpV);
}
else*/ if (auto *op = dyn_cast<StoreInst>(&I)) {
errs() << "storeInst" << "\n";
Value *OpV = I.getOperand(1);
if (OpV->hasName() /*&& OpV->getType()->getTypeID() == 14*/) {
strcpy(OpName, OpV->getName().str().c_str());
//get operand type
auto *type = OpV->getType();
std::string typestring;
raw_string_ostream S(typestring);
type->print(S);
type->print(errs());
S.flush();
strcpy(OpType, typestring.c_str());
createCallForParameterLine(op, 1, OpName, OpType, OpV);
}
}
else if (auto *op = dyn_cast<LoadInst>(&I)) {
errs() << "loadInst" << "\n";
Value *OpV = I.getOperand(0);
if (OpV->hasName() /*&& OpV->getType()->getTypeID() == 14*/) {
strcpy(OpName, OpV->getName().str().c_str());
//get operand type
auto *type = OpV->getType();
std::string typestring;
raw_string_ostream S(typestring);
type->print(S);
S.flush();
strcpy(OpType, typestring.c_str());
createCallForParameterLine(op, 2, OpName, OpType, OpV);
}
}
}
}
}
答案 0 :(得分:0)
[已编辑以更好地匹配OP&#39;问题强>
只需在指令的基础getOperand(0)
上调用User
,就可以获得任何指令的操作数。
在具体说明中,例如LoadInst
或GetElementPtrInst
,您有许多其他方法,例如getPointerOperand
。
这些方法在llvm代码库中的Instructions.h中声明。
无论如何,这将返回Value
,您可以使用该过程。
例如,on:
%b16 = getelementptr inbounds %class.B* %b15, i32 0, i32 1
inst-&gt; getPointerOperand将返回%b15。如果你需要%b16,它只是你正在处理的价值。
以下是尝试执行您想要的代码的示例 [未经测试] :
std::map<Value*, Value*> result;
for(auto &BB: F)
{
for(auto &I: BB)
{
switch(I.getOpcode()) {
case Instruction::GetElementPtr:
llvm::GetElementPtrInst* gep = llvm::dyn_cast<GetElementPtrInst>(&I);
result.insert(std::pair<Value*, Value*>(&I, gep->getPointerOperand());
break;
//.. TODO other cases
}
}
}
然后您可以处理依赖关系图以适当地显示名称。
希望这会有所帮助。