将零扩展指令插入基本块

时间:2012-02-23 15:05:57

标签: compiler-construction llvm

我想在基本块中插入零扩展指令和乘法指令。输入是,

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文档之外还有哪些可用的资源?

1 个答案:

答案 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。