2012-02-23 44 views
1

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

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

我不明白你的问题 - 你能澄清吗?您有什么输入IR,以及您想要创建的输出是什么?在'mul'的第二个参数中做了什么指针咒语? – 2012-02-24 21:30:46

+0

如果你已经在输入函数中有EntryBlock,你为什么要创建一个basicblock? – CAFxX 2012-02-25 08:06:13

+0

此外,如果你在展示你所做的(错误的)方式之前,实际解释了你想要完成的事情,这可能会有所帮助。 – CAFxX 2012-02-25 08:07:23

回答

1

一旦你有了LLVM的一些经验,你就知道在代码中看什么。 直到您获得了这种体验,您可以使用C++后端为您生成等效于给定IR的API调用。

一种方法是使用C++后端编译IR,使用llc。例如,我借此简化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 

您需要安装或地方建有llc访问LLVM。它生成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。