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.
LLVM features powerful intermodular optimizations which can be used at link time. Link Time Optimization (LTO) is another name for intermodular optimization when performed during the link stage.
What makes it so popular is that its modular design allows its functionality to be adapted and reused very easily.
LLVM was released under the University of Illinois/NCSA Open Source License, a permissive free software licence. In 2005, Apple Inc. hired Lattner and formed a team to work on the LLVM system for various uses within Apple's development systems.
Link time optimization is relevant in programming languages that compile programs on a file-by-file basis, and then link those files together (such as C and Fortran), rather than all at once (such as Java's just-in-time compilation (JIT)).
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...
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With