## Udell at OSCON: IronPython news

Udell reports:

"When you think about it," Hugunin said, "why would the CLR be worse for dynamic languages than the JVM, given that Microsoft had the second mover advantage?" And in fact, while he had to do plenty of extra work to support dynamic features that the CLR doesn't natively offer, he notes that the massive engineering resources invested in the CLR make it highly optimized along a number of axes. So, for example, the CLR's function call overhead is apparently less than the native-code CPython's function call overhead, and this is one of the reasons why IronPython benchmarks well against CPython.

## Comment viewing options

### LLVM

Myself, I wonder why languages don't adopt wonderfully portable, open-source, optimizing back-ends like the Low Level Virtual Machine. Being lower level than the JVM or CLR, it can implement either, and can do JIT, C source output, or straight machine code.

### LLVM

Last time I checked, LLVM didn't provide many of the semantics needed and provided by the CLR (for example the overflow detection arith opcodes). It also seems that the sources only have x86 and sparc ports.
Mono, on the other hand, has JIT support for x86, ppc, sparc, s390 in cvs and sparc64 and amd64 currently in the works (with more ports planned soon, it has also been ported to Itanium by a third-party). So simple languages may get away with using llvm, but interactive languages like python, if the python semantics can be implemented efficiently in llvm, would be quite limited if they needed to use the C backend of llvm to achieve portability.

### Reinvented Wheels

That statement postulates a horse race between different animals. LLVM is low-level by design. LLVM can do things that MONO cannot, such as emit C code, which will then work on any processor, or ditch the garbage collector. A PowerPC back end for LLVM is well underway, but the C code output works now.

The chip-portability issue argues for ILs coupled to language-specific runtimes, as opposed to "common language," one-size-fits-all runtimes. Consider how long it has taken MONO to reach barely-half-functional 1.0 status - years, and still lacking iceberg-sized chunks of Microsoft's platform. Now put a new chip under MONO, and see how long the port takes. MONO duplicated a ton of work. Had MONO used LLVM from the beginning, it would be much further along today. The MONO group recently abandoned WINE as well, suggesting a not-invented-here syndrome. MONO is slowing itself down.

The ideas of factored software and third-party leverage are not new. I want a decoupled back end portable to chips which don't interest MONO. I may not want the CLR, but native language runtimes. LLVM already compiles C/C++ using the GCC front end. So in principle, take any Language X (that is implemented in C/C++), and recompile. Now the language, plus all its runtimes, whether written in C/C++ or Language X, live atop a chip-portable IL. Because the IL is simple, porting to a new chip is simple(r).

If someone likes CLR or JVM, nothing prohibits them, in principle. Professor Vikram S. Adve discussed the relationship between CLR, JVM, and LLVM in a remark from one year ago. Integration is underway. Granted, it is a long-term project, but no longer than MONO. In fact LLVM could integrate into the MONO CLR project or any open-source JVM with a bit of work. That work is called factoring.

LtU has discussed LLVM and other projects like Typed Assembly Language and CCured before. There are lots of choices out there at varying levels of abstraction, and it would be nice to see manpower-strapped open-source groups exploit them.

### Reinvented Wheels

Mark, I would love for someone to develop llvm support in mono. When, about two years ago, I designed the new mono jit to replace the old, non-portable one, I was aware of llvm, but we didn't use it, because the requirements of mono are much more lower-level than what llvm provides (even today). I think you'd have a hard time implementing the CLR requirements using llvm, but I'd also love to be proved wrong (I'll also include it in cvs if it turns out to be better than the current code).

Anyway, the output to C is a nice feature, but it's not suitable to many langauges (IronPython, for example uses the jit in mono and any python port to llvm would do the same: in those cases waiting for gcc to compile the code wouldn't be a production solution).

