我想知道真实寄存器中的变量依赖性(如 X86:EAX、EBX ...)。因此,我创建了一个 IR-PASS,可以识别对 IR 的依赖关系。此传递使用新添加的变量和unsigned HasDependency: 1;
类。unsigned HasMaybeDependency: 1;
Value
.
.
// Use the same type as the bitfield above so that MSVC will pack them.
unsigned IsUsedByMD : 1;
unsigned HasName : 1;
unsigned HasHungOffUses : 1;
unsigned HasDescriptor : 1;
unsigned HasDependency : 1;
unsigned HasMaybeDependency : 1;
.
.
.
void setDependency() { HasDependency = true; }
void setMaybeDependency() { HasMaybeDependency = true; }
bool hasDependency() const { return HasDependency; }
bool hasMaybeDependency() const { return HasMaybeDependency; }
//static_assert(sizeof(Value) == 2 * sizeof(void *) + 2 * sizeof(unsigned),
// "Value too big");
当应用于这样的代码片段时:
extern int foo_called(int a);
int foo(int k)
{
int __attribute__((annotate("xxx"))) a;
for (int i = 0; i < k; i++)
{
int c = a + k;
a += foo_called(c);
}
return 0;
}
产生这个位码:
define i32 @"\01?foo@@YAHH@Z"(i32 %k) local_unnamed_addr #0 {
entry:
%a = alloca i32, align 4
%0 = bitcast i32* %a to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #2
call void @llvm.var.annotation(i8* nonnull %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 17)
%cmp7 = icmp sgt i32 %k, 0
br i1 %cmp7, label %for.body.lr.ph, label %for.cond.cleanup
for.body.lr.ph: ; preds = %entry
%.pre = load i32, i32* %a, align 4, !tbaa !3
br label %for.body
for.cond.cleanup: ; preds = %for.body, %entry
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #2
ret i32 0
for.body: ; preds = %for.body, %for.body.lr.ph
%1 = phi i32 [ %.pre, %for.body.lr.ph ], [ %add2, %for.body ]
%i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
%add = add nsw i32 %1, %k
%call = call i32 @"\01?foo_called@@YAHH@Z"(i32 %add)
%2 = load i32, i32* %a, align 4, !tbaa !3
%add2 = add nsw i32 %2, %call
store i32 %add2, i32* %a, align 4, !tbaa !3
%inc = add nuw nsw i32 %i.08, 1
%exitcond = icmp eq i32 %inc, %k
br i1 %exitcond, label %for.cond.cleanup, label %for.body
}
declare i32 @"\01?foo_called@@YAHH@Z"(i32) local_unnamed_addr #3
上述位码的传递结果是:
Function - ?foo@@YAHH@Z
Annotated Variable List :
- Annotated : a(message: xxx)
Annotated-Variable : a
(Perpect) %add2 = add nsw i32 %2, %call
(Perpect) %2 = load i32, i32* %a, align 4, !tbaa !3
(Perpect) %a = alloca i32, align 4
(Perpect) %cmp7 = icmp sgt i32 %k, 0
(Maybe) %exitcond = icmp eq i32 %inc, %k
(Maybe) %inc = add nuw nsw i32 %i.08, 1
(Maybe) %i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
(Perpect) %call = call i32 @"\01?foo_called@@YAHH@Z"(i32 %add)
(Perpect) %add = add nsw i32 %1, %k
(Perpect) %1 = phi i32 [ %.pre, %for.body.lr.ph ], [ %add2, %for.body ]
(Perpect) %.pre = load i32, i32* %a, align 4, !tbaa !3
我按照该SelectionDAGISel.cpp: SelectAllBasicBlocks
函数从后端获取信息,但我只能获取AllocaInst
,StoreInst
和LoadInst
using ,如下所示:
for (MachineBasicBlock &MBB : mf) {
for (MachineInstr& I : MBB) {
for (MachineInstr::mmo_iterator i = I.memoperands_begin(),
e = I.memoperands_end();
i != e; ++i) {
if (const Value *V = (*i)->getValue())
errs() << *V << "\n";
}
}
}
我怎么知道 和 之间的相关MachineInstr
性Instruction
?如果 LLVM 中没有提供,需要修复哪些部分?