If I have:
%x = call @externalFunc
... ; other codes where %x is not used
ret ; assume void function
and use dce optimization, will the call gets eliminated?
If I have:
%x = call @externalFunc
... ; other codes where %x is not used
ret ; assume void function
and use dce optimization, will the call gets eliminated?
Hi leledumbo,
If I have:
%x = call @externalFunc
... ; other codes where %x is not used
ret ; assume void functionand use dce optimization, will the call gets eliminated?
only if the compiler can prove that the called function has
no side effects (such as modifying some global variables or
causing the program to exit).
Ciao,
Duncan.
only if the compiler can prove that the called function has
no side effects (such as modifying some global variables or
causing the program to exit).
can it prove if the function resides in a shared library?
only if the compiler can prove that the called function has
no side effects (such as modifying some global variables or
causing the program to exit).can it prove if the function resides in a shared library?
No, however it can prove it if the function is in a static library consisting
of bitcode files (what you get if you compile with -emit-llvm) and you do
link-time optimization. However it's probably simpler to declare the function
as having no side-effects using gcc's "pure" or "const" attribute.
Ciao,
Duncan.
Only if the right function attributes are added. See
http://llvm.org/docs/LangRef.html#fnattrs for a list, but
'readonly'/'readnone' and 'nounwind' will be most interesting for you
here. I guess calling abort() probably disqualifies a function for
'readonly' (and it's stronger variant 'readnone').
Currently calls to any function that has either of the readnone or
readonly attributes as well as the nounwind attribute qualify as
"trivially dead" if their results aren't used, meaning lots of
optimizations will get rid of them. (in particular, this is pretty
much the entire the job of -die and -dce, but many others will delete
them rather than change or move them if they get in the way)
As Duncan said while I was typing this, putting __attribute__((pure))
or __attribute__((const)) on the declaration will add those llvm
attributes if you're using llvm-gcc or clang to generate this llvm
assembly.
Note that there doesn't seem to be a function attribute to say "this
function won't go into an infinite loop" though, which I guess means
http://llvm.org/PR965 hasn't been fixed yet.
No, however it can prove it if the function is in a static library
consisting
of bitcode files (what you get if you compile with -emit-llvm) and you do
link-time optimization. However it's probably simpler to declare the
function
as having no side-effects using gcc's "pure" or "const" attribute.
Hmm... the library can't be made static so I guess it's OK.
Only if the right function attributes are added. See
http://llvm.org/docs/LangRef.html#fnattrs for a list, but
'readonly'/'readnone' and 'nounwind' will be most interesting for you
here. I guess calling abort() probably disqualifies a function for
'readonly' (and it's stronger variant 'readnone').
Currently calls to any function that has either of the readnone or
readonly attributes as well as the nounwind attribute qualify as
"trivially dead" if their results aren't used, meaning lots of
optimizations will get rid of them. (in particular, this is pretty
much the entire the job of -die and -dce, but many others will delete
them rather than change or move them if they get in the way)
Without those attributes, will the optimizer assume something?
Actually, I don't use llvm-gcc here. I'm creating a compiler for a language
defined by my professor that generates llvm assembly language, for my
bachelor graduation project. The language is database centric but isn't
tight to any database implementation. For my implementation, it's decided to
use postgresql, and to concentrate more in the language rather than the
database I create a shared library for most commonly database related
functionality (connect, disconnect, getting error message, query) so I can
just declare and call it from the generated llvm assembly.
What I'm afraid of is, for example, return value of a call to connect
function may be ignored, and the optimizer will eliminate the call due to
this.
Hi,
leledumbo wrote:
No, however it can prove it if the function is in a static library
consisting
of bitcode files (what you get if you compile with -emit-llvm) and you do
link-time optimization. However it's probably simpler to declare the
function
as having no side-effects using gcc's "pure" or "const" attribute.Hmm... the library can't be made static so I guess it's OK.
Only if the right function attributes are added. See
http://llvm.org/docs/LangRef.html#fnattrs for a list, but
'readonly'/'readnone' and 'nounwind' will be most interesting for you
here. I guess calling abort() probably disqualifies a function for
'readonly' (and it's stronger variant 'readnone').
Currently calls to any function that has either of the readnone or
readonly attributes as well as the nounwind attribute qualify as
"trivially dead" if their results aren't used, meaning lots of
optimizations will get rid of them. (in particular, this is pretty
much the entire the job of -die and -dce, but many others will delete
them rather than change or move them if they get in the way)Without those attributes, will the optimizer assume something?
It will assume that the function could do absolutely anything, which forbids pretty much any optimization.
Actually, I don't use llvm-gcc here. I'm creating a compiler for a language
defined by my professor that generates llvm assembly language, for my
bachelor graduation project. The language is database centric but isn't
tight to any database implementation. For my implementation, it's decided to
use postgresql, and to concentrate more in the language rather than the
database I create a shared library for most commonly database related
functionality (connect, disconnect, getting error message, query) so I can
just declare and call it from the generated llvm assembly.What I'm afraid of is, for example, return value of a call to connect
function may be ignored, and the optimizer will eliminate the call due to
this.
No of course not. Nobody ever checks the return value of printf, for example.
The only special case is if you name your function something that exists in the C standard library; if you name your function "malloc" we're going to remove calls to it with unused results.
Nick
If I have:
%x = call @externalFunc
... ; other codes where %x is not used
ret ; assume void functionand use dce optimization, will the call gets eliminated?
only if the compiler can prove that the called function has
no side effects (such as modifying some global variables or
causing the program to exit).Wasn't there some efforts/investigation to support marking
of (body-less) functions as 'pure'? Is this on the roadmap?
At the level of the original C source you can do this using gcc's "pure" and
"const" attributes. At the level of LLVM IR, you can use the "readonly" and
"readnone" attributes.
Ciao,
Duncan.
No of course not. Nobody ever checks the return value of printf, for
example.The only special case is if you name your function something that exists
in the C standard library; if you name your function "malloc" we're
going to remove calls to it with unused results.
OK, sounds I'm on the right way
At the level of the original C source you can do this using gcc's "pure"
and
"const" attributes. At the level of LLVM IR, you can use the "readonly"
and
"readnone" attributes.
This makes things clearer.
Thanks to all.