Hi,

I mentionned, several times in the past, that I would have liked to have
conditional rules in Monoburg.

A conditional rule is a rule whose application depends not only on the
tree pattern, but also on an arbitrary condition computed on the
relevant tree nodes, such as the ->vm_type field of operands.

I brought that up originally when working on long division. We ended up
adding OP_DIV_64 to the HIR, so that divisions with "long" operands take
a different rule that divisions with "int" operands.
It makes perfect sense but unfortunately, adding things to the HIR is a
solution that does not necessarily scale well (more on that regarding
floating point conversions later).

Monoburg supports an optional cost associated to each rule. By default
this is 0 or 1, and you can associate any integer constant you want.
You can also provide, instead of a constant, a C function that computes
the cost. This function can check the conditions and compute a cost
accordingly, possibly returning a value high enough that the rule is
discarded completely.
This is existing functionnality of Monoburg, I am not adding anything
here.

However, I decided to #define MB_DISCARD_RULE in insn_selector.brg, to
one of those "high enough values" (65535, the maximum value for a cost
in monoburg), in order to make things cleaner and more intuitive to the
reader. This is dispensable.

Here is my addition to monoburg.c, it is probably dispensable but again
cleaner and more intuitive to add it:

--- a/monoburg/monoburg.c
+++ b/monoburg/monoburg.c
@@ -450,7 +450,7 @@ emit_cond_assign (Rule *rule, char *cost, char
*fill)
                rc = g_strdup ("c");


-       output ("%sif (%s < p->cost[MB_NTERM_%s]) {\n", fill, rc,
        rule->lhs->name);
+       output ("%sif (%s < p->cost[MB_NTERM_%s] && %s !=
MB_DISCARD_RULE) {\n", fill, rc, rule->lhs->name, rc);

        output ("%s\tp->cost[MB_NTERM_%s] = %s;\n", fill,
rule->lhs->name, rc);

As you can see, it's not much.

I made a proof of concept on OP_DIV and OP_DIV_64, to check that my
changes and theory work.
I was able to have to reg: OP_DIV(reg, reg) rules, one matching only
long, the other only int, removing OP_DIV_64 completely.
This does not seem too useful for division, but for integer/float
conversion this will be very important.

This is because of reg: EXPR_CONVERSION(reg). We need a freg:
EXPR_CONVERSION(freg) variant, reg: EXPR_CONVERSION(freg) and freg:
EXPR_CONVERSION(reg), but obviously those have to match the right cases
(respectively: float/double -> float/doulbe, float -> int, int ->
float), which can be done by adding three CONVERSION to the HIR, or
using conditional rule matching like I described. 
By the way, here is what a "conditional rule" looks like:

+reg:   OP_DIV(reg, reg)
 {
        emulate_op_64(state, s, tree, emulate_ldiv, J_LONG);
+} cost {
+       struct expression *expr = to_expr(state->tree);
+       int c = 1;
+       if (to_expr(expr->binary_left)->vm_type != J_LONG)
+               c = MB_DISCARD_RULE;
+       return c;
 }

This mail is here to explain my work of tonight, and prepare the minds for
my future patches using "conditional rules".

I would like to see the monoburg.c change merged, I'll send the patch
right away. 

Thanks
-- 
Greetings,
A.H.

------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to