我实现了一个函数传递,它迭代基本块指令并跟踪所有具有 IntegerTy 类型的指令。
这是执行此操作的通行证片段:
if (!I->isTerminator()){
Type::TypeID datatype = I->getType()->getTypeID();
if (datatype == llvm::Type::IntegerTyID) {
IRBuilder<> IRB(I);
Value* v_value = IRB.CreateZExt(I, IRB.getInt64Ty());
Value *args[] = {v_value};
IRB.CreateCall(NNT_log_int, args);
}
}
然而IRB.CreateZExt(I, IRB.getInt64Ty()); 命令似乎创建了一个指令并不能支配所有用途!问题。
我的困惑点是我将此传递应用于没有if语句或任何其他控制流语句的玩具程序,但我仍然遇到这个问题。
错误信息:
Instruction does not dominate all uses!
%2 = load i32, i32* %y, align 4
%1 = zext i32 %2 to i64
Instruction does not dominate all uses!
%4 = load i32, i32* %y, align 4
%3 = zext i32 %4 to i64
请注意,插入的zext指令命名了一个计数器编号小于前一条指令的常量 - 我认为这是问题所在,但我不知道为什么我的 pass 会这样做!!!
这是我的玩具程序在申请通行证之前的 IR:
; Function Attrs: noinline nounwind optnone uwtable
define i32 @_Z3fooi(i32 %x) #4 {
entry:
%x.addr = alloca i32, align 4
%y = alloca i32, align 4
%z = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
store i32 0, i32* %y, align 4
%0 = load i32, i32* %x.addr, align 4
%add = add nsw i32 %0, 3
store i32 %add, i32* %y, align 4
%1 = load i32, i32* %y, align 4
store i32 %1, i32* %x.addr, align 4
%2 = load i32, i32* %y, align 4
ret i32 %2
}
; Function Attrs: noinline nounwind optnone uwtable
define i32 @_Z3bari(i32 %panos) #4 {
entry:
%panos.addr = alloca i32, align 4
%y = alloca i32, align 4
store i32 %panos, i32* %panos.addr, align 4
%0 = load i32, i32* %panos.addr, align 4
%add = add nsw i32 %0, 2
store i32 %add, i32* %y, align 4
%1 = load i32, i32* %y, align 4
ret i32 %1
}
另外,请注意有问题的指令在终止符之前 - 我再次认为这是相关的。
任何想法将不胜感激!