As for the time to port mono to new platforms: it should take less than about 2 months for a basic port
and judging by the lines of code in llvm and mono sources it's about the same (6-9K lines per arch) even if mono implements many more low-level opcodes than llvm because of the needed semantics in the CLR. BTW: there are no chips that don't interest mono: if anyone has the hw and the will, we're happy to provide help and support in porting mono to it (that's the way the s390 port happened).

As you point out, there are many different free and open source projects that do something similar. But many of them cover completely different niches and it would be very difficult to make them agree to which different problem space to solve. There are 3 or more efforts, including llvm, to provide a jit-in-a-library, each with a specific focus or specific arch targets in mind. I think there are many programs and languages which could take advantage of them (compiling regexes with GNU lightning, for example, or, say, making Psyco use llvm). Sadly, mono could not use any of them, because the low-level semantics that mono needs to provide to implement the CLR efficiently are way more complicated than those libraries provide. I already made the overflow-checking arith opcodes example, but you could also consider supporting the semantics of both 32 bit and 64 bit integer additions on 64 bit architectures, or the specific handling of NaNs in FP compares etc.

Maybe in the future we'll provide a JIT interface exposed by libmono that lets people avoid the IL step, so libmono could become a general purpouse jit library, independent of the CLR. What does people think of this idea?

### .TRAP

Surely MONO talked to LLVM and other groups before going it alone. Please post those links for reference.

Adding missing features usually beats building from scratch. Cooperation has benefits and fragmentation has costs. Had MONO layered on a third party kit, then today that kit, MONO, and all their users would enjoy more benefits. I'm not certain that MONO is really doing what makes the most technical sense. The WINE folks begged MONO to help them address MONO-specific problems for everyone's benefit. The LLVM folks also show an interest in CLR integration, for what it may be worth now.

the output to C is a nice feature, but it's not suitable to many languages

C enables these languages to run on embedded devices, or integrate with C++ projects. There are many uses for C output. Not everyone wants CLR language integration, or for that matter, even JITing. Some of us prefer static compilation, and weaker embedded devices require it.

it should take less than about 2 months for a basic port

I don't buy that. However, C code ports in two days. That is another major use for C output.

Microsoft's cheerleading for MONO bears scrutiny. If Microsoft sincerely wants .NET on Linux, then what makes maximum sense is release of .NET as open source (compiler, runtime, and all), or an in-house port to Linux. When Microsoft last made noises about open source, the choices emphatically did not include Linux. Maybe someone has news on that front. I don't follow Microsoft's twists and turns very well. It stands to reason that they will continue advancing .NET while MONO trails perpetually 2-3 years behind. That strategy makes Windows seem superior. My own money is on superior alternatives to the .TRAP set by Microsoft.

### Technical issues and MS fear

Mark, it looks like you're grumpy against mono and MS.
It's not productive for me to talk about technical issues, when you have no intention to address them and
start insulting us (to keep the post barely on topic, I wouldn't say that mono is barely half-functional as you put it, since it runs IronPython, IKVM, and several other programs, both open source and not). I'll just restate a few things for the benefit of people that might be reading the thread.

Surely MONO talked to LLVM and other groups before going it alone.
Nope, I didn't contact the llvm developers two years ago: I read their documentation and source and decided it was unsuitable as a foundation for mono, for the technical reasons I already explained. I might have been wrong, of course: if the llvm developers want to prove me wrong, I'd be happy to help them with guidance about how to integrate llvm in mono, but I'm not going to do the work myself, I have plenty on my plate already:-) I'm sure the llvm developers are nice people and you might be doing just a disservice to them with your attitude here.

About the C output: as I said it's nice for some things, we had a C backend for mono, too, a couple of years ago. The issue is that it is useless in practice in the context of the CLR, so it doesn't make sense to bring it up again as one reason why mono should have used llvm (how do you guarantee tail calls happen with a C backend? Mono has needs that are not easily implemented in C).

You may not believe me on the time to port mono to new cpus, but you can check the cvs logs and you'll see that the ppc port was able to run mcs and compile programs in just a little more than 2 months of active development (mcs is a C# compiler implemented in C# and it exercizes quite a bit of the runtime and JIT during compilation). The ppc port was the first non-x86 port, so other ports should and did take less effort: sparc was done by Zoltan mostly in his spare time, amd64 is in very good shape just after a month of development (yes, Zoltan is a great hacker:-).

It stands to reason that they will continue advancing .NET while MONO trails perpetually 2-3 years behind.

Sure, but this doesn't matter much: mono is interested in compatibility with MS because this allows us to use other peoples efforts, like IronPython and IKVM. For example, I'm sure Dan would have liked having a python compiler written for Parrot by somebody else, so he could focus on parrot itself:-) The primary focus of mono is to provide a good development environment for Linux and other unix-based systems, MS compatibility is just a side effect (and quite fruitful, if we consider IrobPython, IKVM and lots of contributions to mono happened because of that compatibility).

