Jeff Clites <[EMAIL PROTECTED]> wrote: > On Oct 23, 2004, at 3:42 AM, Leopold Toetsch wrote:
> We were allocating the volatile float registers first (or, only)--so > C<set_s_sc> was blowing away an N-register, even with only one in use. > That's why I was surprised there weren't more failures. Yes. As said i386 had the same problem and not one test file did break. I've now added a quick hack to the JIT compiler, which seems to do the right thing, or better, it's a step towards that: $extern = 1 if $asm =~ /call_func/; This marks the function being extern to JIT, so the register preserving code is activated. It's not quite the best solution, because only used volatiles have to be preserved/restored. More below ... >> Anyway, I think we need a more general solution. >... >> Solution: The JIT compiler/optimizer already calculates the register >> mapping. We have to use this information for JIT pro- and epilogs. > That makes sense--I hadn't initially realized we were tracking this, > but since we are, we should use it. Things may be a bit tricky > fixup-wise, since the size of the prolog will depend on how many float > registers we need to preserve. Not really. When creating the prolog/epilog you know exactly the register mapping of each section. So we just have to find the maximum for each register kind, then decide, if we should use non-volatiles or volatiles or both and emit the appropriate code. We probably need some platform settings and tweakables, which allocation policy should be used, e.g. PARROT_JIT_PREFER_VOLATILES and maybe a threshold, when to change allocation policy. But anyway, in jit_info->optimizer, you'll get the count of used registers. With that information the platform code can calculate the used stack storage and emit the appropriate pro- and epilogs. E.g. from Mach-O- Runtime Conventions for PowerPC - PowerPC Stack Structure spaceToSave = linkageArea + params + localVars + 4 * nGPRS + 8 * nFPRS rounded up to x*16. It's the same, what currently is a hardcode define. >> 2) JITed functions with calls into Parrot >> >> The jit2h JIT compiler needs a hint, that we call external code, e.g. >> >> CALL_FUNCTION("string_copy") So, back to external functions. With this syntax (and a needed jit_info argument), we can do: $extern = -1 if $asm =~ /CALL_FUNCTION/; This activates the saving and restoring of used volatiles. I don't think that we have to write back non-volatiles to Parrot registers, at least not, if we define that JITted code like that will not see a correct Parrot register set. If a function would need the Parrot registers, just don't provide a JITted version for it. OTOH this could be problematic if the function throws an exception, and if the exception handler is able to provide a Parrot core dump. > One other question: Your "P_ARITH" optimization in jit/ppc/core.jit. I > can't come up with a case where this kicks in, It's alomost only for examples/benchmarks/mops.pasm: + 50% speed. Now PPC JIT code is two instructions for the loop instead of three ;) > Thanks, > JEff leo