volatile int foo = 0;
/* ... */
transaction {
foo = some_function(foo);
}
I want to be able to determine when a memory load will have a
corresponding memory write later within the current transaction. For
cases like the one above, finding this out is trivial: just look for
matched memory loads and stores. But what if the load or store happen
in another function, like a getter/setter method? Like this:
volatile int foo = 0;
int get_foo(void) { return foo; }
void set_foo(int x) { foo = x; }
/* ... */
transaction {
set_foo(some_function(get_foo()));
}
I don't need to detect all cases, just as many as possible. Is there a
decent way to do this? I'm afraid I'm a newbie to compiler theory, so
if there's a well-established type of analysis that would fit this
problem, just telling me what it's called would be very helpful.
Thanks,
-Peter
If the optimizer first does extensive inlining of calls within
transactions, then conventional basic block (DAGs, value numbering,
etc.) and intra-procedural flow analysis will work fine. Otherwise,
it will take inter-procedural (also called global) flow analysis. This
has traditionally been much trickier, but maybe not so much within
modern frameworks like LLVM (llvm.org).
I have implemented something very similar and the implementation
details, detection efficiency and performance results are published in
ACM TOPLAS Volume 18 , Issue 6 (November 1996) Pages: 659 - 682.
The detection efficiency can be affected by conditional branches
between the load and the store, and some other issues explained in the
paper.
Jonas