似乎最先进的编译器将堆栈传递的参数视为只读.请注意,在x86调用约定中,调用者将参数压入堆栈,并且被调用者使用堆栈中的参数.例如,以下C代码:
extern int goo(int *x);
int foo(int x, int y) {
goo(&x);
return x;
}
Run Code Online (Sandbox Code Playgroud)
clang -O3 -c g.c -S -m32在OS X 10.10中编译成:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 10
.globl _foo
.align 4, 0x90
_foo: ## @foo
## BB#0:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
leal -4(%ebp), %eax
movl %eax, (%esp)
calll _goo
movl -4(%ebp), %eax
addl $8, %esp
popl %ebp
retl
.subsections_via_symbols
Run Code Online (Sandbox Code Playgroud)
这里,首先加载参数x(8(%ebp))%eax; 然后存储-4(%ebp) …
在Clang或LLVM中,如何正确声明引用CPU寄存器的外部变量?例如,我想表达以下声明(如https://github.com/mit-pdos/xv6-public/blob/master/proc.h#L27):
extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()]
extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc
Run Code Online (Sandbox Code Playgroud)
看来上面的代码是编译的,但没有以预期的方式链接.我将xv6移植到Rust,作为踏脚石,我将它移植到Clang 3.8.0(而不是GCC).但在构建期间,链接器发出以下错误消息:
ld -m elf_i386 -T kernel.ld -o kernel entry.o bio.o console.o exec.o file.o fs.o ide.o ioapic.o kalloc.o kbd.o lapic.o log.o main.o mp.o picirq.o pipe.o proc.o sleeplock.o spinlock.o string.o swtch.o syscall.o sysfile.o sysproc.o timer.o trapasm.o trap.o uart.o vectors.o vm.o -b binary initcode entryother
console.o: In function `panic':
.../console.c:114: undefined reference to `%gs:0'
Run Code Online (Sandbox Code Playgroud) clang -O1和之间有什么区别opt -O1?我观察到这两个命令的行为明显不同。
我想测试LLVM优化过程。更具体地说,我想选择一个-O1通行证的子集,以便1)该子集的性能与整体性能相同-O1,以及2)选定的通行证易于推断其正确性。
为了测试子集的性能,我编写了一个shell脚本,例如:
clang -o a.bc -emit-llvm -c a.c
opt (..., optmizations like -adce, ...) a.bc >a.opt.bc
clang -o a a.opt.bc
Run Code Online (Sandbox Code Playgroud)
经过大量尝试,我发现:
clang -o a.bc -emit-llvm -c a.c
opt -O1 a.bc >a.opt.bc
clang -o a a.opt.bc
Run Code Online (Sandbox Code Playgroud)
和clang -O1 -oa ac
发出明显不同的二进制文件。后者要高效得多,例如,对于一个示例程序,前者需要49秒才能运行,而后者则需要29秒。
我搜索了它的含义clang -O1,并找到了一些参考(例如Clang优化级别),但是这篇文章的确是关于opt,而不是clang。
我试图找到的正式文档clang,但没有成果。
我试图了解clang源代码,但我无法...
我尝试过
clang -o a.bc -emit-llvm -c ac opt -mem2reg -O1 a.bc> …