It's true, we lag behind MS in many areas, but we're also ahead in others, like DB interfaces, portability, even performance in some cases. This is not surprising, since we were just 5 people for a lot of time against the hundreds working on .Net at MS. With the limited resources we had we did quite well (and we did reuse other people's code when it made sense, see our use of libgc and the several bugfixes we contributed to them).

### Retargeting VMs

Surely MONO talked to LLVM and other groups before going it alone. Please post those links for reference.

Adding missing features usually beats building from scratch.

Are you basing this on experience with other retargeted virtual machine projects? Please posts links for reference. ;)

Seriously, I don't think that you can reasonably make the claim that it would have made sense to base a CLR implementation on a pre-existing VM, no matter how low-level that VM is, without a serious amount of detailed knowledge of the systems in question. And with that detailed knowledge, you'd most likely find that the systems didn't match up very well.

BTW, I saw a pretty good demo of Mono 1.0 at Usenix in June. Based on what I saw, I'm not inclined to second-guess how they got there. They've done some amazing work, I think[*]. Regardless of any Microsoft .TRAPs, I think Linux is better off having the Mono option than not.

[*] Perhaps I'm unduly influenced by the cute stuffed Ximian monkey I was given for asking Miguel a question... :)

### Low-level requirements

I was aware of llvm, but we didn't use it, because the requirements of mono are much more lower-level than what llvm provides (even today).

Not that I know anything about LLVM, but, out of curiousity, can you give some examples?

[Ah, I see you mentioned overflow trapping in a message above. Any others, then?]

Oh, and:

So simple languages may get away with using llvm, but interactive languages like python, if the python semantics can be implemented efficiently in llvm, would be quite limited if they needed to use the C backend of llvm to achieve portability.

What has interactivity got to do with it?

### Low-level requirements

