Re: [RFC] imcc calling conventions
Benjamin Goldberg wrote: Erm, my statement was actually just an assumption that the first op would be a 'saveall' -- I haven't looked at actual imcc output. imcc does not emit any additional instructions currently. This is why I did start this thread in the first place. - imcc takes the code produced by $HL compiler *as is* and - has to figure out, what $HL actually wants to do (WRT CFG and data flow) Currently imcc checks the first few instructions of a subroutine. If a saveall is found imcc assumes, that there is no inofficial (via registers) data flow into the sub or back. If no saveall is found, imcc assumes that data are passed in registers and accounts in the CFG for this. This is all fine, to make it assemble and run the *hand crafted* test cases. But this is not the way to go (IMHO) for using imcc as a compiler for another HL. I would like to have nailed down the calling conventions and I would like to have hints in imcc's input file, that state we gonna call this sub and caller saves or callee saves, or use PDD03 ... Please imagine something like this: _main: $P0 = new Sub $P1 = new PerlArray ... many set_addr ... $P0 = $P1[$I99] invoke $P0 ret _sub1: ... _sub2: ... _sub3: ... The address, where the invoke branches to is calculated somehow then goes into an array (or may be passed from another sub) and can be anywhere. When imcc has no assumptions about calling conventions, it has to consider each label as possible branch target and has to follow the data flow. This will typically lead to a lot of spilling due to the register allocator running out of free registers. OTOH with known calling conventions imcc could optimize a few simple leafs in the call chain (of procedural code) and e.g. reorganize registers so that pushx/saveall/popx... are just thrown away. leo
Object spec
Dan, Sorry if I'm flogging a dead horse, but I just caught this call via the summarizer. Okay, here's another shot at the semantics for objects [for perl 6]. If folks, especially non-perl folks, would look this over and chime in, I'd much appreciate it. Objects have (all optional): *) Properties *) Methods *) Attributes Add to that: *) A superclass (obviously, but I consider it to be the same level as Properties, Methods and Attributes.) *) Associations, eg in UML. *) a set of Interfaces (similar to multiple inheritance; a way of grouping methods associated with a class for another to implement). eg, in Java and IDL. Associations are similar to special types of attributes, that are typically represented in Perl 5 by a collection, such as a hash, array or set - depending on whether the association is keyed, ordered or unordered. Associations may be *one way* - in which case the referred objects do not have a way of referring to the objects that contain them for that particular association. ie, like all of Perl 5's references and collections. They may be *two way* - in which case referred objects receive a `back-reference', which is another container that is the symmetric opposite of the first association. Two-way associations belong to both classes. Adding Object A to B.association is the same as adding B to A.backref. Tangram does something like this with its `back-references', as does an experimental version of the object prototyping system I have in the works. Associations may have *mutliplicity* on BOTH ends. That is, one to many, many to many, many to one, one to one relationships. Whether or not multiplicity limits are enforced on the *source* side would probably be tightly linked with whether or not the relationship is two way or one way. This information is enough to then take the object structure, and assuming you have a description of the types of attributes as well, map it to an RDBMS (say) using foreign keys, link tables et al. Actually the ability to describe attributes, and place limits on their contents that are both hints to database mapping tools and generate run-time exceptions when abused is a damned handy tool from a software engineer's perspective. Interfaces are similar to multiple inheritance from a functional perspective; a bit like adding a class to @ISA, but qualifying exactly what methods you're including, and probably not inheriting any of the attributes at all. Which of course, you may later be overriding. For what it's worth, I have most of this functionality duplicated into JavaScript. It can be co-erced into having classes, etc - you just need to rely on convention. Are you going to implement the concept of `scope' of methods/attributes? Many other languages have it, and I think in some circumstances it can help clarify the intent of code. Of course anally requiring it to be specified ends up with a language like Java :-). My humble opinion is that `public' attributes should just be implemented in terms of automatically generated accessor functions. Sorta like taking Class::Contract, Class::MethodMaker, Alzabo, Class::Tangram and recognising the common concepts - then making them all effectively obsolete by unifying the concepts into the language :-). my 2c. -- Sam Vilain, [EMAIL PROTECTED] I like a man who grins when he fights. - Winston Churchill -
[CVS ci] faster spilling and ARGDIR IN/OUT - again
During this change (recalculate BB and life info on the fly for spilled regs) I encountered another problem with the INOUT ARG_DIR argument of P-registers: set P0, P1[2] and similar instructions don't need, that P0 already exists at this instruction. P0 is set to point to a PMC located in the aggregate. This is different to, e.g. set P0, 42 where this PMC must have been brought into life some instructions earlier, probably by some new P0, .PerlSome opcode. I have currently a hack in imcc, which catches the former and sets the INOUT $1 to OUT $1. So I think: - when we have $1-vtable-foo, then the $1 should be IN - when we have $1 = $2-vtable-bar, then $1 should be OUT I know, we did have this discussion already, it was one of the first where I was involved :-) But there are still issues. imcc is the only user of the ARG_DIR params, when PMCs are involved, JIT only looks at I and N regs (currently). leo
IMCC and multiple source files
hello, Is it possible to have a program, which consists of multiple IMCC source files? So, something like this: (pseudo code, don't know IMCC (yet)) - /* File #1: */ ... call funcA ... sub funcB(x) /* do something */ end sub ... --- /* File #2 */ ... sub funcA(x) /* do something */ end sub ... call funcB(123) ... - So some function defined in File 2 will be called from File 1. Is this possible? If yes, (how) will this be checked during assembling? Are there some kind of 'header'-like files? Or, is this only possible directly in Parrot ASM? If so, how is checking done then? Regards, Klaas-Jan
Re: Using imcc as JIT optimizer
Leopold Toetsch wrote: Phil Hassey wrote: But with a processor with 16 registers (do such things exist?). Parrot would be overflowing registers that it could have been using in the JIT. RISC processor have a lot of them. But before there are unused processor registers, we will allocate P and S registers too. When a CPU has more then 4*32 free registers, we will look again. Like IA64? AFAIK it has 128 integer registers and 128 fp registers...
[perl #21457] [PATCH] sun4 jit additions
# New Ticket Created by Jason Gloudon # Please include the string: [perl #21457] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=21457 Here are some additional ops for the sun4 jit, a bit of name juggling to use templates in the jit directives and register allocation support. -- Jason -- attachment 1 -- url: http://rt.perl.org/rt2/attach/53234/40147/51b1c5/sunjit.patch Index: jit/sun4/core.jit === RCS file: /cvs/public/parrot/jit/sun4/core.jit,v retrieving revision 1.2 diff -u -r1.2 core.jit --- jit/sun4/core.jit 20 May 2002 05:33:01 - 1.2 +++ jit/sun4/core.jit 4 Mar 2003 15:09:34 - @@ -13,41 +13,180 @@ emitm_nop(NATIVECODE); } +TEMPLATE Parrot_set_x_x { +if(MAP[1] MAP[2]){ + jit_emit_mov_rr_N(NATIVECODE, MAP[1], MAP[2]); +} +else if(MAP[1]){ +jit_emit_load_N(jit_info, interpreter, 2, MAP[1]); +} +else if(MAP[2]){ +jit_emit_store_N(jit_info, interpreter, 1, MAP[2]); +} +else { + jit_emit_load_N(jit_info, interpreter, 2, ISR1); + jit_emit_store_N(jit_info, interpreter, 1, ISR1); +} +} + Parrot_set_i_i { -Parrot_jit_int_load(jit_info, interpreter, 2, emitm_l(0)); -Parrot_jit_int_store(jit_info, interpreter, 1, emitm_l(0)); +Parrot_set_x_x s/_N/_i/ } -Parrot_set_i_ic { -Parrot_jit_int_load(jit_info, interpreter, 2, emitm_l(0)); -Parrot_jit_int_store(jit_info, interpreter, 1, emitm_l(0)); +Parrot_set_p_p { +Parrot_set_x_x s/_N/_i/ } -Parrot_set_n_nc { -Parrot_jit_int_load(jit_info, interpreter, 2, emitm_l(0)); -Parrot_jit_int_store(jit_info, interpreter, 1, emitm_l(0)); +Parrot_set_s_s { +Parrot_set_x_x s/_N/_i/ } Parrot_set_n_n { -Parrot_jit_int_load(jit_info, interpreter, 2, emitm_l(0)); -Parrot_jit_int_store(jit_info, interpreter, 1, emitm_l(0)); +Parrot_set_x_x s/_N/_n/ s/ISR/FSR/ +} + +TEMPLATE Parrot_set_x_xc { +if(MAP[1]){ + jit_emit_load_N(jit_info, interpreter, 2, MAP[1]); +} +else { + jit_emit_load_N(jit_info, interpreter, 2, ISR1); + jit_emit_store_N(jit_info, interpreter, 1, ISR1); +} +} + +Parrot_set_i_ic { +Parrot_set_x_xc s/_N/_i/ +} + +Parrot_set_n_nc { +Parrot_set_x_xc s/_N/_n/ s/ISR/FSR/ } Parrot_set_n_i { -Parrot_jit_float_load(jit_info, interpreter, 2, emitm_f(0)); -emitm_fitod(NATIVECODE, emitm_f(0), emitm_f(2)); -Parrot_jit_float_store(jit_info, interpreter, 1, emitm_f(2)); +/* There's no way to move a value directly between integer and floating + * point registers so the mapped integer register must be written to memory + */ +if(MAP[2]){ + jit_emit_store_i(jit_info, interpreter, 2, MAP[2]); +} + +jit_emit_load_n(jit_info, interpreter, 2, FSR1); + +/* If result register is mapped convert directly into the register */ +if(MAP[1]){ + emitm_fitod(NATIVECODE, FSR1, MAP[1]); +} +else { + emitm_fitod(NATIVECODE, FSR1, FSR2); + jit_emit_store_n(jit_info, interpreter, 1, FSR2); +} } Parrot_set_i_n { -Parrot_jit_float_load(jit_info, interpreter, 2, emitm_f(0)); -emitm_fdtoi(NATIVECODE, emitm_f(0), emitm_f(2)); -Parrot_jit_float_store(jit_info, interpreter, 1, emitm_f(2)); +if(MAP[2]){ + emitm_fdtoi(NATIVECODE, MAP[2], FSR2); +} +else { + jit_emit_load_n(jit_info, interpreter, 2, FSR1); + emitm_fdtoi(NATIVECODE, FSR1, FSR2); +} + +jit_emit_store_n(jit_info, interpreter, 1, FSR2); + +/* No float reg to integer reg move instruction available */ +if(MAP[1]){ + jit_emit_load_i(jit_info, interpreter, 1, MAP[1]); +} +} + +Parrot_set_i_nc { +if(MAP[2]){ +emitm_fdtoi(NATIVECODE, MAP[2], FSR1); +} +else { +jit_emit_load_n(jit_info, interpreter, 2, FSR2); +emitm_fdtoi(NATIVECODE, FSR2, FSR1); +} + +jit_emit_store_n(jit_info, interpreter, 1, FSR1); + +if(MAP[1]){ +jit_emit_load_i(jit_info, interpreter, 1, MAP[1]); +} +} + +TEMPLATE Parrot_binop_x_x { +int arg1, arg2; + +if (MAP[1]) { +arg1 = MAP[1]; +} +else { +arg1 = ISR1; +jit_emit_load_N(jit_info, interpreter, 1, ISR1); +} + +if (MAP[2]) { +arg2 = MAP[2]; +} +else { +arg2 = ISR2; +jit_emit_load_N(jit_info, interpreter, 2, ISR2); +} + +emitm_op(NATIVECODE, arg1, arg2, arg1); + +if(!MAP[1]){ +jit_emit_store_N(jit_info, interpreter, 1, ISR1); +} +} + +Parrot_add_i_i { +Parrot_binop_x_x s/op/add_r/ s/_N/_i/ +} + +Parrot_sub_i_i { +Parrot_binop_x_x s/op/sub_r/ s/_N/_i/ +} + +Parrot_bor_i_i { +Parrot_binop_x_x s/op/or_r/ s/_N/_i/ +} + +Parrot_bxor_i_i { +Parrot_binop_x_x s/op/xor_r/ s/_N/_i/ +} + +Parrot_band_i_i { +Parrot_binop_x_x
RE: Object spec, try 2 [x-adr][x-bayes]
And attributes are essentially member variables of objects, which you can access as $obj.foo. Another possible description of them might be lvalue methods which never take arguments, and which fetch and store class-specific pieces of data. Different classes may define their own private .foo attribute, and these will be distinct even if a class inherits from two classes who both have a .foo attribute. In perl5, attributes are roughly implemented by class instances being blessed hash members, and if more than one class uses a particular member name, they will end up colliding. Well, we aren't continuing that (collisions), are we? Mapping attributes to $object{package}:attribute=no clobber! fixes that. my %attribs_from_package_a = %object{package_A}#might return ('MY::package_A::A' = 1, # 'MY::package_A::Z' = 2) my %variety_of_attribute_a = %object:attribute_A #might return ('MY::package_a::a' = 1, # 'DEF::GHI::A' = 2 ) my %all_attribs= %object{} #might return ('DEF::GHI::A' = 2, # 'MY::package_a::A' = 2, # 'MY::package_a::Z' = 2) I suppose my %all_attribs_no_package = %object{undef?}; #would return (A=2,Z=2) or (A=1,Z=2) This maps 1 to 1 with the XMLNS recommendation. -- This message is intended only for the personal and confidential use of the designated recipient(s) named above. If you are not the intended recipient of this message you are hereby notified that any review, dissemination, distribution or copying of this message is strictly prohibited. This communication is for information purposes only and should not be regarded as an offer to sell or as a solicitation of an offer to buy any financial product, an official confirmation of any transaction, or as an official statement of Lehman Brothers. Email transmission cannot be guaranteed to be secure or error-free. Therefore, we do not represent that this information is complete or accurate and it should not be relied upon as such. All information is subject to change without notice.
Re: IMCC and multiple source files
K Stol wrote: hello, Is it possible to have a program, which consists of multiple IMCC source files? Not yet, directly. As a workaround, other files can be .include-ed into main, at least from now on, I have committed a change and a test for this. Are there some kind of 'header'-like files? No header files. The subroutines have to use global labels (with one underscore in front), like: .sub _main bsr _sub1 bsr _sub2 end .end .include file1.imc # file1.imc .sub _sub1 .. ret .end These labels and branches are resolved then (the compilation of such subs is already separate). Regards, Klaas-Jan leo
Re: [perl #21457] [PATCH] sun4 jit additions
Jason Gloudon (via RT) wrote: # New Ticket Created by Jason Gloudon # Please include the string: [perl #21457] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=21457 Here are some additional ops for the sun4 jit, a bit of name juggling to use templates in the jit directives and register allocation support. Thanks, applied. leo
Re: [perl #21389] [PATCH]Patch to stop compiler warnings in dod.c
Steve Peters (via RT) wrote: # New Ticket Created by Steve Peters # Please include the string: [perl #21389] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=21389 This patch is to stop warnings from being generated when compiling dod.c. In the function trace_active_buffers, the local variables cur_stack and entry are declared but never used. Thanks, applied. leo
Re: [perl #21386] [PATCH]Patch to eliminate compilier warnings in interpreter.c
Steve Peters (via RT) wrote: # New Ticket Created by Steve Peters # Please include the string: [perl #21386] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=21386 This patch fixes compilier warnings generated when compiling interpreter.c. In the function runops_prederef, the local variables code_size and code_end are declared but never used. This patch removes these variable declarations and stops the compilier warnings. Thanks, applied. leo
Re: [RFC] imcc calling conventions
At 7:36 PM -0500 3/3/03, Benjamin Goldberg wrote: Dan Sugalski wrote: Benjamin Goldberg wrote: Jason Gloudon wrote: Piers Cawley wrote: I think you're overlooking the restoreall done just before the jump-no-save-returnaddress operation... I see two savealls and two restorealls. But with proper tail call optimization you'd only need *one* saveall. That's why it's an optimization. Tail call optimization is a space (stack size) optimization. The scheme definition only requires space efficiency. The time optimization is important but a secondary consideration for the functional language folks. Here's an idea -- considering that the first op of every sub seems to be a 'saveall' instruction, If that's true, we need to thump IMCC some. There's no reason for this to be the first op--if the caller wanted any registers saved it had darned well beter have taken care of it itself. That's the point of caller-save, after all... Erm, my statement was actually just an assumption that the first op would be a 'saveall' -- I haven't looked at actual imcc output. By your comment, I'll assume that my earlier assumption was wildly wrong. Ben, please don't make assumptions. We've done this to death in the past, and it's all in the archives to go digging out. While there's plenty of useful metadata we can expose to imcc to get it better optimized output, the *last* thing we need is for someone to make a bunch of WAG and go off on the conversation based on them. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Object spec, try 2
Allen Short [EMAIL PROTECTED] writes: Peter == Peter Seibel [EMAIL PROTECTED] writes: Hi, I'm new to this list and haven't had a chance to grovel through the old archives yet so please forgive me for jumping in in the middle of things. Anyway, what about languages that don't attach methods to particular classes--languages that support generic functions and multimethods (i.e. a method is dispatched at runtime based on the type of more than one of its arguments.) I ask because I started looking at Parrot (and joined this list) because I was interested in the idea of writing a Common Lisp that runs on Parrot. I had looked at the CLR as a possible target and found it too tied to the single-dispatch model of methods belonging to particular classes. I was hoping things would be more flexible here. Was I hoping for too much? I'd expect defmethod/defgeneric to generate instances of a standard-generic-function and standard-method class, which holds the code and specializations, and whose methods implement CL-style dispatch; this would make for a convenient MOP, as well as providing some chance for interfacing with modules in other languages. So if I did that (and it makes sense) what are the chances that the JIT would be able to do anything smart in the case where all the methods defined on a generic function happen to be single dispatch? I'm assuming that the code to do fully general CL-style dispatching is going to be slower than the native single dispatch; in the case where all the methods *are* in fact single dispatch, I'd like to compile them to the native single dispatch rather than going through a bunch of generalized machinery. Again, apologies if this is all out of nowhere and ignorant to boot--I've just recently started looking at Parrot. -Peter -- Peter Seibel [EMAIL PROTECTED] The intellectual level needed for system design is in general grossly underestimated. I am convinced more than ever that this type of work is very difficult and that every effort to do it with other than the best people is doomed to either failure or moderate success at enormous expense. --Edsger Dijkstra
[OT] joining list, test message, delete with impunity :)
Hello all. I'm here mostly as a lurker to keep up with the evolving structure of p6, but will try to contribute something useful when I can. Good to be aboard. Paul __ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/
coroutines end and DFG
Does a couroutine end? And how? The current implementation jumps forth and back by the Binvoke opcode, one is a call coroutine the other is a yield. There seems to be no possibility, that the coroutine states, I'm finished now - with possibly meaning don't call me again. And from imcc's register allocations POV the whole coroutine stuff is a PITA, no registers are preserved, AFAIK, so a coroutines and the caller + all edges out from both do share the same registers, don't they? leo
RE: coroutines end and DFG
-Original Message- From: Leopold Toetsch [mailto:[EMAIL PROTECTED] Does a couroutine end? And how? The current implementation jumps forth and back by the Binvoke opcode, one is a call coroutine the other is a yield. There seems to be no possibility, that the coroutine states, I'm finished now - with possibly meaning don't call me again. That's correct. And from imcc's register allocations POV the whole coroutine stuff is a PITA, no registers are preserved, AFAIK, so a coroutines and the caller + all edges out from both do share the same registers, don't they? They do, except that each coroutine has its own user stack so saveall and restoreall can work properly. -- jonathan sillito
RE: Object spec
Sam Vilain: # Okay, here's another shot at the semantics for objects [for # perl 6]. # If folks, especially non-perl folks, would look this over and chime # in, I'd much appreciate it. # Objects have (all optional): # *) Properties # *) Methods # *) Attributes # # Add to that: # *) A superclass (obviously, but I consider it to be the # same level as # Properties, Methods and Attributes.) Superclass*es*. Perl 5 has MI, and I don't expect that to change in Perl 6. Parrot absolutely *must* support Perl, or it has failed in its primary goal. # *) Associations, eg in UML. I've deleted your stuff about associations below, which described their properties nicely, but didn't explain what they *are*. What are they and when would you use them? Can they be implemented in terms of properties and/or attributes? # *) a set of Interfaces (similar to multiple inheritance; a way of # grouping methods associated with a class for another to # implement). # eg, in Java and IDL. Can this be implemented in terms of MI and/or delegation? (For Perl 6's part, my understanding is that an interface is just a class that inherits from Interface--although I could *easily* be wrong about that.) # Are you going to implement the concept of `scope' of # methods/attributes? # Many other languages have it, and I think in some # circumstances it can # help clarify the intent of code. Of course anally requiring it to be # specified ends up with a language like Java :-). If you mean public/private, yes. If you mean lexically-scoped methods and such...they have been proposed for Perl 6, although implementing them is non-trivial. # My humble opinion is that `public' attributes should just be # implemented in # terms of automatically generated accessor functions. The attribute slots in a Parrot object are private to the object (and, by extension, any classes it is a member of), so access will be mediated through accessors. --Brent Dax [EMAIL PROTECTED] @roles=map {Parrot $_} qw(embedding regexen Configure) How do you test this 'God' to prove it is who it says it is? If you're God, you know exactly what it would take to convince me. Do that. --Marc Fleury on alt.atheism
c-style assembly in .pasm
In my ongoing quest to understand the possibilities (and possible limitations) of parrot, here's another one. ;-) How close a mapping can there be between regular (x86 in this example) assembly (as generated by c-compilation) and pasm? I can't figure out if the stack ops can approximate this kind of thing. Issues I don't understand are inline in the assembly. ---test.c- int main(){ int i=5; i++; } -test.s main: pushl %ebp movl%esp, %ebp subl$8, %esp ; Is there a stack pointer to move? andl$-16, %esp movl$0, %eax subl%eax, %esp movl$5, -4(%ebp); Is there any analogue to bit/byte sized offsets? leal-4(%ebp), %eax ; Or is the granularity strictly at the item level? incl(%eax); can you modify an element on the stack in place? leave ret -Tupshin