Optimization clang/LLVM ARM ABI,非易失性寄存器被销毁
我试图使用clang/llvm作为armcortex-m的交叉编译器 基于一个/一些LLVM页面,这就是我构建工具链的方式Optimization clang/LLVM ARM ABI,非易失性寄存器被销毁,optimization,arm,clang,llvm,abi,Optimization,Arm,Clang,Llvm,Abi,我试图使用clang/llvm作为armcortex-m的交叉编译器 基于一个/一些LLVM页面,这就是我构建工具链的方式 rm -rf /opt/llvm/llvm10armv6m rm -rf llvm-project git clone https://github.com/llvm/llvm-project.git cd llvm-project git checkout llvmorg-10.0.0 mkdir build cd build cmake -DLLVM_ENABLE_PR
rm -rf /opt/llvm/llvm10armv6m
rm -rf llvm-project
git clone https://github.com/llvm/llvm-project.git
cd llvm-project
git checkout llvmorg-10.0.0
mkdir build
cd build
cmake -DLLVM_ENABLE_PROJECTS='clang;lld' -DCMAKE_CROSSCOMPILING=True -DCMAKE_INSTALL_PREFIX=/opt/llvm/llvm10armv6m -DLLVM_DEFAULT_TARGET_TRIPLE=armv6m-none-eabi -DLLVM_TARGET_ARCH=ARM -DLLVM_TARGETS_TO_BUILD=ARM -G "Unix Makefiles" ../llvm
make -j 8
make -j 4
make
sudo make install
测试c
void fun ( unsigned int, unsigned int );
int test ( void )
{
unsigned int ra;
unsigned int rx;
for(rx=0;;rx++)
{
ra=rx;
ra|=((~rx)&0xFF)<<16;
fun(0x12345678,ra);
}
return(0);
}
clang -Wall -O2 -nostdlib -ffreestanding -fomit-frame-pointer -c test.c -o test.o
arm-none-eabi-objdump -D test.o
Disassembly of section .text:
00000000 <test>:
0: 20ff movs r0, #255 ; 0xff
2: 0405 lsls r5, r0, #16
4: 2600 movs r6, #0
6: 4c06 ldr r4, [pc, #24] ; (20 <test+0x20>)
8: 4637 mov r7, r6
a: 4629 mov r1, r5
c: 43b1 bics r1, r6
e: 4339 orrs r1, r7
10: 4620 mov r0, r4
12: f7ff fffe bl 0 <fun>
16: 2001 movs r0, #1
18: 0400 lsls r0, r0, #16
1a: 1836 adds r6, r6, r0
1c: 1c7f adds r7, r7, #1
1e: e7f4 b.n a <test+0xa>
20: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
没有任何改善
00000000 <test>:
0: b580 push {r7, lr}
2: af00 add r7, sp, #0
4: 20ff movs r0, #255 ; 0xff
6: 0405 lsls r5, r0, #16
8: 2400 movs r4, #0
a: 4626 mov r6, r4
c: 4629 mov r1, r5
e: 43a1 bics r1, r4
10: 4331 orrs r1, r6
12: 4804 ldr r0, [pc, #16] ; (24 <test+0x24>)
14: f7ff fffe bl 0 <fun>
18: 2001 movs r0, #1
1a: 0400 lsls r0, r0, #16
1c: 1824 adds r4, r4, r0
1e: 1c76 adds r6, r6, #1
20: e7f4 b.n c <test+0xc>
22: 46c0 nop ; (mov r8, r8)
24: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
但是如果我用一个通用的apt/llvm
clang -Wall -O2 -nostdlib -ffreestanding -fomit-frame-pointer -target armv6m-none-gnueabi -mthumb -mcpu=cortex-m0 -c test.c -o test.o
arm-none-eabi-objdump -D test.o
Disassembly of section .text:
00000000 <test>:
0: b5f0 push {r4, r5, r6, r7, lr}
2: b081 sub sp, #4
4: 20ff movs r0, #255 ; 0xff
6: 0405 lsls r5, r0, #16
8: 2600 movs r6, #0
a: 4c06 ldr r4, [pc, #24] ; (24 <test+0x24>)
c: 4637 mov r7, r6
e: 4629 mov r1, r5
10: 43b1 bics r1, r6
12: 4339 orrs r1, r7
14: 4620 mov r0, r4
16: f7ff fffe bl 0 <fun>
1a: 2001 movs r0, #1
1c: 0400 lsls r0, r0, #16
1e: 1836 adds r6, r6, r0
20: 1c7f adds r7, r7, #1
22: e7f4 b.n e <test+0xe>
24: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
显然不需要tbl gen的东西。理论上,-G Unix Makefiles应该允许并行构建Makefiles,但我确实有一个问题。有一两个地方它能工作,但有一个地方它不能,它必须一次又一次地运行,或者最终连续运行。因此,最终的结果是这样的
随着版本的发布,二进制文件明显更小,而不是几十GB,整个安装的二进制文件大小大约为1.5 GB
我不认为构建速度更快。与1990年代的GCC相比,持续时间仍然合适。P>答案很简单:你的功能永远不会返回。因此,保存/恢复被叫方保存的寄存器没有任何意义 如果更改源以允许函数终止,如下所示:
void fun ( unsigned int, unsigned int );
unsigned bar();
int test ( void )
{
unsigned int ra;
unsigned int rx;
for(rx=0;rx<bar();rx++)
{
ra=rx;
ra|=((~rx)&0xFF)<<16;
fun(0x12345678,ra);
}
return(0);
}
void fun(无符号整数,无符号整数);
无符号条();
内部测试(无效)
{
无符号整数ra;
无符号整数rx;
对于(rx=0;rxDOH这太有趣了,我数不出多少年了,我没有看到我使用的编译器这么做,如果你删除了返回,例如有些人抱怨没有从函数中返回,那么有些人甚至会检测到这一点,并抱怨返回是无法访问的代码。谢谢,我可能会删除这一点,这太微不足道了,我错过了它…将尝试发布模式,多亏了这一点,这是我将要研究的东西还解释了为什么llvm二进制文件比gnuUnix Makefiles小-用于生成与make兼容的并行Makefiles…嗯,我在一台机器上失败了。因此多次运行make…有趣的是,交叉编译确实推动了寄存器,所以,也许这是一个不应该出现的问题。
00000000 <test>:
0: b580 push {r7, lr}
2: b082 sub sp, #8
4: 2000 movs r0, #0
6: 9000 str r0, [sp, #0]
8: e7ff b.n a <test+0xa>
a: 9800 ldr r0, [sp, #0]
c: 9001 str r0, [sp, #4]
e: 4668 mov r0, sp
10: 7800 ldrb r0, [r0, #0]
12: 21ff movs r1, #255 ; 0xff
14: 4048 eors r0, r1
16: 0400 lsls r0, r0, #16
18: 9901 ldr r1, [sp, #4]
1a: 4301 orrs r1, r0
1c: 9101 str r1, [sp, #4]
1e: 9901 ldr r1, [sp, #4]
20: 4803 ldr r0, [pc, #12] ; (30 <test+0x30>)
22: f7ff fffe bl 0 <fun>
26: e7ff b.n 28 <test+0x28>
28: 9800 ldr r0, [sp, #0]
2a: 1c40 adds r0, r0, #1
2c: 9000 str r0, [sp, #0]
2e: e7ec b.n a <test+0xa>
30: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
The CMake options you need to add are:
-DCMAKE_CROSSCOMPILING=True
-DCMAKE_INSTALL_PREFIX=<install-dir>
-DLLVM_TABLEGEN=<path-to-host-bin>/llvm-tblgen
-DCLANG_TABLEGEN=<path-to-host-bin>/clang-tblgen
-DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabihf
-DLLVM_TARGET_ARCH=ARM
-DLLVM_TARGETS_TO_BUILD=ARM
export THEPLACE=/opt/llvm/llvm10armv6m
export THETARGET=armv6m-none-eabi
rm -rf $THEPLACE
rm -rf llvm-project
git clone https://github.com/llvm/llvm-project.git
cd llvm-project
git checkout llvmorg-10.0.0
mkdir build
cd build
cmake \
-DLLVM_ENABLE_PROJECTS='clang;lld' \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CROSSCOMPILING=True \
-DCMAKE_INSTALL_PREFIX=$THEPLACE \
-DLLVM_DEFAULT_TARGET_TRIPLE=$THETARGET \
-DLLVM_TARGET_ARCH=ARM \
-DLLVM_TARGETS_TO_BUILD=ARM \
-G "Unix Makefiles" \
../llvm
make -j 8
make -j 4
make
sudo make install
void fun ( unsigned int, unsigned int );
unsigned bar();
int test ( void )
{
unsigned int ra;
unsigned int rx;
for(rx=0;rx<bar();rx++)
{
ra=rx;
ra|=((~rx)&0xFF)<<16;
fun(0x12345678,ra);
}
return(0);
}