在学习Kaleidoscope的codegen的时候,看得很痛苦。虽然代码很短,而且没有什么复杂的算法,但由于之前没有接触过llvm所以几乎不知道每一行代码的意思,不懂这些llvm的代码都在干什么。
最后,看了很多遍逐渐意会了。然后就提出了下列问题。
代码链接:kaleidoscope-chapter3
问题
1. 下面代码中第一行为什么可以直接在TheModule中查找Callee。
答:因为这是callExpr的codegen,在执行call之前肯定要定义这个函数。在那个时候就把Callee对应的函数初始化到TheModule中了。这是llvm教程顺序安排的问题,没有看到那里去,所以遇到了问题。
Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (!CalleeF)
return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->codegen());
if (!ArgsV.back())
return nullptr;
}
return Builder->CreateCall(CalleeF, ArgsV, "calltmp");
}
2. 下面代码中,Type*是什么?
答:是Type::getDoubleTy(*TheContext))的类型。这段代码的意思是要建一个大小为Args.size()的vector,里面值的类型都是Type*。Type::getDoubleTy(*TheContext))就是llvm得到double这个类型。
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
std::vector<Type*> Doubles(Args.size(),
Type::getDoubleTy(*TheContext));
FunctionType *FT =
FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
3. 下面代码中,为什么把NamedValues清空了?
答:NamedValues是专门处理函数函数参数的符号表。处理当前函数时,前面的函数已经处理好了,所以之前函数的参数名到值的映射就没有作用了。删去的话,可以防止参数名重复,并且节省内存。
Function *FunctionAST::codegen() {
// First, check for an existing function from a previous 'extern' declaration.
Function *TheFunction = TheModule->getFunction(Proto->getName());
if (!TheFunction)
TheFunction = Proto->codegen();
if (!TheFunction)
return nullptr;
if (!TheFunction->empty())
return (Function*)LogErrorV("Function cannot be redefined.");
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction);
Builder->SetInsertPoint(BB);
// Record the function arguments in the NamedValues map.
NamedValues.clear();
for (auto &Arg : TheFunction->args())