I already mentioned overflow checking and tail calls (how would the C backend implement them?). A few others come to mind: both ordered and unordered FP compares must be exposed (it's true you could insert calls to finite()/isnan() from libc, but it would be dead slow), the precision at which FP ops happen needs to be carefully controlled (for example, on x86, you can't use 80 bits precision in the FP stack and spill the temporaries at 64 bit precision), it doean't look like llvm exposes widening instructions (byte/sbyte to short/ushort etc), the vararg call conv needs to be implemented in a specific way (the called function knows the types of the arguments for each invocation). Most of these things are trivial, but they amout to about half of the complexity of the low-level code emitter: implementing the rest of it may take just a day of work or so. There are other areas in the JIT that are more complicated and that take most of the time to do a port: handling jit trampolines (llvm has some code, but it wouldn't handle interface calls on valuetype in the CLR or indirect calls like what could happen with tail calls or delegates). And the hardest part of the port is exception handling (which doesn't seem to be implemented in llvm in the x86 in version 1.2): this is critical to mono and has a lot of complexities in it (stack walks, stack unwinding, finally handlers invocation etc.). There are also issues when optimizations are performed on the code: we can't just give the optimizer some code and expect it to respect all the peculiar semantics of the CLR. This means that the optimizations need to be implemented with the expected semantics in mind (like don't change the order in which implicit exceptions would be thrown and so on). There are also a lot of other features in the CLR that require tight control on the generated code (mostly related to garbage collection) that don't allow us to use other people's code as a black box that takes an intermediate representation and spits out binary code. The CLR is a complex beast to implement correctly with the expected features. So when you look at it, you have:

• Low-level code emitter (llvm implemented 90 or even 100 % of the code needed for C/C++, but barely half of the code needed for the CLR)
• the optimization framework would have needed to be audited and probably rewritten in part to address the semantic issues
• all the complex code (trampolines and exception handling) would have to be written

So, at the time (remember, this is the assessment I did about two years ago) the advantage of llvm was that it had an optimization framework that we didn't know if it was usable for our needs, the rest of the code is standard jit stuff. I don't remember the status of the llvm x86 port at the time, but that was our main target and I had the impression it was lagging the sparc code. I'd like to reduce the effort needed to port mono to new architectures and we have plans for that, but it looks like we're not doing bad in that area: we went from 1 backend to 5-6 in a year and we hope to add arm and itanium to the current cvs code as soon as possible (mips, alpha and sh are open for people to take on, btw:-).

Note, my comments are mostly related to the complexity of the CLR requirements: I'm sure llvm is a great tool for people that have simpler needs.

Frank, as for the interactivity issue: a python runtime like IronPython creates intermediated code on the fly (IL) which is jitted by mono and run: image what would happen if mono had a C backend that invoked gcc at each method call: create a C code file, run gcc, dlopen the shared library. IronPython was only ever tried by its author on windows: I was happy to see reports upon release that it worked with mono on both Linux/x86 and MacOSX without any change.

### LLVM + CLR/MSIL Support

Hi All,

I'm sorry that I didn't chime in earlier. Here are some corrections with respect to your comments, though I would like to note in particular, that all three of your bullets are just plain incorrect:

I already mentioned overflow checking and tail calls
> (how would the C backend implement them?).

Overflow checking is the one big thing that we do not handle efficiently today, but it can be inefficiently emulated. It doesn't matter if the C backend does things well or not. In particular, the C backend doesn't support accurate GC particularly efficiently either, but it DOES support it (something not true of the Mono JITs from what I know). The C backend is primarily a transition device useful for when native target support is not available yet.

both ordered and unordered FP compares must be exposed

LLVM exposes both directly.

the precision at which FP ops happen needs to be
> carefully controlled (for example, on x86, you can't
> use 80 bits precision in the FP stack and spill the
> temporaries at 64 bit precision)

LLVM, in contrast to GCC, does not spill with 64-bits of precision, it spills all 80 bits. I believe LLVM provides fully correct FP support for MSIL.

it doean't look like llvm exposes widening
> instructions (byte/sbyte to short/ushort etc)

Huh? Of course it does, the cast instruction.

the vararg call conv needs to be implemented in a
> specific way

I don't follow.

handling jit trampolines (llvm has some code, but it
> wouldn't handle interface calls on valuetype in the
> CLR or indirect calls like what could happen with
> tail calls or delegates).

Huh? Of course it does. This is conceptually the same as calling through a function pointer in C. We JIT full C and C++ programs without problem, today.

The hardest part of the port is exception handling
> (which doesn't seem to be implemented in llvm in the
> x86 in version 1.2)

It is fully implemented in LLVM 1.2.

There are also issues when optimizations are
> performed on the code: we can't just give the
> optimizer some code and expect it to respect all
> the peculiar semantics of the CLR.

I have no idea what you are talking about here, but LLVM has a BROAD range of aggressive optimizations and all preserve the semantics of the source program. In particular, I suspect that the types of semantic-invalidating transformations you are thinking about are due to traditional targets not being as expressive as LLVM.

There are also a lot of other features in the CLR
> that require tight control on the generated code
> (mostly related to garbage collection)

LLVM also provides full featured *accurate* GC support, something that Mono does not.

image what would happen if mono had a C backend that
> invoked gcc at each method call: create a C code
> file, run gcc, dlopen the shared library.

While that would be cute, the LLVM C backend does not support JITing code. :) Note that the other backends we have (X86/PPC/Sparc) work as static code generators, and the X86/Sparc codegens both work as JITs (PPC support is coming in 1.4).

Just as a general note, I would like to say that it is very possible to support MSIL extremely well in LLVM. In particular, this summer I was commisioned to BUILD a MSIL front-end for LLVM (by MS, which unfortunately means that it won't be released in the public domain). The biggest missing feature in LLVM is support for trapping overflows, but this would also be the most trivial to add to LLVM (for the purposes of the project, inefficient support is fine: trapping ops are not commonly used).

To me, I find MSIL and the CLR fascinating creations: LLVM is *designed* to support such VMs and a lot of others purposes as well. For example, LLVM supports scheme pretty well, something which is not true of the CLR. LLVM is being used by several functional and other research language front-ends purely because it is really easy to target and provides a TON of different options to the language designer.

I think that a mono JIT implemented with LLVM would be an excellent thing for BOTH projects: you would get accurate GC support, aggressive interprocedural and static optimizations for your AOT translator, and non-naive JIT generated code. For us, we would get more exposure and more happy users. However, like you, I have many other things on my plate.

If anyone is interested in discussing LLVM or a LLVM/.NET interface, the llvmdev mailing list is a great place to do so. Also, LLVM 1.3 will be out shortly (a week or two), and has a broad range of new features and improvments available in it. Watch this space. :)

-Chris

### LLVM + CLR/MSIL Support

Chris, thanks for your input. I'll just note, again that my comments were about the llvm status as of two years ago, since the issue raised was why didn't mono use llvm at the time. I'm sure llvm has improved since, but as you say, too, some of the features you say are implemented are not in a release yet, even if it's soon to be released: this probbaly means it wasn't available two years ago either:-)

Overflow checking is the one big thing that
we do not handle efficiently today, but it can
be inefficiently emulated.


Sure, but we're supposed to build an efficient mono JIT and overflow checks are more common in the C# code (they are even the default in VB.net).

> both ordered and unordered FP compares must be exposed
LLVM exposes both directly.


I see llvm.isunordered has been provided in the yet to be released 1.3, nice. We needed it a lot of time ago, though and it remains to be seen how efficient is the code generated with it with the expected CLR semantics, since this is involved in most FP compare operations.

LLVM, in contrast to GCC, does not spill with
64-bits of precision, it spills all 80 bits.
I believe LLVM provides fully correct FP support for MSIL.


Good, for a number of reasons, we found it actually better to set the precision to 64 bit, instead, which provides better compat with other architectures and the MS runtime results.

Huh? Of course it does, the cast instruction.


Sorry, I missed that somehow. Does it provide the semantics explained in the ECMA spec for the CLR?

> the vararg call conv needs to be implemented in a
> specific way

I don't follow.


It's similar to how vararg is implemented on amd64, you can read the spec for more info.

> handling jit trampolines (llvm has some code, but it
> wouldn't handle interface calls on valuetype in the
> CLR or indirect calls like what could happen with
> tail calls or delegates).

Huh? Of course it does. This is conceptually the same
as calling through a function pointer in C. We JIT
full C and C++ programs without problem, today.


Tail calls are not invoked with a call, so you don't get the return address pushed on the stack, which your CompilationCallback() method doesn't seem to handle.
The value type vtable needs are peculiar to the CLR, I think, certainly nothing of the sorts happens for C code.

> The hardest part of the port is exception handling
> (which doesn't seem to be implemented in llvm in the
> x86 in version 1.2)

It is fully implemented in LLVM 1.2.


\$ grep -i unwind *

InstSelectSimple.cpp: // it's not an unwind/return), insert the FP_REG_KILL instruction.

X86TargetMachine.cpp: // FIXME: Implement the invoke/unwind instructions!

Maybe that comment in the source is misleading, but with a quick look there doesn't seem to be much code to do stack unwinding (even less across jitted and C compiled code, which is required in mono).

LLVM also provides full featured *accurate* GC
support, something that Mono does not.


True, but the issue is not so much the JIT work involved (basically only the metadata/bitmap collection is missing in mono), but the integration with all the rest of the runtime and thread support which llvm doesn't have either. Thread support, crossing jitted and compiled code boundaries and extensive testing are the main issues in GC support and they take a lot of time. And, again, llvm didn't have GC support when the decision to not use llvm was made (remember we're talking about two years ago?).

> file, run gcc, dlopen the shared library.

While that would be cute, the LLVM C backend does
not support JITing code. :) Note that the other
backends we have (X86/PPC/Sparc) work as static code
generators, and the X86/Sparc codegens both work as
JITs (PPC support is coming in 1.4).


Nice: we released x86, sparc and ppc in 1.0. s390, amd64 and sparc64 are in good shape already in cvs and will be released in the next mono version. Anyway, the comment was just to say that for practical purpouses a C backend would be useless in mono: it's better to have twice the supported architectures in the jit than supporting all of them, but in an unusable way.

For example, LLVM supports scheme pretty well,
something which is not true of the CLR.


Well, that page says: But be warned, the resulting programs are painfully slow ^_^. The next step is to implement garbage collection for it.
So it's certainly a good start, but there are already more complete implementations of scheme for the CLR, including GC support. I could not find tail call support in llvm, which is a requirement for good scheme support.

I think that a mono JIT implemented with LLVM
would be an excellent thing for BOTH projects:
you would get accurate GC support, aggressive
interprocedural and static optimizations for your AOT
translator, and non-naive JIT generated code. For us,
we would get more exposure and more happy users.


Well, as I said, the biggest part of accurate GC support is not implemented in llvm either (because of the missing thread support or because it needs to be implemented in the mono runtime itself, not in the mono jit). Good thread support is tricky and GC safe points only at call sites is not enough to handle implicit exceptions anyway (div by 0, null refs etc). We can't say to our users that they can't use threads:-)
We have certainly areas for improvements in jit performance, but the generated code is certainly not naive, our optimization framework is improving and jit time must be considered, too, I have no idea how llvm performs for that. We're also pretty good portability-wise with twice the architectures supported, so there is actually no incentive for us to switch to llvm, considering the amount of work it would take (which we could spend on more optimizations or on more ports: porting to llvm would take the same amount of time as a cpu port, plus all the work needed to implement the missing llvm support like tail calls, ovf and actually testing it works, so we could port to two more archs, or develop other SSA-based optimizations, so that time is better spent on mono from my point of view).
I whish you good luck with your proprietary llvm-MSIL integration, I'm sure it will prompt for further refinements of llvm and happier users.

