我正在使用flex野牛和llvm编写自己的编译器。但是,当我想为一个简单函数示例生成ir时
int jia (int a){
a=a+1;
return a;
}
结果是:
; ModuleID = 'main'
source_filename = "main"
define i32 @jia(i32 %a) {
entry:
%0 = alloca i32
store i32 %a, i32* %0
%tmp = load i32, i32* %0
%tmp1 = load i32, i32* %0
%addtmp = add i32 %tmp1, i32 1
store i32 %addtmp, i32* %0
%tmp2 = load i32, i32* %0
ret i32 %tmp2
}
我使用Lli来执行IR代码。但显示enter image description here时出错
所以我用一个很好的demo来生成同样的函数,ir是
define i32 @jia(i32 %a) {
entry:
%0 = alloca i32
store i32 %a, i32* %0
%arrayPtr = load i32, i32* %0
%1 = load i32, i32* %0
%addtmp = add i32 %1, 1
store i32 %addtmp, i32* %0
%arrayPtr1 = load i32, i32* %0
%2 = load i32, i32* %0
ret i32 %2
}
所以重点是“%addtmp = add i32%1,1”和“%addtmp = add i32%tmp1,i32 1”为什么第一个可以执行。下一个不能这样做。以及指令%addtmp = add i32%1,1中的1的类型是什么
我希望有人能告诉我为什么我在1之前多了一个“i32”。以及如何生成正确的代码。
我使用的代码:
llvm::Value* int_num_node::codegen(CodeGenerator & generator){
cout<<"[ast.cpp line93 int_num_node::codegen]NInteger"<<endl;
return ConstantInt::get(Type::getInt32Ty(TheContext), this->number, true);
//return TheBuilder.getInt32(this->number);
}
llvm::Value* op_node::codegen(CodeGenerator & generator){
cout<<"[ast.cpp line73 op_node::codegen]NBexpression"<<endl;
llvm::Value* left_value = this->LHS->codegen(generator);
llvm::Value* right_value = this->RHS->codegen(generator);
if(left_value==NULL) return nullptr;
if(right_value==NULL) return nullptr;
cout<<"[ast.cpp line83 op_node::codegen]this->op_code: "<<this->op_code<<endl;
switch(this->op_code){
//add
case '+':
return TheBuilder.CreateAdd(left_value,right_value,"addtmp");
case '-':
return TheBuilder.CreateSub(left_value,right_value,"subtmp");
case '*':
return TheBuilder.CreateMul(left_value,right_value,"multmp");
case '/':
return TheBuilder.CreateSDiv(left_value,right_value,"divtmp");
}
}
1条答案
按热度按时间ss2ws0br1#
add
的语法如下所示:add
的两个参数必须是整数,并且必须具有相同的类型,这就是为什么只指定一次type的原因。