llvm-如何用我的语言实现打印功能? [英] llvm - How to implement print function in my language?

查看:90
本文介绍了llvm-如何用我的语言实现打印功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注 llvm 的教程,了解他们自己的简单编程语言Kaleidoscope",我的语言中有一个明显的功能,本教程似乎没有涵盖.我只是想像C ++一样将任何double输出到标准输出:

I'm following llvm's tutorial for their own simple programming language "Kaleidoscope" and there's an obvious functionality in my language which this tutorial doesn't seem to cover. I simply want to print any double to standard output pretty much as C++ would do:

std::cout << 5.0;

我的语言会做类似的事情

my language would do something like

print(5.0);

llvm 教程的第三章介绍了函数调用.他们使用的代码是:

Third chapter of llvm's tutorial covers function calls. The code they use is:

Value *CallExprAST::codegen() {
  // Look up the name in the global module table.
  Function *CalleeF = TheModule->getFunction(Callee);
  if (!CalleeF)
    return ErrorV("Unknown function referenced");

  // If argument mismatch error.
  if (CalleeF->arg_size() != Args.size())
    return ErrorV("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");
}

如何为特定的函数调用实现 codegen()方法 print(任何fp编号)?

How could I implement codegen() method for specific function call print(any fp number)?

推荐答案

下面是为printf(%f",a)生成的llvm ir代码;使用c声.printf签名为int printf(const char *,...);

below is the llvm ir code generated for printf("%f", a); using clang. printf signature is int printf(const char*, ...);

@.str = private unnamed_addr constant [3 x i8] c"%f\00", align 1

; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%a = alloca double, align 8
%1 = load double* %a, align 8
%2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]*  @.str, i32 0, i32 0), double %1)
ret i32 0
}

declare i32 @printf(i8*, ...) #1

要在代码生成中实现,您首先需要检查该功能是否已存在于模块中.如果不是这样,则需要添加声明,您可以在一个调用中完成这两个操作.

to implement in codegen you first need to check if the function is already present in module or not. if not then you need to add the declaration, you can do both in one call.

Function *CalleeF = TheModule->getOrInsertFunction("printf",
                                                   FunctionType::get(IntegerType::getInt32Ty(Context), PointerType::get(Type::getInt8Ty(Context), 0), true /* this is var arg func type*/) 
                                                   );

以上将获取或添加函数声明的句柄

above will get or add you the handle to function declaration

 declare i32 @printf(i8*, ...) #1

然后您可以通过匹配的参数调用函数.

then you can call function via matching params.

 std::vector<Value *> ArgsV;
 for (unsigned i = 0, e = Args.size(); i != e; ++i) 
   ArgsV.push_back(Args[i]->codegen());

return Builder.CreateCall(CalleeF, ArgsV, "printfCall");

这篇关于llvm-如何用我的语言实现打印功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