### LLVM Status, other stuff :)

> llvm status as of two years ago, since the issue raised
> was why didn't mono use llvm at the time.

Sure, that makes sense. We are making a tremendous amount of progress in various fronts, and you're right, two years ago we were not nearly as far along (LLVM is only ~3 years old). The point of me responding was just to correct statements that are out of date, that's all. I don't expect mono to make dramatic changes in approach :)

Sure, but we're supposed to build an efficient mono
> JIT and overflow checks are more common in the C#
> code (they are even the default in VB.net).

Sure, that makes sense. As I said, LLVM is not a static and immutable piece of software. It is regularly extended and enhanced. Adding this would be pretty trivial.

though and it remains to be seen how efficient is the
> code generated with it with the expected CLR
> semantics, since this is involved in most FP
> compare operations.

It, combined with the other comparison instruction, are folded to a single X86 machine instruction. I believe this is as efficient as you can get :)

Good, for a number of reasons, we found it actually
> better to set the precision to 64 bit

Sure, but using 80 bits follows the letter of the standard. If this was truly important, it would not be hard to change either.

Does [the cast instruction] it provide the semantics
> explained in the ECMA spec for the CLR?

Yes, for primitive types. For casting between interface pointers and object pointers, obviously the object model needs to be taken into consideration.

