Re: [Mono-dev] ir instructions.
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.
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.
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.
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.
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