Hi, all,
I am using llvm-gcc --emit-llvm to generate byte code. With llvm
readable ll format, I found some standard C library function such as
llvm.memset.
In fact, I'm trying to compile newlibc with llvm, I do not need this
kind of llvm functions. How can I remove them during the compilation?
Best regards,
Hi Hao Shen,
I am using llvm-gcc --emit-llvm to generate byte code. With llvm
readable ll format, I found some standard C library function such as
llvm.memset.
this is not a C library function, it is an LLVM intrinsic. An intrinsic is
analogous to a builtin in gcc. An intrinsic may be expanded out into a code
sequence by the compiler, or may get turned into a library call (which sounds
like is what you are seeing).
In fact, I'm trying to compile newlibc with llvm, I do not need this
kind of llvm functions. How can I remove them during the compilation?
You can't avoid them. The same problem exists with gcc: you can't always
avoid having gcc use the gcc memset builtin. However it has to be said
that gcc generates its memset builtin less often than llvm-gcc generates
llvm.memset, so this is not as visible. Also (I'm not sure about this)
it may be that on some platforms gcc always expands builtin_memset into a
code sequence rather than generating a call to the library memset function.
However, gcc is not obliged to use a code sequence even in a freestanding
environment. The environment is always required to provide memset. Here's
what the gcc docs say:
GCC requires the freestanding environment provide `memcpy', `memmove',
`memset' and `memcmp'.
Ciao,
Duncan.
Thanks a lot for your answer.
As what you said, I can not have any options to avoid generating this kind
of intrinsic for byte code. Is it possible to modify gcc and ask it take
all memset liked functions as a general function call? I know this solution
is less performance efficient, but I would like to have it for my llvm
assembly level modification works.
But anyway, thanks for you help.
Hao
SHEN Hao wrote:
Thanks a lot for your answer.
As what you said, I can not have any options to avoid generating this kind
of intrinsic for byte code. Is it possible to modify gcc and ask it take
all memset liked functions as a general function call? I know this solution
is less performance efficient, but I would like to have it for my llvm
assembly level modification works.
It's possible to write an LLVM pass that converts calls to llvm.memset() into calls to an external memset() function. You could then modify your version of llvm-gcc to run this pass.
However, is there really a problem with letting llvm-gcc use the intrinsic, even if you're compiling a C library? If the code generator replaces llvm.memset() with inline assembly code that does the same thing, then you get the correct behavior. If it modifies the llvm.memset() call to call an external memset() function, then the program ends up using the implementation of memset() from the C library that you're compiling. Either way, I'd think you'd get correct behavior.
-- John T.
SHEN Hao wrote:
Thanks a lot for your answer.
As what you said, I can not have any options to avoid generating this kind
of intrinsic for byte code. Is it possible to modify gcc and ask it take
all memset liked functions as a general function call? I know this solution
is less performance efficient, but I would like to have it for my llvm
assembly level modification works.
It's possible to write an LLVM pass that converts calls to llvm.memset()
into calls to an external memset() function. You could then modify your
version of llvm-gcc to run this pass.
However, is there really a problem with letting llvm-gcc use the
intrinsic, even if you're compiling a C library? If the code generator
replaces llvm.memset() with inline assembly code that does the same
thing, then you get the correct behavior. If it modifies the
llvm.memset() call to call an external memset() function, then the
program ends up using the implementation of memset() from the C library
that you're compiling. Either way, I'd think you'd get correct behavior.
Thanks for your suggestion. I am using the LLVM for a simulator related
research project. I need to modify all memory address related instructions
such as load/store, br and call. As I should modify all the call related
instructions, I can only support general functional calls. That's why I do not
like all these intrinsic instructions.
I like your suggestion of adding a LLVM pass. I think it's a good way to solve
this problem with some works. Now I am now taking a look of existing
LLVM code and I wish I can solve it ASAP.
Best regards,
Hao
SHEN Hao wrote:
Thanks a lot for your answer.
As what you said, I can not have any options to avoid generating this kind
of intrinsic for byte code. Is it possible to modify gcc and ask it take
all memset liked functions as a general function call? I know this solution
is less performance efficient, but I would like to have it for my llvm
assembly level modification works.
It's possible to write an LLVM pass that converts calls to llvm.memset()
into calls to an external memset() function. You could then modify your
version of llvm-gcc to run this pass.
However, is there really a problem with letting llvm-gcc use the
intrinsic, even if you're compiling a C library? If the code generator
replaces llvm.memset() with inline assembly code that does the same
thing, then you get the correct behavior. If it modifies the
llvm.memset() call to call an external memset() function, then the
program ends up using the implementation of memset() from the C library
that you're compiling. Either way, I'd think you'd get correct behavior.
Thanks for your suggestion. I am using the LLVM for a simulator related
research project. I need to modify all memory address related instructions
such as load/store, br and call. As I should modify all the call related
instructions, I can only support general functional calls. That's why I do not
like all these intrinsic instructions.
I like your suggestion of adding a LLVM pass. I think it's a good way to solve
this problem with some works. Now I am now taking a look of existing
LLVM code and I wish I can solve it ASAP.
Fortunately, in the lib/Target/CBackend/CBackend.cpp, I found the
CWriter::lowerIntrinsics function which is a good example for my
work. The LLVM pass can be realized based on this example.