[re unwinding] Maybe that comment in the source is

Yes, it is. All code generators support exceptions, even the C backend.

And, again, llvm didn't have GC support when the
> decision to not use llvm was made

Again, I'm really not trying to say that your decisions two years ago are incorrect. :) I'm just trying to make sure that the current state of LLVM is well known for others who are embarking on compiler-related projects.

Nice: we released x86, sparc and ppc in 1.0.

Sure, but LLVM provides much better code quality.

Anyway, the comment was just to say that for
> practical purpouses a C backend would be useless in
> mono.

No doubt. LLVM is designed to support many more types of client than mono does.

[re scheme] there are already more complete
> implementations of scheme for the CLR

Of course. My point was not to say that the current llvm scheme implementation is perfect. Actually something that is interesting about it is that it is TINY and written in scheme itself (it also self-hosts). The current scheme front-end is obviously a work-in-progress and just a start, but the CLR is *not* designed to run scheme well at all (in contrast, LLVM is). In particular, the whole MSIL object model makes no sense for scheme, you can't realistically bang bits into the low order bits of pointers in MSIL, etc.

Well, as I said, the biggest part of accurate GC
> support is not implemented in llvm either

You're absolutely correct. The LLVM GC support is still very young and developing. That said, it's only about 3 months old. :)

