public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
* lvalues and rvalues
@ 2015-01-01  0:00 Dibyendu Majumdar
  2015-01-01  0:00 ` David Malcolm
  0 siblings, 1 reply; 3+ messages in thread
From: Dibyendu Majumdar @ 2015-01-01  0:00 UTC (permalink / raw)
  To: jit

I am still trying to get the lvalue / rvalue concepts so that I know
exactly what to use when.

I have struct with a pointer member.

struct X {
 struct Y *base;
};

Now this pointer base can be updated while the function is running so
I need the value of the pointer refreshed (loaded) whenever it can
potentially change. In LLVM I emit explicit load instructions which
are then optimized so that any redundant loads are deleted. What would
be the equivalent method here? Should I just use a rvalue reference?
Will this be automatically refreshed? Should I use a local variable
and assign the value of the base pointer to it explicitly (i.e.
similar to explicit load) ?

Thanks and Regards

Dibyendu

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: lvalues and rvalues
  2015-01-01  0:00 ` David Malcolm
@ 2015-01-01  0:00   ` Dibyendu Majumdar
  0 siblings, 0 replies; 3+ messages in thread
From: Dibyendu Majumdar @ 2015-01-01  0:00 UTC (permalink / raw)
  To: David Malcolm; +Cc: jit

On 15 June 2015 at 01:38, David Malcolm <dmalcolm@redhat.com> wrote:
> Typically if you have a pointer chain to something that's visible
> outside of local scope then the optimizer can't know whether or not
> something else is writing to the ptr, so the generated code has to
> re-read it each time.
>
>> Should I use a local variable
>> and assign the value of the base pointer to it explicitly (i.e.
>> similar to explicit load) ?
>
> That's worth doing if you know more than the optimizer can about when
> the value can change (e.g. if you're calling some function, and know
> that the value can't be changed by it, whereas the optimizer has to
> assume that it might touch it).
>

In the Lua interpreter the code does this exactly. However I set the
variable on every instruction I compile on the assumption that if the
variable is not involved in an external call between bytecodes and
there are no steps that modify the value stored in the variable then
the optimizer will do away with the redundant assignments. This seems
to be true in LLVM once appropriate aliasing metadata is provided. I
would hope that the gcc optimizer will do the same.

Setting the variables manually is problematic due to the unforeseen
interaction of basic blocks ... I would rather err on the side of
correctness. I did consider doing this manually initially but gave up
the idea when I found I could not reason about the way the blocks
would interact and what it would do to the assumptions I made.

Regards

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: lvalues and rvalues
  2015-01-01  0:00 lvalues and rvalues Dibyendu Majumdar
@ 2015-01-01  0:00 ` David Malcolm
  2015-01-01  0:00   ` Dibyendu Majumdar
  0 siblings, 1 reply; 3+ messages in thread
From: David Malcolm @ 2015-01-01  0:00 UTC (permalink / raw)
  To: Dibyendu Majumdar; +Cc: jit

On Sun, 2015-06-14 at 11:08 +0100, Dibyendu Majumdar wrote:
> I am still trying to get the lvalue / rvalue concepts so that I know
> exactly what to use when.
> 
> I have struct with a pointer member.
> 
> struct X {
>  struct Y *base;
> };
> 
> Now this pointer base can be updated while the function is running so
> I need the value of the pointer refreshed (loaded) whenever it can
> potentially change. In LLVM I emit explicit load instructions which
> are then optimized so that any redundant loads are deleted. What would
> be the equivalent method here? Should I just use a rvalue reference?

Just use an gcc_jit_rvalue *: it represents an expression tree.

> Will this be automatically refreshed?

Yes.  libgccjit will generate code for the expression tree.

In theory the generated code will re-evaluate the full expression tree
each time, but some of that code may get optimized away if you've got
optimizations enabled, but only when the optimizer can "know" that it is
safe.  Typically if you have a pointer chain to something that's visible
outside of local scope then the optimizer can't know whether or not
something else is writing to the ptr, so the generated code has to
re-read it each time.

> Should I use a local variable
> and assign the value of the base pointer to it explicitly (i.e.
> similar to explicit load) ?

That's worth doing if you know more than the optimizer can about when
the value can change (e.g. if you're calling some function, and know
that the value can't be changed by it, whereas the optimizer has to
assume that it might touch it).

Local variables are much more "optimizable" than accesses to memory,
especially memory that might get touched in a function call.  GCC
internally uses an SSA representation and can do a lot of
simplifications to uses of local vars.

It may be worth reading:
https://gcc.gnu.org/onlinedocs/jit/intro/tutorial04.html#behind-the-curtain-how-does-our-code-get-optimized

and playing with:

gcc_jit_context_set_bool_option (state.ctxt,
                                 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
                                 1);
gcc_jit_context_set_bool_option (state.ctxt,
                                 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
                                 1);

to see what happens to the code you supply.

> Thanks and Regards

Hope the above makes sense
Dave


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-06-15 19:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-01  0:00 lvalues and rvalues Dibyendu Majumdar
2015-01-01  0:00 ` David Malcolm
2015-01-01  0:00   ` Dibyendu Majumdar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).