我想要实现的目标:在LLVM IR中用i64
替换i32
的每一次出现。
最初我用块传递尝试了这个。块传递适用于函数体,但不适用于函数声明和全局变量。然后我切换到使用模块传递,在每个LLVM指令上执行以下操作:
void substitute(llvm::Instruction& inst)
{
inst.mutateType(cast(inst.getType()));
if (llvm::CallInst* ci = dynamic_cast<llvm::CallInst*>(&inst)))
{
llvm::Function* func = ci->getCalledFunction();
func->mutateTYpe(cast(func->getType()));
ci->setCalledFunction(func);
}
const int nops = inst.getNumOperands();
for (int i = 0; i < nops; ++i)
{
llvm::Value* const v = inst.getOperand(i);
llvm::Type* const tsrc = v->getType();
llvm::Type* const tdst = cast(tsrc);
v->mutateType(tdst);
}
cast
函数通过使用 Type::get
构建新类型,递归地将类型转换为另一种类型。
我尝试使用地图来缓存已创建的类型,但仍会创建大量类型别名,并且模块链接上的不兼容性仍然存在。
但是,这会产生大量类型别名,并且相同结构的类型别名不兼容。例如,如果%18
和%28
属于同一类型,则返回类型为%18
的函数无法返回%28
。
我还读到mutateType
是一个危险的操作。有更安全的选择吗?