We can't say to our users that they can't use threads:-)

I understand that. LLVM 1.4 will almost certainly have thread support. My point is just that you are acting like this is the way it will be until the end of the world. :) Please check out the LLVM status updates on the left bar of the main llvm web page for an idea of how quickly we make progress. Note that LLVM also provides many things that CLR simply does not, and probably will never.

Anyway, LLVM and mono are both interesting projects for various different purposes. I think it's too bad that you're implicitly acting as though they are competing against each other: this really does not need to be the case. In any event, if lambda readers need a backend for their crazy and nifty new languages, I heartily encourage them to check out both LLVM and mono.

-Chris

### Re: LLVM Status, other stuff :)

It, combined with the other comparison instruction, are
folded to a single X86 machine instruction. I believe
this is as efficient as you can get :)


I'll leave to you the fun to discover the subtler issues when you'll write the IL support;-)

The CLR is *not* designed to run scheme well at all (in
contrast, LLVM is). In particular, the whole MSIL object
model makes no sense for scheme, you can't realistically
bang bits into the low order bits of pointers in MSIL, etc.


It looks like one of the reasons IronPython was mentioned on LtU is exactly as a proof that a language which it was claimed the CLR was not designed to run or run well, does indeed run quite well. There is no reason a CLR implementation couldn't provide tagged values that can hold ints or references. It would actually be quite easy to add to mono and adapt the Boehm GC to deal with it. With different GCs it may require more changes, since the two low bits available are both used in the straightforward implementation (a mark bit and a pinned bit). On 64 bit platforms this is not an issue, though and it's just another speed/space tradeoff to consider in the design. So, yes, currently the CLR doesn't provide tagged values, but it does provide tail calls, which are a requirement as well.
In the end, the actual implementation is what matters and only when the CLR and LLVM will have comparable (in features) scheme implementations a conclusion can be drawn, just like now IronPython can be compared to CPython.

My point is just that you are acting like this is the
way it will be until the end of the world. :)


