- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我是 .Net 的新手,我想先了解基础知识。 MSIL 和 LLVM 位码有什么区别?
最佳答案
LLVM bitcode 和 MSIL 都是 intermediate languages .从本质上讲,它们是通用汇编代码语言:不像大多数源语言(例如 Swift、C#)那样高级,但也不像真正的汇编语言(例如 ARM、x86)那样低级。这两种语言之间存在许多技术实现差异,但大多数开发人员不需要了解这些细节*。他们只需要知道如何在各自平台的分发模型中使用它们。
LLVM 位码格式是 the intermediate representation code used within the LLVM compiler 的序列化版本.编译器的“前端”将源语言(如Swift)翻译成LLVM bitcode,然后编译器的“后端”将bitcode翻译成目标指令集(如ARM机器码)。 (注意:此答案的先前版本暗示 LLVM 位码与处理器无关。事实并非如此,因为源语言取决于目标处理器。)
Apple 允许 iOS 开发人员以完全编译的 ARM 代码形式提交他们的应用程序 or as LLVM bitcode ,其中后者:
[...] will allow Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store.
本质上,您在开发环境中运行 LLVM 前端,将位码传递给 Apple,后者在其服务器上运行 LLVM 后端。此过程称为提前 (AOT) 编译(the Wikipedia article 对于非位码情况是否也是 AOT 或是否只是“标准”编译有两种看法)。
但是无论您是否使用 bitcode,iOS 最终用户始终会以 ARM 机器代码的形式获取应用。
.NET 中的情况有些不同。大多数 .NET 代码都编译为 MSIL,打包在名为assemblies 的文件中。最终用户设备上的 .NET 运行时加载并执行程序集,在运行时将 MSIL 编译为设备处理器的机器代码。这称为即时 (JIT) 编译。
通常,MSIL 与处理器无关,因此大多数开发人员可以将 .NET 应用程序视为与处理器无关。但是,在最终用户通过 JIT 运行应用程序之前,可以通过多种方式打包特定于处理器的代码:
一些工具,例如 Native Image Generator和 .NET Native , 允许 AOT 编译。事实上,上传到 Microsoft Store 的通用 Windows 平台 (UWP) 应用程序是 AOT 编译的 - 您将应用程序的 MSIL 版本提交给 Microsoft,然后他们的服务器使用 .NET Native 为 Windows 10 支持的各种架构编译它。
也可以在程序集本身中包含 native 代码;这些叫做mixed assemblies .
如果源语言使用“不安全”操作(例如,pointer math in C#),MSIL 本身可以是处理器特定的。
但这些通常是异常(exception)情况,而不是规则。通常,.NET 应用程序以 MSIL 形式分发,最终用户的设备是生成 native 代码的地方。
总结一下:
LLVM 位码是特定于处理器的,但并不像实际机器码那样低级。 Apple 允许 iOS 开发人员以位码形式提交应用程序,以便在可以引入优化时允许 future 重新编译。最终用户运行 native 可执行文件。
MSIL 通常与处理器无关。最终用户通常运行此与处理器无关的代码,而 .NET 在运行时将 MSIL 编译为 native 代码。但是,在某些情况下,应用的部分或全部可能是 native 代码。
* 当然,如果您对技术细节感兴趣,这里有标准for LLVM bitcode和 for MSIL, under its ECMA name CIL .我对后者有一定的了解;粗略浏览前者后,最显着的技术差异是内存模型:LLVM 位码是基于寄存器的,MSIL/CIL 使用评估堆栈。
关于llvm - MSIL 和 LLVM 位码有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47622113/
我指的是 https://llvm.org/docs/GettingStarted.html从其源代码构建 LLVM。我正在使用 Ubuntu 18.04。 $ cmake -G Ninja -DCM
使用 ModulePass,我的目标是向上遍历 SSA 图:从一个具有 0..2 个操作数的语句(大多数操作码属于该语句)开始,我想找出两件事: 操作数是元数据/常量(简单:只需尝试转换为常量类型)还
注意:我注意到 this question与这个问题有很大关系,所以如果您对我的问题感兴趣,那么您一定要阅读另一个问题及其答案。 我可以想到一些 OOP 语言前端可以做的优化,例如创建临时变量来保存来
我正在尝试使用 clang-3.2 创建自动矢量化代码 从这里的幻灯片 - http://llvm.org/devmtg/2012-04-12/Slides/Hal_Finkel.pdf 我应该能够使
我想问的是,我们可以将现有pass生成的信息转化为新pass吗? 如果是,那么如何? 例如 -loops 给出了自然循环信息,所以我们可以通过调用它来将这些信息用于新的传递。 最佳答案 您可以通过覆盖
在 LLVM IR 中,当我想从一个数组中获取一个值时,似乎有三种方法可以做到这一点:使用 extractvalue、使用 extractelement 和使用 getelementptr 然后加载。
我想逐步介绍一下我生成的LLVM IR代码。就llc和lli而言,该代码在语法上是有效的并且类型有效,但是结果不是我所期望的。 这些块足够大,以至于我无法简单地读取该错误就无法成功完成,并且我很难制作
我想弄清楚如何使用 trampoline intrinsics在 LLVM 中。该文档提到了存储蹦床所需的一些存储量,这取决于平台。我的问题是,我如何确定需要多少? 我找到了 this example
我需要使用抽象解释来使用 LLVM 进行一些分析。这可能吗?或者我需要更轻松地使用分析工具。如果我可以通过 LLVM 做到这一点,哪些类将帮助我从原始源代码中制定语句以获取变量之间的关系(以及每个变量
我正在创建一种静态编译的编程语言,并使用 LLVM 作为其后端。我希望我的语言在发生整数溢出时陷入/崩溃。 我知道类似 llvm.sadd.with.overflow 的事情,但我认为这不是最佳/有效
我正在尝试学习 LLVM tablegen。 http://llvm.org/docs/TableGen/LangRef.html表明 field关键字存在但不解释其含义。有人知道这是什么意思吗? 我
Fibonacci LLVM 示例使用 errs() getIR() ) 我一直在搜索 llvm::Module Class Reference并没有得到任何帮助。 Fibonacci.cpp 的一部
我想在 llvm IR 中找到对 llvm.pow.f64 函数的所有函数调用。请建议我一个方法来做到这一点。 最佳答案 嗯,这是一个基本的 FunctionPass找到所有对函数的调用: class
我正在尝试从 llvm 中间代码中删除未使用的 block 。 首先,我通过从入口 basicblock 开始并从它们的终止符指令添加所有 basicblock 后继者来构建可访问的 basicblo
我想获取 llvm 中每条指令的后继列表。如果我没理解错的话,对于除了branch(br)之外的所有指令,后继指令就是下一条。但是对于分支指令来说有点棘手。 例如,如果我有以下 C 代码: int m
我有文本格式的 LLVM IR 代码。我想做的是能够解析它并修改该代码。是否有可以帮助解析 LLVM IR 代码的 API?我的系统中应该有哪些库?此刻我有clang编译器也安装了 LLVM,因为我可
(1) @str = private constant [13 x i8] c"Hello World\0A\00" (2) define i32 @main(){ (3) %r2 = getelem
如果我有一组基本块和边,我需要为它们创建一个具有新入口和端点的新函数。 我可以直接在 LLVM 中创建它吗,就像 createFunction(F) 一样然后 F.insert(bb, edges)其
我通过教程使用 LLVM http://llvm.org/releases/3.1/docs/tutorial/ 编写玩具编译器 但是关于符号表处理的内容并不多。 有一个命令 llvm-nm 显示符号
我希望编写一个 LLVM 传递两个 i32 类型的参数来选择函数。我的第一次尝试(如下所示)失败了: bool MyFunctionPass::runOnFunction(Function &f) {
我是一名优秀的程序员,十分优秀!