问题标签 [llvm-codegen]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 为什么 LLVM 会分配冗余变量?
这是一个带有枚举定义和main
函数的简单 C 文件:
它转译为以下 LLVM IR:
%2
显然是d
变量,它被分配了 2。%1
如果直接返回零,对应的是什么?
performance - 为什么 LLVM 似乎忽略了 Rust 的假设内在?
LLVM 似乎忽略了core::intrinsics::assume(..)
调用。它们最终会出现在字节码中,但不会更改生成的机器码。例如,采用以下(无意义的)代码:
这编译成一大堆程序集:
现在我们可以在(仅每晚xs
)之后引入未满(满载)的假设:pop()
然而,尽管assume
出现在 LLVM 字节码中,程序集并没有改变。但是,如果我们使用core::hint::unreachable_unchecked()
在非假设情况下创建发散路径,例如:
我们得到以下信息:
这本质上是无操作的,但还不错。当然,我们可以使用以下方法保留该值:
这编译到我们期望的:
为什么 LLVM 似乎忽略了assume
内在函数?
rust - Is signed integer overflow in safe Rust in release mode considered as undefined behavior?
Rust treats signed integer overflow differently in debug and release mode. When it happens, Rust panics in debug mode while silently performs two's complement wrapping in release mode.
As far as I know, C/C++ treats signed integer overflow as undefined behavior partly because:
- At that time of C's standardization, different underlying architecture of representing signed integers, such as one's complement, might still be in use somewhere. Compilers cannot make assumptions of how overflow is handled in the hardware.
- Later compilers thus making assumptions such as the sum of two positive integers must also be positive to generate optimized machine code.
So if Rust compilers do perform the same kind of optimization as C/C++ compilers regarding signed integers, why does The Rustonomicon states:
No matter what, Safe Rust can't cause Undefined Behavior.
Or even if Rust compilers do not perform such optimization, Rust programmers still do not anticipate seeing a signed integer wrapping around. Can't it be called "undefined behavior"?
llvm - 使用 clang 调用 LLVM CodeGen 传递时出错:尝试在没有目标机器的情况下构造 TargetPassConfig
我一直在尝试使用 clang 调用我的树外 LLVM 函数传递(opt 不是一个选项。与 opt btw 一起工作正常):
clang -std=c99 -m64 -c -o file.o -DSPEC -DNDEBUG -Ispec_qsort -DSPEC_AUTO_SUPPRESS_OPENMP -g -march=native -fno-unsafe-math-optimizations -Xclang -load -Xclang path/to/MyPass.so path /to/my_lib.a -fno-strict-aliasing -fgnu89-inline -DSPEC_LP64 file.c
但我收到以下错误:
如果我删除与 TargetPassConfig 相关的代码,则该通行证可以正常工作。
我通过执行以下操作向 clang 注册通行证:
要大致了解我的通行证的外观,请查看:
https://github.com/llvm-mirror/llvm/blob/master/lib/CodeGen/SafeStack.cpp
它也依赖于 TargetPassConfig。以下行似乎是问题所在:
TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
我不确定如何在我的通行证运行之前调用/填充 TargetMachine。但如上所述,通过 opt 可以正常工作。因此,我不愿意更改通过逻辑。
任何指针将不胜感激。
rust - 什么是代码模型以及它们如何影响代码生成?
在 rustc 中,有 4 种代码模型。您可以通过键入以下内容查看列表rustc --print code-models
:
他们的意思是什么?
c++ - LLVM 从 C/C++ 构建器创建可执行代码
我从这里得到了一个示例 llvm 代码。这段代码有一些问题,我也修复了它们。此时,它所做的只是转储翻译后的 IR 代码。我所追求的是从我的代码创建一个可执行文件,而不在我的 bash 中C++
调用llvm-as
// llc
。clang
我怎样才能做到这一点?
我也不想创建任何 IR 或字节码中间文件。
一个附带问题:顺便说一句,当我搜索 LLVM 示例时,很多结果都是 IR 示例。如何获得从 C++ 教授创建的结果?
compiler-construction - 静态调度OOO处理器
LLVM MISched 指令调度程序使用处理器功能单元、管道和延迟的声明性 TableGen 描述。想象一下,试图从这些声明中确定与英特尔优化参考手册中的编码指南等效的情况。
从广义上讲,静态调度 OOO 处理器的目标/技术是什么?对于OOO处理器,它什么时候会在B之前调度指令A,什么时候在B之后调度A?
超标量处理器一次可以执行多条指令。有序处理器将只考虑原始顺序中的指令。乱序(OOO)处理器可以乱序执行指令,然后按顺序提交结果。推测对于这个问题并不重要,但我认为这些处理器是流水线的。想想 A53(有序)和 Haswell(OOO)。
OOO 处理器接下来将执行哪条指令是处理器在运行时做出的调度决策。所以这通常被称为动态调度。顺序处理器执行哪条指令是由编译器在编译程序时决定的。因此,这通常称为静态调度。
然而,编译器也静态地定位/调度 OOO 处理器。在有序和 OOO 情况下,编译器可以查看大窗口的指令;编译器必须处理寄存器压力;在这两种情况下,编译器都希望使功能单元保持忙碌。OOO 处理器通常还可以重命名寄存器,从而减少寄存器压力。
鉴于 OOO 处理器动态调度指令,提前编译器应该做些什么来帮助这一点?
c - LLVM-C 创建目标文件导致:“TargetMachine 无法发出这种类型的文件”
尝试使用 LLVM-C 生成一个非常简单的目标文件。不幸的是,我仍然坚持“TargetMachine 无法发出这种类型的文件”尝试重新排序代码和 CPU 的各种东西(x64-64、通用和 LLVMGetHostCPUName())。显然这里缺少一些东西(希望是显而易见的)。
下面的代码是用clang -Wall -O2 test.c LLVM-C.dll -o test
输出:
模块.txt:
代码(test.c):
assembly - 在 clang 中禁用 cmov
从命令行可以告诉 clang 禁用某些功能,例如-mno-mmx
或-mno-popcnt
. 但是,虽然cmov
是 llvm 跟踪的功能,但-mno-cmov
x86 处理器没有(尽管您可以禁用其他处理器目标的条件移动)。
作为一种解决方法,我可以直接告诉 llvm 组件不要在处理器功能列表中包含“cmov”。但是,也许这是一个错误或者我做错了什么,即使关闭此功能它仍然会生成 cmov 指令。
如何让 clang/llvm 不生成 cmov 指令?
(在我的特定用例中,将条件保留为分支对于自动覆盖跟踪分析很有用,并且-O0
非常苛刻,如果代码使用三元运算符,可能仍不能保证防止这种情况发生。)
这是一个带有一些测试的代码示例
文件:ac
显示正常编译的控制台片段
控制台片段显示作为 llvm 发出,并关闭 cmov 目标功能,
然后编译 llvm -> 机器指令
c - 使用 LLVM 的 C API 在内存中发出目标代码
我将 LLVM-C API 用于编译器项目,需要将目标代码从 IR 发送到内存缓冲区。我知道 JIT 可以做到这一点,但是生成的代码将使用不同的参数执行多次,因此静态编译一次而不是每次 JIT 编译更有意义。
我想要的是一个目标代码缓冲区,然后我可以设置可执行文件,可能通过使用mmap
(但如果有更简单的方法,请告诉我),然后运行。
我发现这个函数LLVMTargetMachineEmitToMemoryBuffer
似乎可以完成我需要的第一部分,但它需要一个现有的 LLVM 内存缓冲区类型才能写入。据我所知,我想要LLVMCreateMemoryBufferWithRange
这个,它需要一个指针char
和一个大小。但是现在我需要知道要提前写入多少字节LLVMTargetMachineEmitToMemoryBuffer
才能为它提供正确的缓冲区,因为它从任意 IR 生成目标代码可能是任意大的,所以我觉得我在这里采取了错误的方法,但我我不确定该怎么做。
如何使用 LLVM 的 API 实现这一点?