我想在基本块中插入零扩展指令和乘法指令。输入是,
define void @DriverInit() {
EntryBlock:
%abc = call i32 @cuInit(i32 0)
ret void
}
我想将其转换为
define void @DriverInit() {
EntryBlock:
%abc = call i32 @cuInit(i32 0)
%2 = zext i32 1 to i64
%3 = mul i64 %2, ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
ret void
}
如何使用LLVM C ++ API执行此操作?我使用下面的代码来创建零扩展指令,但我无法做到。
IRBuilder<> builder(BB);
Value *One = builder.getInt32(1);
Value *zer=builder.CreateZExt(One, IntegerType::getInt64Ty(M.getContext()),"1");
CreateZExt的第二个参数是我想要零扩展的目标类型,如果我错了,请纠正我。
我是LLVM的初学者,并且很难获得有关在传递中使用哪些函数的信息。除了源代码的doxygen文档之外还有哪些可用的资源?
答案 0 :(得分:1)
一旦您对LLVM有一些经验,您就知道在代码中查找的位置。 直到您获得了这种体验,您可以使用C ++后端为您生成与给定IR相当的API调用。
这样做的一种方法是使用C ++后端使用llc
编译IR。例如,我采用这种简化的IR:
define void @DriverInit() {
EntryBlock:
%0 = zext i32 1 to i64
%1 = mul i64 %0, ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
ret void
}
将其保存到名为z.ll
的文件并运行:
llc -march=cpp -O0 -cppgen=program z.ll
您需要在某处安装或构建LLVM才能访问llc
。它生成z.cpp
,它具有C ++ API调用以创建整个模块。 EntryBlock
基本块的相关部分是:
// Function: DriverInit (func_DriverInit)
{
BasicBlock* label_EntryBlock = BasicBlock::Create(mod->getContext(), "EntryBlock",func_DriverInit,0);
// Block EntryBlock (label_EntryBlock)
CastInst* int64_6 = new ZExtInst(const_int32_1, IntegerType::get(mod->getContext(), 64), "", label_EntryBlock);
BinaryOperator* int64_7 = BinaryOperator::Create(Instruction::Mul, int64_6, const_int64_2, "", label_EntryBlock);
ReturnInst::Create(mod->getContext(), label_EntryBlock);
}
您可以在其中查看如何使用zExtInstr
构造函数以及稍后BinaryOperator::Create
正确调用来生成该IR。