问题
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.
回答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
thanks to artless noise while adding -ffreestanding, I decided to re-read all the --help options for llc and opt, and found the -disable-simpilfy-libcalls is an option for both opt and llc, adding it to opt fixed the problem.
lib_memset:
cmp r2, #0
bxeq lr
.LBB0_1:
strb r1, [r0], #1
subs r2, r2, #1
bne .LBB0_1
bx lr
I dont like answering my own question, can sit here for a bit so I can maybe find the answer next time or if the SO gods decide to leave it here that is fine...
回答2:
I encounter the same problem and if it still can help anyone this is what I did to solve it - I modify the LoopIdiomRecognize.cpp file in the llvm source code: there is a code that checks if the name of the function is memset or memcpy it cancel the optimization, so I changed it from:
StringRef Name = L->getHeader()->getParent()->getName();
if (Name == "memset" || Name == "memcpy")
to
StringRef Name = L->getHeader()->getParent()->getName();
if (Name.endswith("memset") || Name == "memcpy")
来源:https://stackoverflow.com/questions/21318229/llvm-optimizes-with-library-functions