【问题标题】:llvm optimizes with library functionsllvm 使用库函数进行优化
【发布时间】:2014-02-14 14:16:16
【问题描述】:

从这样的代码开始

void lib_memset( unsigned char *dest, unsigned char c, unsigned int n)
{
    while(n--)
    {
        *dest=c;
        dest++;
    }
}

使用 llvm 作为交叉编译器

clang -Wall -m32 -emit-llvm -fno-builtin --target=arm-none-eabi  -c lib_memset.c -o lib_memset.bc
opt -std-compile-opts -strip-debug -march=arm -mcpu=mpcore -mtriple=arm-none-eabi lib_memset.bc -o lib_memset.opt.bc
llc -march=arm -mcpu=mpcore -disable-simplify-libcalls  lib_memset.opt.bc -o lib_memset.opt.s
llc -march=arm -mcpu=mpcore -disable-simplify-libcalls  lib_memset.bc -o lib_memset.s

当使用优化器时,它会检测并用真实的 memset 替换它

lib_memset:
    push    {r11, lr}
    mov r3, r1
    mov r11, sp
    cmp r2, #0
    beq .LBB0_2
    mov r1, r2
    mov r2, r3
    bl  __aeabi_memset
.LBB0_2:                                @ %while.end
    pop {r11, pc}

但没有实现它。

我不希望它编译我给它的代码,用于我给它的目标,而不是使用库调用。我认为 -disable-simplify-libcalls 会这样做,但事实并非如此。

我以为我之前已经解决了这个问题,但不知道该怎么做。我需要优化器,我不希望这种实现库的循环依赖问题以及它需要库等。可以在 asm 中执行以使编译器脱离循环,但不应该这样做。

【问题讨论】:

  • -ffreestanding? same problem?
  • 卫生署!在 opt 步骤中需要 -disable-simplify-libcalls 而不是或与 llc 一样...修复它。

标签: optimization assembly embedded arm bare-metal


【解决方案1】:
clang -Wall -m32 -emit-llvm -fno-builtin --target=arm-none-eabi -ffreestanding -c lib_memset.c -o lib_memset.bc
opt -std-compile-opts -strip-debug -march=arm -mcpu=mpcore -mtriple=arm-none-eabi -disable-simplify-libcalls  lib_memset.bc -o lib_memset.opt.bc
llc -march=arm -mcpu=mpcore -disable-simplify-libcalls -mtriple=arm-none-eabi  lib_memset.opt.bc -o lib_memset.opt.s
llc -march=arm -mcpu=mpcore -disable-simplify-libcalls -mtriple=arm-none-eabi  lib_memset.bc -o lib_memset.s

感谢添加 -ffreestanding 时的无艺术噪音,我决定重新阅读 llc 和 opt 的所有 --help 选项,并发现 -disable-simpilfy-libcalls 是 opt 和 llc 的选项,将其添加到opt 解决了这个问题。

lib_memset:
    cmp r2, #0
    bxeq    lr
.LBB0_1:
    strb    r1, [r0], #1
    subs    r2, r2, #1
    bne .LBB0_1
    bx  lr

我不喜欢回答我自己的问题,可以在这里坐一会儿,这样我下次可能会找到答案,或者如果 SO 大神决定把它留在这里也没关系...

【讨论】:

  • 回答你自己的问题就好了。在您接受之前有 2 天的延迟,因此其他人也有公平的机会回复。你绝对应该把它放在这里,以防其他人将来遇到同样的问题。
【解决方案2】:

我遇到了同样的问题,如果它仍然可以帮助任何人,这就是我为解决它所做的 - 我修改了 llvm 源代码中的 LoopIdiomRecognize.cpp 文件: 有一个代码可以检查函数的名称是 memset 还是 memcpy 它取消了优化,所以我将其更改为:

StringRef Name = L->getHeader()->getParent()->getName();
  if (Name == "memset" || Name == "memcpy")

StringRef Name = L->getHeader()->getParent()->getName();
  if (Name.endswith("memset") || Name == "memcpy")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    相关资源
    最近更新 更多