Re: Perl 6's Exporter
On Sun, Dec 23, 2001 at 01:58:32AM -0500, Michael G Schwern wrote: On Sat, Dec 22, 2001 at 09:20:08PM -0800, Brent Dax wrote: I do think that we should get rid of '!symbol' and especially '/regex/'; they seem like an unnecessary complication. Yeah, chuck 'em. It would be interesting to see how often that's getting used. I'd agree. But I'd expect that Exporter::NG's internals would be extensible enough that it would be possible for Exporter::NG::KitchenSink to add that functionality to Exporter::NG without having to re-implement anything of Exporter::NG [All hot air, no patch. oops] Nicholas Clark
Re: Perl 6's Exporter
On Sat, Dec 22, 2001 at 07:47:31PM -0500, Michael G Schwern wrote: I've rearranged the proposed features a bit to put the long objections at the bottom. Brent Dax wrote: I've been thinking about improvements that could be made to Exporter for Perl 6. 3. Warnings about conflicts: use warnings 'Exporter'; sub Dumper { ... } use Data::Dumper qw(Dumper); #prints out a warning (not just 'redefined subroutine', either). This would be nice. In fact, it could be retrofitted onto perl5's Exporter. 4. For modules, saying 'use Exporter' should be enough to get import. If you don't want Exporter's import(), just Cuse Exporter(). Very nice. Exporter::Lite does just that. What actually stops us retrofitting that onto perl5's exporter? put import (or export or some other simple name) into EXPORT_OK for Exporter, and if Exporter is called to export that function from Exporter's namespace, it knows it's being requested to act as Exporter for a non-OO caller. [either by messing with the callers @ISA (documented as doing this) or by placing a closure into the caller's namespace to act as an OO call to Exporter::import, or something such like] What is bad about this, apart from we're creating a new interface that perl6 may not like? [and doing something that perl6 isn't doing is bad enough not to do it] Nicholas Clark
Re: Perl 6's Exporter
On Mon, Dec 24, 2001 at 01:11:21PM +, Nicholas Clark wrote: 4. For modules, saying 'use Exporter' should be enough to get import. If you don't want Exporter's import(), just Cuse Exporter(). Very nice. Exporter::Lite does just that. What actually stops us retrofitting that onto perl5's exporter? If we did everyone would still say @ISA = qw(Exporter) to be backwards compatible, so I don't know what the benefits would be. Also it would cause subroutine redefined warnings in this sort of code: use Exporter; sub import { ... Exporter::export_to_level(...); } -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Plus I remember being impressed with Ada because you could write an infinite loop without a faked up condition. The idea being that in Ada the typical infinite loop would be normally be terminated by detonation. -- Larry Wall in [EMAIL PROTECTED]
Re: Perl 6's Exporter
On Mon, Dec 24, 2001 at 04:22:33PM +, Nicholas Clark wrote: Also it would cause subroutine redefined warnings in this sort of code: use Exporter; sub import { ... Exporter::export_to_level(...); } Not if it's in EXPORT_OK, surely? Oh, I was thinking @EXPORT. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One We don't know. But if we did, we wouldn't tell you.
Re: JIT me some speed!
On Fri, Dec 21, 2001 at 12:03:51AM +, Tom Hughes wrote: It looks like it is going to need some work before it can work for other instruction sets though, at least for RISC systems where the operands are typically encoded with the opcode as part of a single word and the range of immediate constants is often restricted. I'm thinking it will need some way of indicating field widths and shifts for the operands and opcode so they can be merged into an instruction word and also some way of handling a constant pool so that arbitrary addresses can be loaded using PC relative loads. Another thing that struck me on reading it was: =item CBIRIn Place the address of the CINTVAL register specified in the Inth argument. RISC chips have lots of general purpose registers. It's likely that there will be enough spare that several can be used to map to parrot registers. Say 4 are available, it would be useful to be able to say that an op requires the value of rN and rM, and modifies rD. The JIT compiler would make a sandwich with the code to read in N and M into two of the real CPU registers, the op filling, and then some more code to write D back to memory. However, if the JIT can see that N is already in memory from the previous OP, or D is going to be used and modified by the next op, it can skip, defer or whatever some of the memory reads and writes. [And provided the descriptions are this helpful it doesn't have to do it immediately. It becomes possible to write a better optimising JIT that makes sandwiches with multiple fillings or even Scooby Snacks, while the initial JIT insists that the only recipe available is bread, 1 filling, bread] mops will be fast if REDO: subI4, I4, I3 if I4, REDO maps to REDO: load I4 from memory (which will be in the L1 cache) load I3 from memory I4 = I4 - I3 store I4 to memory load I4 from memory is it 0? goto REDO if true it will be slightly faster if it maps to REDO: load I4 from memory (which will be in the L1 cache) load I3 from memory I4 = I4 - I3 store I4 to memory # I4 still in a CPU register is it 0? goto REDO if so and faster still if the JIT can see how to push things out of the loop: load I4 from memory load I3 from memory REDO: I4 = I4 - I3 is it 0? goto REDO if so store I4 to memory (does threading mess this idea up?) Nicholas Clark
Re: JIT me some speed!
I think we should leave all that for an optimizer. Daniel Grunblatt. On Mon, 24 Dec 2001, Nicholas Clark wrote: On Fri, Dec 21, 2001 at 12:03:51AM +, Tom Hughes wrote: It looks like it is going to need some work before it can work for other instruction sets though, at least for RISC systems where the operands are typically encoded with the opcode as part of a single word and the range of immediate constants is often restricted. I'm thinking it will need some way of indicating field widths and shifts for the operands and opcode so they can be merged into an instruction word and also some way of handling a constant pool so that arbitrary addresses can be loaded using PC relative loads. Another thing that struck me on reading it was: =item CBIRIn Place the address of the CINTVAL register specified in the Inth argument. RISC chips have lots of general purpose registers. It's likely that there will be enough spare that several can be used to map to parrot registers. Say 4 are available, it would be useful to be able to say that an op requires the value of rN and rM, and modifies rD. The JIT compiler would make a sandwich with the code to read in N and M into two of the real CPU registers, the op filling, and then some more code to write D back to memory. However, if the JIT can see that N is already in memory from the previous OP, or D is going to be used and modified by the next op, it can skip, defer or whatever some of the memory reads and writes. [And provided the descriptions are this helpful it doesn't have to do it immediately. It becomes possible to write a better optimising JIT that makes sandwiches with multiple fillings or even Scooby Snacks, while the initial JIT insists that the only recipe available is bread, 1 filling, bread] mops will be fast if REDO: subI4, I4, I3 if I4, REDO maps to REDO: load I4 from memory (which will be in the L1 cache) load I3 from memory I4 = I4 - I3 store I4 to memory load I4 from memory is it 0? goto REDO if true it will be slightly faster if it maps to REDO: load I4 from memory (which will be in the L1 cache) load I3 from memory I4 = I4 - I3 store I4 to memory # I4 still in a CPU register is it 0? goto REDO if so and faster still if the JIT can see how to push things out of the loop: load I4 from memory load I3 from memory REDO: I4 = I4 - I3 is it 0? goto REDO if so store I4 to memory (does threading mess this idea up?) Nicholas Clark
Re: JIT me some speed!
Oh, and by the BTW, I already tried you fastest example last week and got 50x speed up, but that's works only for mops, so ... Daniel Grunblatt. On Mon, 24 Dec 2001, Nicholas Clark wrote: On Fri, Dec 21, 2001 at 12:03:51AM +, Tom Hughes wrote: It looks like it is going to need some work before it can work for other instruction sets though, at least for RISC systems where the operands are typically encoded with the opcode as part of a single word and the range of immediate constants is often restricted. I'm thinking it will need some way of indicating field widths and shifts for the operands and opcode so they can be merged into an instruction word and also some way of handling a constant pool so that arbitrary addresses can be loaded using PC relative loads. Another thing that struck me on reading it was: =item CBIRIn Place the address of the CINTVAL register specified in the Inth argument. RISC chips have lots of general purpose registers. It's likely that there will be enough spare that several can be used to map to parrot registers. Say 4 are available, it would be useful to be able to say that an op requires the value of rN and rM, and modifies rD. The JIT compiler would make a sandwich with the code to read in N and M into two of the real CPU registers, the op filling, and then some more code to write D back to memory. However, if the JIT can see that N is already in memory from the previous OP, or D is going to be used and modified by the next op, it can skip, defer or whatever some of the memory reads and writes. [And provided the descriptions are this helpful it doesn't have to do it immediately. It becomes possible to write a better optimising JIT that makes sandwiches with multiple fillings or even Scooby Snacks, while the initial JIT insists that the only recipe available is bread, 1 filling, bread] mops will be fast if REDO: subI4, I4, I3 if I4, REDO maps to REDO: load I4 from memory (which will be in the L1 cache) load I3 from memory I4 = I4 - I3 store I4 to memory load I4 from memory is it 0? goto REDO if true it will be slightly faster if it maps to REDO: load I4 from memory (which will be in the L1 cache) load I3 from memory I4 = I4 - I3 store I4 to memory # I4 still in a CPU register is it 0? goto REDO if so and faster still if the JIT can see how to push things out of the loop: load I4 from memory load I3 from memory REDO: I4 = I4 - I3 is it 0? goto REDO if so store I4 to memory (does threading mess this idea up?) Nicholas Clark
Re: JIT me some speed!
On Mon, Dec 24, 2001 at 03:19:39PM -0300, Daniel Grunblatt wrote: I think we should leave all that for an optimizer. I agree with that Sorry, my point wasn't clear: I believe the current JIT description syntax precludes making a good optimiser. By making all ops pass by reference, with no information to the JIT about whether parameters are input, output, modified or not, we are making a system where a future optimising JIT can't quickly know what it can do. The current system is similar to perl5, where all subroutines are pass by reference. Pass by reference has this disadvantage that the caller can't know which parameters the subroutine expects to be able to modify. We don't need to throw out the current Place the address of the CINTVAL register specified in the Inth argument. but the sooner we give people the ability to write jit descriptions something like: Parrot_set_i_i(in,out): \x8b \x0d IR2 \x89 \x0d IR1 rather than just Parrot_set_i_i: \x8b \x0d IR2 \x89 \x0d IR1 the less we need to *redo* in future to give an optimising JIT more information to work with. The current JIT can ignore the extra information. But the extra information is there ready - we don't need to go over every opcode again when we come to write an optimising JIT. [or am I missing something - is it possible to write a tool to analyse the op descriptions and infer this information about what modifies what?] Nicholas Clark
.ops metadata [was: Re: JIT me some speed!]
Nicholas -- Parrot_set_i_i(in,out): \x8b \x0d IR2 \x89 \x0d IR1 I'm tempted to push the specification of this information all the way back to the syntax of .ops files, since the code that lives there should behave the same wrt read/write on args. Dan likes C-like syntax as much as possible in other parts of the ops file. Thats why I chose 'inline' as the tag for 'trivial' ops (although that's a C++-ism). If we didn't mind the verbosity, a C-like syntax would be: inline op set(register INTVAL, const register INTVAL) { $1 = $2; } instead of inline op set(i, i) { $1 = $2; } The problem is, we lose the nice space/time/etc. saving capability of: inline op set(i, i|ic) { $1 = $2; } But, we could still adopt the C-ism 'const' as meaning read-only, and assume all non-const arguments are written: inline op set(i, const i|ic) { $1 = $2; } Or, do we really need to have the three-way in/out/inout tagset? inline op set(out i, in i|ic) { $1 = $2; } Regards, -- Gregor /Inspiration Innovation Excellence (TM)\ Gregor N. Purdy [EMAIL PROTECTED] Focus Research, Inc. http://www.focusresearch.com/ 8080 Beckett Center Drive #203 513-860-3570 vox West Chester, OH 45069 513-860-3579 fax \/ [[EMAIL PROTECTED]]$ ping osama.taliban.af PING osama.taliban.af (68.69.65.68) from 20.1.9.11 : 56 bytes of data. From 85.83.77.67: Time to live exceeded
RE: .ops metadata [was: Re: JIT me some speed!]
Gregor N. Purdy: # Parrot_set_i_i(in,out): \x8b \x0d IR2 \x89 \x0d IR1 # # I'm tempted to push the specification of this information all the way # back to the syntax of .ops files, since the code that lives there # should behave the same wrt read/write on args. # # Dan likes C-like syntax as much as possible in other parts of the ops # file. Thats why I chose 'inline' as the tag for 'trivial' ops # (although # that's a C++-ism). # # If we didn't mind the verbosity, a C-like syntax would be: # # inline op set(register INTVAL, const register INTVAL) { # $1 = $2; # } # # instead of # # inline op set(i, i) { # $1 = $2; # } # # The problem is, we lose the nice space/time/etc. saving capability of: # # inline op set(i, i|ic) { # $1 = $2; # } # # But, we could still adopt the C-ism 'const' as meaning read-only, and # assume all non-const arguments are written: # # inline op set(i, const i|ic) { # $1 = $2; # } # # Or, do we really need to have the three-way in/out/inout tagset? # # inline op set(out i, in i|ic) { # $1 = $2; # } Or we could go with the Perl 6-ism: inline op set(i is rw, i|ic) { $1=$2; } --Brent Dax [EMAIL PROTECTED] Configure pumpking for Perl 6 Nothing important happened today. --George III of England's diary entry for 4-Jul-1776
Peaceful coexistence (for 5 and 6)
We have an empty 'less' pragma in Perl 5, right? use less '6'; use less '6' = 'path/to/perl/6/version'; --Brent Dax [EMAIL PROTECTED] Configure pumpking for Perl 6 Nothing important happened today. --George III of England's diary entry for 4-Jul-1776
[COMMIT] More JIT from Daniel Grunblatt
All -- I've just committed the latest patch from Daniel Grunblat: * Ops added set_s_s, set_s_sc, bsr_i and eq_s_sc but using calls to C functions. * Added JUMP(END) to place the number of bytes to the end of the current op. * The *.jit files syntax changed. * Added jit/i386/lib.jit to place handly functions as jump that take as argument the address where is the opcode number to jump to. * There is a bug at some point, but I will start writting jit/i386/string.jit and jit/i386/stacks.jit so that we don't have use calls, which make the jit as slow as the interpreter. Regards, -- Gregor