Melvin Smith writes: > My email was concerned with storing/retrieving multiple variables > with a single lookup, not with hinting to the compiler.
Okay. Can you show an example of this optimization. I'd rather see it in a HLL talking about PIR, as opposed to in PIR itself.
Sure, although what I am talking about is something that the compiler would insert itself, not something we would expose at the HLL.
But anyway, a typical module with package variables (syntax may vary) might do:
package MyLDAP;
import LDAPLib;
# Package variables string top = "dn=foo, cn=bar, co=blah"; string user = "melvin"; string password = "abcd";
sub do_something { do_something_else(top, type, user); }
Assume that the 3 variables are commonly used in this package (in various routines).
Assume that there are other variables and constants that are private to this package.
Or forget package altogether, they might be globals.
The Parrot translation of the sub do_something() has to fetch the 3 package variables
every invocation.
.sub _do_something .local string top .local string user .local string password top = fetch "MyLDAP::top" user = fetch "MyLDAP::user" password = fetch "MyLDAP::password" _do_something_else(top, user, password) .end
This would translate to bytecode that assigns 3 registers to the variables. Each invocation those registers get initialized by a fetch (hash lookup).
For the simple case, I'd like IMCC to look at the package (all subs) and compute a use-count of certain variables, pre-package the N most common (4, 8?) into a register block, and restore that block of registers at the entrance of the routine, rather than doing the 3 fetch lookups.
# Beware pseudo-ops :)
_do_something:
fetch P29, "MyLDAP::top"
fetch P30, "MyLDAP::user"
fetch P31, "MyLDAP::password"
_do_someting_else(P29, P30, P31) # Assume the fetch worked for the top 4 regs
Changes to:
_do_something:
fetchreggroup "MyLDAP::g1" # 1 lookup and you get all 3
_do_someting_else(P29, P30, P31) # Assume the fetch worked for the top 4 regs,
# so P28 just gets clobbered with a NULL
I can see some potential problems to solve with regards to some languages where variables are dynamic and can be "undefined", such as Perl6, but the optimization would certainly work for constants in all languages. The only problem with Perl6 would be if a global or package variable's address changed after it was stored in the register group at bytecode load time, (which could probably happen).
Anytime we cache something dynamic, we have to make sure the caches know about changes. I think that is where notifications might help.
For constants it is easy. IMCC might say, "this routine requires us to intialize
at least 3 registers with a constant value, lets make it into a register block"
This may be a premature optimization, but for certain cases I think its pretty nifty.
-Melvin