Re: [Mono-dev] ir instructions.

2010-02-23 Thread Paolo Molaro
On 02/22/10 Rodrigo Kumpera wrote:
 On Sat, Feb 20, 2010 at 2:07 AM, Jerry Maine - KF5ADY crashfou...@gmail.com
  I remember you talking about instead of having marcos and defines
  describe certain attributes of IR instructions, having them be defined
  in a single data structure like what is done for when calling LLVM. What
  would that entail?
 
 
 That would entail been able to encode more properties and relations of
 instructions
 without all the repetition that currently exist in our JIT.

All the repetition can be trivially eliminated: nobody did that yet
because it's mostly a waste of time at this point (and some invariants
in opcode order need to be maintained right now, so changing things
blindly could break code).

 There are 3 different problems I think deserve been solved.
 
 The first is encoding of instruction properties such as commutative or
 side-effect free.
 For this it would be a matter of adding an extra parameter to the MINI_OP
 macro or'ing
 those properties and then filling a table with this data.

Right, so there is no need for the bloat of tablegen for this (not
counting the build issues it would bring on).

 The second is encode relations between instructions. For example,
 op_to_op_dest_membase
 is only enabled on x86/amd64 and to small amount of operations. Doing this
 for all SIMD ops
 would be a a lot of repetitive work.

See the attached program that will generate all the stuff you need there
and more. It can be trivially enhanced to generate also the backend
code or mono_op_to_op_imm() support.

 The last is to reduce the amount of repetition between instructions
 definitions, it has to be very
 template oriented and support customization of the result. For example, I
 want to define a single
 template for binary SIMD ops that produce reg_reg, reg_membase, reg_memindex
 variants, which
 don't have side effects and, finally, can be easily instantiated for the
 many vector elements.
 
 This is asking for a lot. But it would simplify the JIT a lot and make it
 produce better code easier.

See the attached program, it does already basically all the things you outlined.
All with half an hour of scripting and 60 lines of code.
So, no, there is no need for tablegen in mono, adapting it to hour needs
would require much more than half an hour and being so different is more
likely to introduce subtle issues.
Once the templates are defined, you can simply add a new SSE instruction
by addig its name to the proper list.

lupus

-- 
-
lu...@debian.org debian/rules
lu...@ximian.com Monkeys do it better
#!/usr/bin/perl -w

my %templates = (
	# typical sse instructions
	XREG XREG XREG - MEMBASE[2] = [qw (ADDPD DIVPD MULPD SUBPD MAXPD)],
	# typical integer instruction
	IREG IREG IREG - IMM[2:NONE] = [qw (IADD ISUB IMUL IDIV)],
);

my @data = (
# a more complex case: we generate several instructions
'COMPARE compare NONE IREG IREG - IMM[2:NONE], MEMBASE_REG[1], MEMBASE_IMM[1 2:NONE], REG_MEMBASE[2]',
);

foreach my $template (keys %templates) {
	foreach my $op (@{$templates{$template}}) {
		push @data, $op . lc($op) .  $template;
	}
}

sub output {
	my @spec = @_;
	print MONO_OP(OP_$spec[0], \$spec[1]\, $spec[2], $spec[3], $spec[4])\n;
}

sub output_variant {
	my ($variant, @spec) = @_;
	my @orig = @spec;
	return unless $variant =~ /(\S+)\s*\[(.*)\]/;
	my $name = $1;
	my @regs = split (/\s/, $2);
	$spec [0] .= _$name;
	$spec [1] .= _ . lc $name;
	my $membase;
	foreach my $reg (@regs) {
		my ($num, $new) = split (/:/, $reg);
		$new = IREG unless defined $new;
		$spec [2 + $num] = $new;
		# we use the convention that the first one is the base pointer
		$membase = $num unless defined $membase;
	}
	output (@spec);
	my $orig = $spec[0];
	$orig =~ s/_MEMBASE//;
	# to be used in the switch in functions like op_to_op_* with something like:
	# #define OP_2_OP_REG1_MEMBASE(a,b) case a: return b;
	print OP_2_OP_REG${membase}_MEMBASE(OP_$orig,OP_$spec[0])\n if defined $membase  $name =~ /MEMBASE/;
}

sub generate {
	my $template = shift;
	my ($opcode, $variant) = split (/-/, $template);
	my @spec = split (/\s/, $opcode);
	output (@spec);
	return unless (defined $variant) and (length $variant);
	foreach my $var (split (/,/, $variant)) {
		# variants could go to a different output queue to
		# maintain instruction order currently required in the JIT
		output_variant ($var, @spec) 
	}
}

foreach my $op (@data) {
	generate ($op);
}