Not at all, I'm happy for your progress:-) Mono improves pretty fast, too and this is another proof that mono and llvm fill different needs and make different tradeoffs. For example, take tagged pointers. Adding them to mono and writing a scheme compiler that takes advantage of them may speedup a scheme implementation on mono by an order of magnitude. If the feature would slowdown common C# code by 1% I'd definitely have no issue in implementing it. But if it takes a 10 or 20% hit, it's a tradeoff we're not going to make (at least in the default build: people are free and encouraged to experiment). In llvm you'll have to consider the same tradeoffs if you want the same feature (running both C# and scheme code in the same VM), since there is no free lunch here. Or you can just have different versions, one tweaked for one language and one tweaked for the other one, but losing in interoperability.

Note that LLVM also provides many things that CLR
simply does not, and probably will never.


The opposite is true, too;-)

I think it's too bad that you're implicitly acting as
though they are competing against each other.


I don't think there is competition between mono and llvm: there is some overlap, but there are also different design decisions that lead to different tradeoffs and different user bases. I wish you full success with your project: if llvm turns out to publish good results we'll certainly have a look at it as a source of inspiration.

MONO's latest roadmap shows plenty of work being sunk into JIT.

### How's the Parrot version coming along?

And who's going to get the custard pie?

Last I heard, Python on Parrot wasn't benchmarking so spectacularly. But I don't know what's been tried yet in the way of optimizations.

### Dan will take the pie

Dan Sugalski admits he will eat some pie at OSCON. Although a lot has been done, not enough of python was implemented to run all benchmarks.

### Oh, I'm getting the pie all right...

For a variety of reasons, we didn't get the translator done in time, so not all of the parts of the benchmark run yet.

The thing's in seven parts (0-6) with a driver program. The times I do have (in seconds) are:

ParrotPython
b11.401.65
b2: 0.15 0.45
b3: 5.00 2.40
b6: 1.62 2.40

So we're not doing too bad, though the b3 test definitely needs to get a thump on our end. (One of the other tests runs as well, but I couldn't get it happy on my dev system in the few minues I have right now)

### Could you post a message in the discussion group here...

...when you get that retrospective written up and posted to your blog? Implementation reports are always very interesting.

### I'll post the post-mortem

I've still got the pie delivery and a conference presentation on parrot, but once that's done we're going to do a post-mortem on the project. It's pointed out a number of things (good, bad, and interesting) about Parrot and the project, and we'd be foolish to not take advantage of this to work out what happend and what we need to do because of it.

We will finish the python translator, probably some time in August, and release it when it's done. (It'll be part of the parrot distribution) Between that and the PHP compiler (which is also working pretty nicely from what I can see) we should be in a position to start doing production-ready, or at least real engine stress-testing and library writing, code within the next month or three.

And yeah, I'm as surprised as anyone else how far along things really are. :)

### Congrats

Dan, congrats: you and leo have done some excellent work there, it seems. The current mono numbers are not as good, though I have identified a couple of tweaks we need to speed up the code (we're doing especially bad at b5, because of the exception-handling code): we hope to fix them in the next few days/weeks.

BenchMonoPython
b04.141.81
b10.590.83
b20.600.23
b31.331.13
b41.560.57
b59.540.11
b62.151.31

If you exclude b5, currently IronPython on mono is 80% slower than CPython which is quite good IMHO, given that it can integrate seamlessly with C# code which in many things can be easily 1 order of magnitude faster that python.

### Thanks very much

Though you guys are to be congratulated too--the numbers that the .NET versions pull off are better than I'd expected. Quite nice, and I do hope the Ximian folks (or someone) picks up the IronPython project and finish it. That'd be cool, and good for everyone, I think.

### Parrot now more than a hoax?

I assume the Parrot spoken of here is a virtual machine, and not the April Fools Day joke of a Python/Perl successor (see ParrotLanguage):

while left_angle_right_angle:
if dollar_underscore[0] =eq= "#":
continue_next;
}
print dollar_underscore;
}


### Never was a hoax

Though we did take the name for the VM from the joke. Life imitates satire, and all that.

We're real, though, and doing remarkably well, all things considered.