8

Starting with code like this

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

using llvm as a cross compiler

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

and it detects and replaces it with a real memset when the optimizer is used

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}

but implements it without.

I don't want that I want it to compile the code I gave it for the target I gave it rather than use library calls. I thought the -disable-simplify-libcalls would do it but it doesn't.

I thought I had figured this out before, but cant find out how to do it. I need the optimizer, I don't want this circular dependency problem of implementing the library and it needing the library, etc. Could do it in asm to take the compiler out of the loop, but shouldn't have to.

4

2 回答 2

12
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 大神决定把它留在这里,那很好......

于 2014-01-24T01:18:25.337 回答
1

我遇到了同样的问题,如果它仍然可以帮助任何人,这就是我为解决它所做的 - 我修改了 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")
于 2015-12-01T08:04:45.170 回答