___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] ir instructions.

2010-02-22 Thread Rodrigo Kumpera
On Sat, Feb 20, 2010 at 2:07 AM, Jerry Maine - KF5ADY crashfou...@gmail.com
 wrote:

 Rodrigo:

 I remember you talking about instead of having marcos and defines
 describe certain attributes of IR instructions, having them be defined
 in a single data structure like what is done for when calling LLVM. What
 would that entail?


That would entail been able to encode more properties and relations of
instructions
without all the repetition that currently exist in our JIT.

I am getting more interested in that project as a was thinking it would
 be quite a bit helpful in the other projects I'd like to do, and may be
 even needed in some parts.


I talked abou that with Paolo and he suggested that this it would be better
done without
using a tool like llvm's tablegen. Thou we didn't talk much further, so I'm
CC'ing him so
he can give us a better idea of what he has on his mind.

There are 3 different problems I think deserve been solved.

The first is encoding of instruction properties such as commutative or
side-effect free.
For this it would be a matter of adding an extra parameter to the MINI_OP
macro or'ing
those properties and then filling a table with this data.

The second is encode relations between instructions. For example,
op_to_op_dest_membase
is only enabled on x86/amd64 and to small amount of operations. Doing this
for all SIMD ops
would be a a lot of repetitive work.

The last is to reduce the amount of repetition between instructions
definitions, it has to be very
template oriented and support customization of the result. For example, I
want to define a single
template for binary SIMD ops that produce reg_reg, reg_membase, reg_memindex
variants, which
don't have side effects and, finally, can be easily instantiated for the
many vector elements.

This is asking for a lot. But it would simplify the JIT a lot and make it
produce better code easier.

Rodrigo
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] ir instructions.

2010-02-22 Thread Zoltan Varga
Hi,

LLVM's tablegen is designed for exactly this purpose, to reduce repetition.
It doesn't
generate code in a general way, it has plugins which take the information
from the .td files and generate code in any format they like, so it could be
used for generating our cpu-X.h
files for example, the same file, not some bloated version of it. Of course,
using LLVM's
tablegen would add a dependency, which is not desirable, but we could write
our own parser
which reads the same syntax, or a subset of it.

 Zoltan


 The last is to reduce the amount of repetition between instructions
 definitions, it has to be very
 template oriented and support customization of the result. For example, I
 want to define a single
 template for binary SIMD ops that produce reg_reg, reg_membase,
 reg_memindex variants, which
 don't have side effects and, finally, can be easily instantiated for the
 many vector elements.

 This is asking for a lot. But it would simplify the JIT a lot and make it
 produce better code easier.

 Rodrigo

 ___
 Mono-devel-list mailing list
 Mono-devel-list@lists.ximian.com
 http://lists.ximian.com/mailman/listinfo/mono-devel-list


___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] ir instructions.

2010-02-22 Thread Rodrigo Kumpera
Later versions (as of  2.6) of tablegen makes it easier to take it out of
LLVM and make it a standard alone tool.
We could even import it into our repository.


On Mon, Feb 22, 2010 at 11:36 PM, Zoltan Varga var...@gmail.com wrote:

 Hi,

 LLVM's tablegen is designed for exactly this purpose, to reduce repetition.
 It doesn't
 generate code in a general way, it has plugins which take the information
 from the .td files and generate code in any format they like, so it could be
 used for generating our cpu-X.h
 files for example, the same file, not some bloated version of it. Of
 course, using LLVM's
 tablegen would add a dependency, which is not desirable, but we could write
 our own parser
 which reads the same syntax, or a subset of it.

  Zoltan


 The last is to reduce the amount of repetition between instructions
 definitions, it has to be very
 template oriented and support customization of the result. For example, I
 want to define a single
 template for binary SIMD ops that produce reg_reg, reg_membase,
 reg_memindex variants, which
 don't have side effects and, finally, can be easily instantiated for the
 many vector elements.

 This is asking for a lot. But it would simplify the JIT a lot and make it
 produce better code easier.

 Rodrigo

 ___
 Mono-devel-list mailing list
 Mono-devel-list@lists.ximian.com
 http://lists.ximian.com/mailman/listinfo/mono-devel-list



___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


[Mono-dev] ir instructions.

2010-02-19 Thread Jerry Maine - KF5ADY
Rodrigo:

I remember you talking about instead of having marcos and defines
describe certain attributes of IR instructions, having them be defined
in a single data structure like what is done for when calling LLVM. What
would that entail?

I am getting more interested in that project as a was thinking it would
be quite a bit helpful in the other projects I'd like to do, and may be
even needed in some parts.

Jerry.
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list