【问题标题】:Crystal-lang: why is the LLVM "hello.bc" not the same if generated by Crystal or by clang?Crystal-lang:如果由 Crystal 或 clang 生成,为什么 LLVM “hello.bc”不一样?
【发布时间】:2018-10-18 15:10:55
【问题描述】:

这是我的第一个 Stackoverflow 问题 :-)

我的背景:

  • 2 年 Python 经验
  • 2个月的水晶语言经验(使用Amber框架运行的网站)
  • 1 个月进入 C、C++、汇编

事实: - 水晶朗正在编译和运行没有任何问题 - 在 x86_64 上运行

请客气,因为我还没有太多低级语言知识。

据我了解,当我们使用 LLVM 编译和运行一个基本的 hello.c 文件时,它的内容如下:

你好.c:

#include
int main() {
  printf("hello world\n");
  return 0;
}

外壳:

$ clang -O3 -emit-llvm hello.c -c -o hello.bc
$ llc hello.bc -o hello.s
$ gcc hello.s -o hello.native
$ ./hello.native

这来自 LLVM 示例)

我的意思是,我们可以生成一个非常短的 hello.bc 文件(128 行),可以使用以下命令以较慢的方式运行:

$ lli hello.bc

但是当我尝试从 hello.cr 文件生成类似的 hello.bc 并像使用 hello.c 文件一样运行它时:

你好.cr:

puts "hello world"

外壳:

$ crystal build hello.cr --emit llvm-bc --release
$ llc hello.bc -o hello.s

我注意到了什么:

  • 这个 hello.bc 文件比从 c 文件生成的文件大得多(43'624 行)
  • 这个 hello.bc 不能使用“lli”运行,因为它会生成:

    "LLVM 错误:程序使用了无法解析的外部函数 'pcre_malloc'!

  • 我什至无法从 hello.s 编译到 hello.native

  • 如果我尝试使用 generate 和 hello.ll 文件也会出现同样的问题

据我了解,LLVM 是可移植的,所有前端语言都会生成一个中间 *.bc,然后可以编译为任何架构。

我的问题是:

  • 为什么 hello.bc 在两种情况下都不相似?
  • 我在水晶程序中做错了吗?

谢谢!

【问题讨论】:

    标签: llvm-ir crystal-lang


    【解决方案1】:

    一切都像它应该的那样。 Crystal 有一个运行时库,即使您没有包含任何内容,它也始终存在。这是运行 Crystal 程序所必需的。

    除了对printf 的系统调用之外,C 示例几乎不包含任何其他内容。这就是编译后的 ASM 也非常小的原因。

    Crystal 的简单puts 调用背后有更多内容。它基于用于处理异步 IO、并发、信号处理、垃圾收集等的库。其中一些库完全在 Crystal 标准库中实现,一些使用直接嵌入到二进制文件中的其他库 (libgc) 或仍然需要系统中的动态库 (libpcre, libpthread)。

    默认情况下,任何 Crystal 程序都带有此运行时库。甚至是一个空程序。这通常完全被忽视,因为更大的程序最终还是需要这些东西,并且运行时库的编译二进制大小小于 500 KB(在发布模式下)。 像你这样的小程序真的不需要所有这些来打印一个字符串。但 Crystal 运行时需要这些库。

    注意:您可以在没有这些默认库的情况下编译 Crystal 程序。但这意味着您不能使用 Crystal 标准库中的 任何东西,您必须使用 Crystal 语法编写 C 代码(或实现您自己的标准库):

    require "lib_c"
    require "c/stdio"
    
    LibC.printf pointerof("hello world".@c)
    

    这可以用--prelude=empty 选项编译,它会生成一个小得多的ASM,大致类似于C 示例。

    【讨论】:

    • 知道如何使用lli 启动IR 并绕过关于pcre_malloc 的错误仍然会很有趣。也许你也知道这个问题的答案。
    • 我对 LLVM 工具一无所知。但是您可能必须告诉 LLVM 解释器使用哪些动态库(-load 选项)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多