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