Johannes Doerfert via llvm-dev
2021-Nov-01 15:05 UTC
[llvm-dev] Proposal: writing calls that can nevertheless be removed
I assume you cannot make `Singleton` a "non-exposed" symbol, correct? At the end of the day it is that global visibility/linkage that is problematic not necessarily the function. ~ Johannes On 11/1/21 07:27, Max Kazantsev via llvm-dev wrote:> Hello everyone, > > I have a proposal to introduce a function attribute to solve a dead code elimination problem for singleton-get-like functions. Imagine the following code: > > MyObj *Singleton = nullptr; > > MyObj *getUnique() { > if (Singleton) > return Singleton; > Singleton = <idempotent initialization> > } > > Here getUnique is the only accessor of Singleton variable, which cannot be otherwise read or written. > > This function is formally writing memory, but it has 2 important properties: > - This function is idempotent, meaning that its result only depends on parameters (which is empty in this case); > - If the result of the call is not used, it can safely be deleted without causing any problems. > > In other words, if we have code like > > for (int I = 0; I < 1000; I++) { > getUnique(); > } > > We can consider this loop dead and just delete it. Note that currently, because getUnique may write external memory, we cannot do so (even if we inline it and cleanse the remaining code, we'll still have a store to Singleton). > > In Java world, motivation for this is Object identity hash code. It requires to return the same value for the same object every time, it may write memory (usually it computes hash on 1st invocation<https://srvaroa.github.io/jvm/java/openjdk/biased-locking/2017/01/30/hashCode.html> basing on current address and stores it to the object). But if the hash code result is not used, it's completely fine to skip this invocation. > > In current function attributes, I could not find anything that could express "this is a mem-writing idempotent function which is OK to delete if trivially dead". Optimization prospects for this are great: we can simply DCE them. > > Do you think it's work having such attribute? > > Best regards, > Max > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Max Kazantsev via llvm-dev
2021-Nov-01 15:34 UTC
[llvm-dev] Proposal: writing calls that can nevertheless be removed
Right, but how is it a problem? Whoever sets this attribute wields all responsibility for its correctness, so it's used when appropriate. --Max -----Original Message----- From: Johannes Doerfert <johannesdoerfert at gmail.com> Sent: Monday, November 1, 2021 10:06 PM To: Max Kazantsev <mkazantsev at azul.com>; llvm-dev at lists.llvm.org Cc: Dmitry Makogon <dmakogon at azul.com>; Artur Pilipenko <apilipenko at azul.com> Subject: Re: [llvm-dev] Proposal: writing calls that can nevertheless be removed I assume you cannot make `Singleton` a "non-exposed" symbol, correct? At the end of the day it is that global visibility/linkage that is problematic not necessarily the function. ~ Johannes On 11/1/21 07:27, Max Kazantsev via llvm-dev wrote:> Hello everyone, > > I have a proposal to introduce a function attribute to solve a dead code elimination problem for singleton-get-like functions. Imagine the following code: > > MyObj *Singleton = nullptr; > > MyObj *getUnique() { > if (Singleton) > return Singleton; > Singleton = <idempotent initialization> } > > Here getUnique is the only accessor of Singleton variable, which cannot be otherwise read or written. > > This function is formally writing memory, but it has 2 important properties: > - This function is idempotent, meaning that its result only depends on > parameters (which is empty in this case); > - If the result of the call is not used, it can safely be deleted without causing any problems. > > In other words, if we have code like > > for (int I = 0; I < 1000; I++) { > getUnique(); > } > > We can consider this loop dead and just delete it. Note that currently, because getUnique may write external memory, we cannot do so (even if we inline it and cleanse the remaining code, we'll still have a store to Singleton). > > In Java world, motivation for this is Object identity hash code. It requires to return the same value for the same object every time, it may write memory (usually it computes hash on 1st invocation<https://srvaroa.github.io/jvm/java/openjdk/biased-locking/2017/01/30/hashCode.html> basing on current address and stores it to the object). But if the hash code result is not used, it's completely fine to skip this invocation. > > In current function attributes, I could not find anything that could express "this is a mem-writing idempotent function which is OK to delete if trivially dead". Optimization prospects for this are great: we can simply DCE them. > > Do you think it's work having such attribute? > > Best regards, > Max > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev