Various questions

1 view
Skip to first unread message

Philip Taylor

unread,
Apr 15, 2005, 3:27:24 PM4/15/05
to perl6-i...@perl.org
I've been working on a C-to-Parrot compiler (actually an IMC backend
for the LCC compiler), tentatively named Carrot, over the past week. It
can currently do some reasonably useful things, like running the Cola
compiler (with only a very small amount of cheating), but it has raised
a few queries:

* I can usually handle unsigned numbers by pretending they're signed and
using 'I' registers, but some things appear to be awkward without new
ops - in particular, div and cmod, and le/lt/ge/gt comparisons. (As far
as I can tell, those are the only ones C would need; everything else
should work fine with the signed variants).

I've added divu/leu/etc ops to math.ops/cmp.ops (and just made them cast
their operands into UINTVALs) - is that a reasonable thing to do? Would
they be better in a new .ops file?


* Should there be an 'isatty' op/method? (or is there something else
that "isatty(fileno(file))" (which Cola's lexer uses) should do, in
order to return a reasonable answer?)


* Is it possible to merge PBC files together, like load_bytecode but at
compile-time?

The compiler converts .c to .pbc (via .imc), then the linker just
creates a program full of load_bytecode, so the actual linking gets done
at run-time, which isn't very nice when you try moving/deleting one of
the .pbcs. (And lcc always deletes the .pbcs, since it assumes they're
temporary files.)


* How efficient are PMC method calls? (And are performance concerns
documented anywhere, like "op calls are roughly n times faster than
methods", so compiler-writers could avoid implementing things in stupid
ways, or is it too early to be doing that?)

I've been using [gs]et_integer_keyed_int on a PMC to allow pointer
access. Since it reads whole ints, it probably crashes unnecessarily
when e.g. reading chars at unlucky addresses - but IMC code like "val =
mem.read_i1(ptr)" feels unpleasantly inefficient, particularly in
string-processing loops.

Hmm... Should I just accept that C-on-Parrot will always be relatively
slow, since its concept of memory is slightly incompatible with
Parrot's, and anybody who wants speed can use a native C compiler, so I
can stop worrying about it? :-)


Thanks,
--
Philip Taylor
phi...@zaynar.demon.co.uk

Chip Salzenberg

unread,
Apr 15, 2005, 9:48:10 PM4/15/05
to Philip Taylor, perl6-i...@perl.org
According to Philip Taylor:

> * I can usually handle unsigned numbers by pretending they're signed and
> using 'I' registers, but some things appear to be awkward without new
> ops - in particular, div and cmod, and le/lt/ge/gt comparisons. (As far
> as I can tell, those are the only ones C would need; everything else
> should work fine with the signed variants).

Don't you also need unsigned assignment to N registers?

double d = 0xFFFFFFFFUL;

> I've added divu/leu/etc ops to math.ops/cmp.ops (and just made them cast
> their operands into UINTVALs) - is that a reasonable thing to do? Would
> they be better in a new .ops file?

May as well leave them there.

> * Should there be an 'isatty' op/method?

I think so. I wouldn't tie it to the fileno() concept, because
fileno() is less portable than isatty(filehandle), which is a
reasonable sort of question beyond the bounds of Unix, in the Great
Wilderness.

> * Is it possible to merge PBC files together, like load_bytecode but at
> compile-time?

I'll punt on this one for now... Leo?

> I've been using [gs]et_integer_keyed_int on a PMC to allow pointer
> access. Since it reads whole ints, it probably crashes unnecessarily
> when e.g. reading chars at unlucky addresses

Yes ... on some arch's. Not x86, though, so I'm safe. :-)

> but IMC code like "val = mem.read_i1(ptr)" feels unpleasantly
> inefficient, particularly in string-processing loops.

What about a native-code _function_ rather than an object method?
--
Chip Salzenberg - a.k.a. - <ch...@pobox.com>
Open Source is not an excuse to write fun code
then leave the actual work to others.

Leopold Toetsch

unread,
Apr 16, 2005, 4:56:35 AM4/16/05
to Philip Taylor, perl6-i...@perl.org
Philip Taylor <phi...@zaynar.demon.co.uk> wrote:
> I've been working on a C-to-Parrot compiler (actually an IMC backend
> for the LCC compiler), tentatively named Carrot, over the past week. It
> can currently do some reasonably useful things, like running the Cola
> compiler (with only a very small amount of cheating), but it has raised
> a few queries:

Wow.

> * I can usually handle unsigned numbers by pretending they're signed and
> using 'I' registers, but some things appear to be awkward without new
> ops - in particular, div and cmod, and le/lt/ge/gt comparisons. (As far
> as I can tell, those are the only ones C would need; everything else
> should work fine with the signed variants).

> I've added divu/leu/etc ops to math.ops/cmp.ops (and just made them cast
> their operands into UINTVALs) - is that a reasonable thing to do? Would
> they be better in a new .ops file?

No, keeping the ops in their categories is fine.

> * Should there be an 'isatty' op/method? (or is there something else
> that "isatty(fileno(file))" (which Cola's lexer uses) should do, in
> order to return a reasonable answer?)

A method, like e.g. C<eof>, see classes/parrotio.pmc

$P0 = getstding
$I0 = $P0."__isatty"()

METHOD INTVAL __isatty() ...

(we'll create the mangled version with two underscores automagically
soon)

> * Is it possible to merge PBC files together, like load_bytecode but at
> compile-time?

Not really. But you might have a look at src/pbc_info.c, which
demonstrates some of the packfile manipulations. Such a utility would be
really great.

> * How efficient are PMC method calls? (And are performance concerns
> documented anywhere, like "op calls are roughly n times faster than
> methods", so compiler-writers could avoid implementing things in stupid
> ways, or is it too early to be doing that?)

It's a bit early still, but a general rule of thumb is:
- if you have native I or N types, make it an opcode
- everything else is at least a function call already and will be
optimized like hell and will be fast enough ;)

> I've been using [gs]et_integer_keyed_int on a PMC to allow pointer
> access. Since it reads whole ints, it probably crashes unnecessarily
> when e.g. reading chars at unlucky addresses - but IMC code like "val =
> mem.read_i1(ptr)" feels unpleasantly inefficient, particularly in
> string-processing loops.

That (but not only) seems to warrant new {Fixed,Resizable}ByteArray
PMCs. See e.g. the *BooleanArray PMCs.

> Hmm... Should I just accept that C-on-Parrot will always be relatively
> slow, since its concept of memory is slightly incompatible with
> Parrot's, and anybody who wants speed can use a native C compiler, so I
> can stop worrying about it? :-)

WRT "memory" access probably yes. When it comes to raw calculation speed
with INTVALs, Parrot can reach the speed of optimized C.

> Thanks,

Welcome,
leo

Reply all
Reply to author
Forward
0 new messages