But...
Right now the only good way to find out if a value is true or not is
to do something like:
$I0 = 1
if $P0, done
$I0 = 0
done:
and look in $I0 for the result. This is OK, but if you're dealing
with a language with relatively primitive views of logical operations
(i.e they return 0 or 1) you end up with a *lot* of these little code
snippets when evaluating something like:
if ((foo or bar) and ((x1 >= 12) or (x2 < 15) or (x5 and x6 and
x7)) goto somewhere
(And yes, that's close to a real code snippet. Feel my pain here :)
Not a huge deal to translate, but once you hit 30K basic blocks in a
sub the register coloring algorithm really gets unhappy and dies an
unpleasant death after an hour or so.
Anyway, because of it I'm pondering non-flowcontrol logical ops. That
is, something like:
istrue I0, P5 # I0 = 1 if P5 is true
isgt I0, P5, P6 # I0 = i if P5 > P6
The or/and/xor/not ops don't really need alternate versions, since:
isor I0, P5, P6
can be done with
or P4, P5, P6
istrue P4
so there doesn't seem to be much pressure there.
Given the semi-self-serving nature of these I think some discussion's
in order first.
--
Dan
--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk
> Right now the only good way to find out if a value is true or not is
> to do something like:
>
> $I0 = 1
> if $P0, done
> $I0 = 0
> done:
>
> and look in $I0 for the result. This is OK, but if you're dealing
> with a language with relatively primitive views of logical operations
> (i.e they return 0 or 1) you end up with a *lot* of these little code
> snippets when evaluating something like:
>
> if ((foo or bar) and ((x1 >= 12) or (x2 < 15) or (x5 and x6 and
> x7)) goto somewhere
>
> (And yes, that's close to a real code snippet. Feel my pain here :)
> Not a huge deal to translate, but once you hit 30K basic blocks in a
> sub the register coloring algorithm really gets unhappy and dies an
> unpleasant death after an hour or so.
So: branches are bad for modern (CPUs|VMs|...). I thought we'd
established that? :)
> Anyway, because of it I'm pondering non-flowcontrol logical ops. That
> is, something like:
>
> istrue I0, P5 # I0 = 1 if P5 is true
> isgt I0, P5, P6 # I0 = i if P5 > P6
There's definitely precedence for "primitive bools," which is one step
beyond where you're writing about. PowerPCs have a condition register,
which is really better thought of as a set of 32 one-bit boolean
registers. The bits can be filled by gt and lt operators and the like.
Next, they can be &&'d, ||'d, !'d, etc. Finally, the branch conditional
instruction executes, deciding whether to branch just off of that one
bit in the CR. Using CR operators can save pipeline bubbles over &&'s
with branches.
Of course, short-circuiting expression evaluation requires actually
branching mid-expression.
> Given the semi-self-serving nature of these I think some discussion's
> in order first.
Doesn't seem self-serving at all if it helps make common code constructs
more amenable to the optimizer.
--
Gordon Henriksen
IT Manager
ICLUBcentral Inc.
gor...@iclub.com
[snip]
> Anyway, because of it I'm pondering non-flowcontrol logical ops. That
> is, something like:
>
> istrue I0, P5 # I0 = 1 if P5 is true
> isgt I0, P5, P6 # I0 = i if P5 > P6
Definitely! When I was writing my compiler to parrot I ran into that
awkward idiom over and over. Something like this would be great.
Luke
By all means! I've thought non-branching comparison ops would be a good
idea for years...
--
Brent "Dax" Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker
Oceania has always been at war with Eastasia.
My goodness. Takes me back to the early 90s Acorn RISC processors, where
every instruction was conditional on the control flags. Could skip half a
dozen instructions with the same false conditional at the same cost as
performing a branch. I doubt if this would be nearly as much of an
optimization for a virtual machine, but an aggressively optimizing compiler
would make constructs like the following just that extra bit faster:
if ( foo < bar ) baz++;
--
Jon Shapcott <ed...@xibalba.demon.co.uk>
"This is the Space Age, and we are Here To Go" - Wlliam S. Burroughs
Those would be very nice for us compiler-writers.
It's a bit (heh) late for me to bring this up, now,
but I always thought the flow-control ops should be
prefixed with 'j' or something. Like in most other
assemblies. You have "je" for jump-if-equal and so on.
In PASM we have "eq" for equal, but that doesn't give
any indication that it will jump on equal. So really,
'eq' should be the non-jumping version, while 'jeq'
would be the jumping version.
Then again, IMCC can hide this from you, so it doesn't
matter so much, anymore.
if $P0 == $P2 goto somewhere
Just a thought. But anyhow, non-jumping comparison ops
would be nice. :)
$I1 = ($P0 == $P2)
?
__________________________________
Do you Yahoo!?
Yahoo! Domains – Claim yours for only $14.70/year
http://smallbusiness.promotions.yahoo.com/offer
Okay, it's pretty obvious that these would be useful and people have
been humoring me the past few years. :)
I'll check in the new ops. experimental.ops to start, with them
moving over somewhere after we're comfortable with the final
appearance.
getattribute $P0, ...
isnull $P0, INIT
branch DONE
INIT:
$P0 = new .Foo
setattribute ..., $P0
DONE:
which can be written shorter with a "notnull" op:
getattribute $P0, ...
notnull $P0, OK
$P0 = new .Foo
setattribute ..., $P0
OK:
Its IMO easier to understand the latter code.
jens
isnull probably ought to get turned into a non-branching op to match
the other is<foo> ops I added. The current isnull could get renamed
to ifnull (with a corresponding unlessnull, I expect)
Mmm. Yes, ARM. These days most likely to be found inside a mobile phone.
> every instruction was conditional on the control flags. Could skip half a
> dozen instructions with the same false conditional at the same cost as
> performing a branch. I doubt if this would be nearly as much of an
IIRC 5 not 6. :-)
Not sure how much the timings have changed recently, and hence whether this is
still the case.
It doesn't look like anyone has added anything to the JIT recently:
$ ls -l jit/arm/
total 72
drwxr-xr-x 5 nick nick 170 6 May 17:42 CVS
-rw-r--r-- 8 nick nick 27256 19 Oct 2002 core.jit
-rw-r--r-- 8 nick nick 3561 23 Apr 10:20 exec_dep.h
-rw-r--r-- 8 nick nick 37553 23 Apr 10:20 jit_emit.h
Nicholas Clark