Commit 8b5aac95 authored by Matthias Braun's avatar Matthias Braun
Browse files

remove DivMod

[r28345]
parent 43e469da
......@@ -35,7 +35,7 @@
enum firmstat_options_t {
FIRMSTAT_ENABLED = 0x00000001, /**< enable statistics */
FIRMSTAT_PATTERN_ENABLED = 0x00000002, /**< enable pattern calculation */
FIRMSTAT_COUNT_STRONG_OP = 0x00000004, /**< if set, count Mul/Div/Mod/DivMod by constant */
FIRMSTAT_COUNT_STRONG_OP = 0x00000004, /**< if set, count Mul/Div/Mod by constant */
FIRMSTAT_COUNT_DAG = 0x00000008, /**< if set, count DAG statistics */
FIRMSTAT_COUNT_DELETED = 0x00000010, /**< if set, count deleted graphs */
FIRMSTAT_COUNT_SELS = 0x00000020, /**< if set, count Sel(Sel(..)) differently */
......
......@@ -140,25 +140,6 @@ FIRM_API ir_node *arch_dep_replace_div_by_const(ir_node *irn);
*/
FIRM_API ir_node *arch_dep_replace_mod_by_const(ir_node *irn);
/**
* Replace DivMods with Shifts and Add/Subs and Mulh.
* This function is driven by the 3 parameters:
* - allow_mulhu
* - allow_mulhs
* - max_bits_for_mulh
*
* If irn is a DivMod with a Const, the constant is inspected if it meets the
* requirements of the variables stated above. If a Shl/Add/Sub/Mulh
* sequence can be generated that meets these requirements, this expression
* is returned. In each other case irn is returned unmodified.
*
* @param div After call contains the Firm node div result or NULL.
* @param mod After call contains the Firm node mod result or NULL.
* @param irn The Firm node to inspect.
*/
FIRM_API void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod,
ir_node *irn);
#include "end.h"
#endif
......@@ -269,7 +269,6 @@
* ir_node *new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode);
* ir_node *new_Mulh (ir_node *op1, ir_node *op2, ir_mode *mode);
* ir_node *new_Quot (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state);
* ir_node *new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state);
* ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state);
* ir_node *new_Mod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state;
* ir_node *new_And (ir_node *op1, ir_node *op2, ir_mode *mode);
......@@ -700,15 +699,6 @@
* A tuple containing a memory and a execution for modeling exceptions
* and the result of the arithmetic operation.
*
* ir_node *new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state)
* ---------------------------------------------------------------------------------------------------
*
* Performs Div and Mod on integer values.
*
* Output:
* A tuple containing a memory and a execution for modeling exceptions
* and the two result of the arithmetic operations.
*
* ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state)
* ------------------------------------------------------------------------------------------------
*
......
......@@ -159,7 +159,7 @@ typedef struct hook_entry {
/** This hook is called after a Mul was replaced by a series of Shift and Add/Sub operations. */
void (*_hook_arch_dep_replace_mul_with_shifts)(void *context, ir_node *irn);
/** This hook is called after a Div/Mod/DivMod by a constant value was replaced. */
/** This hook is called after a Div/Mod by a constant value was replaced. */
void (*_hook_arch_dep_replace_division_by_const)(void *context, ir_node *irn);
/** This hook is called after a new mode was registered. */
......
......@@ -482,7 +482,7 @@ FIRM_API const char *get_builtin_kind_name(ir_builtin_kind kind);
operands can be factored out. Left is the first, right the
second arithmetic value as listed in tech report 1999-44.
unops are: Minus, Abs, Not, Conv, Cast
binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
binops are: Add, Sub, Mul, Quot, Div, Mod, And, Or, Eor, Shl,
Shr, Shrs, Rotl, Cmp */
FIRM_API int is_unop(const ir_node *node);
FIRM_API ir_node *get_unop_op(const ir_node *node);
......@@ -619,13 +619,11 @@ FIRM_API ir_node *skip_HighLevel_ops(ir_node *node);
FIRM_API int is_cfop(const ir_node *node);
/** Returns true if the operation can change the control flow because
of an exception: Call, Quot, DivMod, Div, Mod, Load, Store, Alloc,
of an exception: Call, Quot, Div, Mod, Load, Store, Alloc,
Bad. Raise is not fragile, but a unconditional jump. */
FIRM_API int is_fragile_op(const ir_node *node);
/** Returns the memory operand of fragile operations. */
FIRM_API ir_node *get_fragile_op_mem(ir_node *node);
/** Returns the result mode of a Div operation. */
FIRM_API ir_mode *get_divop_resmod(const ir_node *node);
/** Returns true if the operation is a forking control flow
* operation: Cond. */
......
......@@ -366,7 +366,7 @@ static int vrp_update_node(ir_node *node)
is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
is_Break(node) is_Builtin(node) is_Call(node)
is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
is_CopyB(node) is_Div(node) is_DivMod(node) is_Dummy(node)
is_CopyB(node) is_Div(node) is_Dummy(node)
is_End(node) is_Free(node)
is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node)
......
......@@ -1066,8 +1066,14 @@ static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
match_flags_t flags = match_commutative;
/* happens for div nodes... */
if (mode == mode_T)
mode = get_divop_resmod(node);
if (mode == mode_T) {
if (is_Div(node))
mode = get_Div_resmode(node);
else if (is_Mod(node))
mode = get_Mod_resmode(node);
else
panic("can't determine mode");
}
/* cannot use address mode with long double on x87 */
if (get_mode_size_bits(mode) <= 64)
......@@ -1533,7 +1539,7 @@ static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
}
/**
* Generates an ia32 DivMod with additional infrastructure for the
* Generates an ia32 Div with additional infrastructure for the
* register allocator if needed.
*/
static ir_node *create_Div(ir_node *node)
......@@ -1565,12 +1571,6 @@ static ir_node *create_Div(ir_node *node)
mem = get_Mod_mem(node);
mode = get_Mod_resmode(node);
break;
case iro_DivMod:
op1 = get_DivMod_left(node);
op2 = get_DivMod_right(node);
mem = get_DivMod_mem(node);
mode = get_DivMod_resmode(node);
break;
default:
panic("invalid divmod node %+F", node);
}
......@@ -1621,15 +1621,6 @@ static ir_node *gen_Div(ir_node *node)
return create_Div(node);
}
/**
* Generates an ia32 DivMod.
*/
static ir_node *gen_DivMod(ir_node *node)
{
return create_Div(node);
}
/**
* Creates an ia32 floating Div.
......@@ -4583,9 +4574,9 @@ static ir_node *gen_Proj_Load(ir_node *node)
}
/**
* Transform and renumber the Projs from a DivMod like instruction.
* Transform and renumber the Projs from a Div or Mod instruction.
*/
static ir_node *gen_Proj_DivMod(ir_node *node)
static ir_node *gen_Proj_Div_Mod(ir_node *node)
{
ir_node *block = be_transform_node(get_nodes_block(node));
ir_node *pred = get_Proj_pred(node);
......@@ -4624,28 +4615,11 @@ static ir_node *gen_Proj_DivMod(ir_node *node)
break;
}
break;
case iro_DivMod:
switch (proj) {
case pn_DivMod_M:
return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
case pn_DivMod_res_div:
return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
case pn_DivMod_res_mod:
return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
case pn_DivMod_X_regular:
return new_rd_Jmp(dbgi, block);
case pn_DivMod_X_except:
set_ia32_exc_label(new_pred, 1);
return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
default:
break;
}
break;
default:
break;
}
panic("No idea how to transform proj->DivMod");
panic("No idea how to transform proj->Div/Mod");
}
/**
......@@ -5625,8 +5599,7 @@ static ir_node *gen_Proj(ir_node *node)
return gen_Proj_Builtin(node);
case iro_Div:
case iro_Mod:
case iro_DivMod:
return gen_Proj_DivMod(node);
return gen_Proj_Div_Mod(node);
case iro_CopyB:
return gen_Proj_CopyB(node);
case iro_Quot:
......@@ -5706,7 +5679,6 @@ static void register_transformers(void)
be_set_transform_function(op_Conv, gen_Conv);
be_set_transform_function(op_CopyB, ia32_gen_CopyB);
be_set_transform_function(op_Div, gen_Div);
be_set_transform_function(op_DivMod, gen_DivMod);
be_set_transform_function(op_Eor, gen_Eor);
be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
......
......@@ -820,7 +820,7 @@ static struct mu magicu(ir_tarval *d)
/**
* Build the Mulh replacement code for n / tv.
*
* Note that 'div' might be a mod or DivMod operation as well
* Note that 'div' might be a Mod operation as well
*/
static ir_node *replace_div_by_mulh(ir_node *div, ir_tarval *tv)
{
......@@ -1088,111 +1088,3 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
return res;
}
/* Replace DivMods with Shifts and Add/Subs and Mulh. */
void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn)
{
const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
*div = *mod = NULL;
/* If the architecture dependent optimizations were not initialized
or this optimization was not enabled. */
if (params == NULL ||
((opts & (arch_dep_div_by_const|arch_dep_mod_by_const)) != (arch_dep_div_by_const|arch_dep_mod_by_const)))
return;
if (is_DivMod(irn)) {
ir_node *c = get_DivMod_right(irn);
ir_node *block, *left;
ir_mode *mode;
ir_tarval *tv, *ntv;
dbg_info *dbg;
int n, bits;
int k;
int n_flag = 0;
if (! is_Const(c))
return;
tv = get_Const_tarval(c);
/* check for division by zero */
if (tarval_is_null(tv))
return;
left = get_DivMod_left(irn);
mode = get_irn_mode(left);
block = get_irn_n(irn, -1);
dbg = get_irn_dbg_info(irn);
bits = get_mode_size_bits(mode);
n = (bits + 7) / 8;
k = -1;
if (mode_is_signed(mode)) {
/* for signed divisions, the algorithm works for a / -2^k by negating the result */
ntv = tarval_neg(tv);
n_flag = 1;
k = tv_ld2(ntv, n);
}
if (k < 0) {
n_flag = 0;
k = tv_ld2(tv, n);
}
if (k >= 0) { /* division by 2^k or -2^k */
ir_graph *irg = get_irn_irg(irn);
if (mode_is_signed(mode)) {
ir_node *k_node, *c_k;
ir_node *curr = left;
if (k != 1) {
k_node = new_r_Const_long(irg, mode_Iu, k - 1);
curr = new_rd_Shrs(dbg, block, left, k_node, mode);
}
k_node = new_r_Const_long(irg, mode_Iu, bits - k);
curr = new_rd_Shr(dbg, block, curr, k_node, mode);
curr = new_rd_Add(dbg, block, left, curr, mode);
c_k = new_r_Const_long(irg, mode_Iu, k);
*div = new_rd_Shrs(dbg, block, curr, c_k, mode);
if (n_flag) { /* negate the div result */
ir_node *k_node = new_r_Const(irg, get_mode_null(mode));
*div = new_rd_Sub(dbg, block, k_node, *div, mode);
}
k_node = new_r_Const_long(irg, mode, (-1) << k);
curr = new_rd_And(dbg, block, curr, k_node, mode);
*mod = new_rd_Sub(dbg, block, left, curr, mode);
} else { /* unsigned case */
ir_node *k_node = new_r_Const_long(irg, mode_Iu, k);
*div = new_rd_Shr(dbg, block, left, k_node, mode);
k_node = new_r_Const_long(irg, mode, (1 << k) - 1);
*mod = new_rd_And(dbg, block, left, k_node, mode);
}
} else {
/* other constant */
if (allow_Mulh(params, mode)) {
ir_node *t;
*div = replace_div_by_mulh(irn, tv);
t = new_rd_Mul(dbg, block, *div, c, mode);
/* t = arch_dep_mul_to_shift(t); */
*mod = new_rd_Sub(dbg, block, left, t, mode);
}
}
}
if (*div)
hook_arch_dep_replace_division_by_const(irn);
}
......@@ -724,9 +724,6 @@ void dump_node_opcode(FILE *F, ir_node *n)
case iro_Mod:
fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Mod_resmode(n), NULL));
break;
case iro_DivMod:
fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_DivMod_resmode(n), NULL));
break;
case iro_Builtin:
fprintf(F, "%s[%s]", get_irn_opname(n), get_builtin_kind_name(get_Builtin_kind(n)));
break;
......@@ -845,17 +842,6 @@ static const pns_lookup_t quot_lut[] = {
#undef X
};
/** the lookup table for Proj(DivMod) names */
static const pns_lookup_t divmod_lut[] = {
#define X(a) { pn_DivMod_##a, #a }
X(M),
X(X_regular),
X(X_except),
X(res_div),
X(res_mod)
#undef X
};
/** the lookup table for Proj(Div) names */
static const pns_lookup_t div_lut[] = {
#define X(a) { pn_Div_##a, #a }
......@@ -949,7 +935,6 @@ static const proj_lookup_t proj_lut[] = {
{ iro_Cond, E(cond_lut) },
{ iro_Call, E(call_lut) },
{ iro_Quot, E(quot_lut) },
{ iro_DivMod, E(divmod_lut) },
{ iro_Div, E(div_lut) },
{ iro_Mod, E(mod_lut) },
{ iro_Load, E(load_lut) },
......
......@@ -968,15 +968,6 @@ void set_Sel_index(ir_node *node, int pos, ir_node *index)
set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
}
/* For unary and binary arithmetic operations the access to the
operands can be factored out. Left is the first, right the
second arithmetic value as listed in tech report 0999-33.
unops are: Minus, Abs, Not, Conv, Cast
binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
Shr, Shrs, Rotate, Cmp */
ir_node **get_Call_param_arr(ir_node *node)
{
assert(is_Call(node));
......@@ -1585,7 +1576,6 @@ ir_node *get_fragile_op_mem(ir_node *node)
switch (get_irn_opcode(node)) {
case iro_Call :
case iro_Quot :
case iro_DivMod:
case iro_Div :
case iro_Mod :
case iro_Load :
......@@ -1602,19 +1592,6 @@ ir_node *get_fragile_op_mem(ir_node *node)
}
}
/* Returns the result mode of a Div operation. */
ir_mode *get_divop_resmod(const ir_node *node)
{
switch (get_irn_opcode(node)) {
case iro_Quot : return get_Quot_resmode(node);
case iro_DivMod: return get_DivMod_resmode(node);
case iro_Div : return get_Div_resmode(node);
case iro_Mod : return get_Mod_resmode(node);
default:
panic("should not be reached");
}
}
/* Returns true if the operation is a forking control flow operation. */
int (is_irn_forking)(const ir_node *node)
{
......
......@@ -593,24 +593,6 @@ static ir_tarval *do_computed_value_Mod(const ir_node *a, const ir_node *b)
return tarval_bad;
} /* do_computed_value_Mod */
/**
* Return the value of a Proj(DivMod).
*/
static ir_tarval *computed_value_Proj_DivMod(const ir_node *n)
{
long proj_nr = get_Proj_proj(n);
/* compute either the Div or the Mod part */
if (proj_nr == pn_DivMod_res_div) {
const ir_node *a = get_Proj_pred(n);
return do_computed_value_Div(get_DivMod_left(a), get_DivMod_right(a));
} else if (proj_nr == pn_DivMod_res_mod) {
const ir_node *a = get_Proj_pred(n);
return do_computed_value_Mod(get_DivMod_left(a), get_DivMod_right(a));
}
return tarval_bad;
} /* computed_value_Proj_DivMod */
/**
* Return the value of a Proj(Div).
*/
......@@ -723,7 +705,6 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops
CASE(Mux);
CASE(Confirm);
CASE_PROJ(Cmp);
CASE_PROJ(DivMod);
CASE_PROJ(Div);
CASE_PROJ(Mod);
CASE_PROJ(Quot);
......@@ -1565,40 +1546,6 @@ static ir_node *equivalent_node_Proj_Quot(ir_node *proj)
return proj;
} /* equivalent_node_Proj_Quot */
/**
* Optimize a / 1 = a.
*/
static ir_node *equivalent_node_Proj_DivMod(ir_node *proj)
{
ir_node *oldn = proj;
ir_node *divmod = get_Proj_pred(proj);
ir_node *b = get_DivMod_right(divmod);
ir_tarval *tb = value_of(b);
/* Div is not commutative. */
if (tarval_is_one(tb)) { /* div(x, 1) == x */
switch (get_Proj_proj(proj)) {
case pn_DivMod_M:
proj = get_DivMod_mem(divmod);
DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1);
return proj;
case pn_DivMod_res_div:
proj = get_DivMod_left(divmod);
DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1);
return proj;
default:
/* we cannot replace the exception Proj's here, this is done in
transform_node_Proj_DivMod().
Note further that the pn_DivMod_res_div case is handled in
computed_value_Proj(). */
return proj;
}
}
return proj;
} /* equivalent_node_Proj_DivMod */
/**
* Optimize CopyB(mem, x, x) into a Nop.
*/
......@@ -1949,7 +1896,6 @@ static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *op
CASE_PROJ(Tuple);
CASE_PROJ(Div);
CASE_PROJ(Quot);
CASE_PROJ(DivMod);
CASE_PROJ(CopyB);
CASE_PROJ(Bound);
CASE_PROJ(Load);
......@@ -3071,121 +3017,6 @@ make_tuple:
return n;
} /* transform_node_Mod */
/**
* Transform a DivMod node.
*/
static ir_node *transform_node_DivMod(ir_node *n)
{
const ir_node *dummy;
ir_node *a = get_DivMod_left(n);
ir_node *b = get_DivMod_right(n);
ir_mode *mode = get_DivMod_resmode(n);
ir_node *va, *vb;
ir_graph *irg = get_irn_irg(n);
ir_tarval *ta, *tb;
int evaluated = 0;
if (is_Const(b) && is_const_Phi(a)) {
/* check for Div(Phi, Const) */
va = apply_binop_on_phi(a, get_Const_tarval(b), (eval_func) tarval_div, mode, 0);
vb = apply_binop_on_phi(a, get_Const_tarval(b), (eval_func) tarval_mod, mode, 0);
if (va && vb) {
DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
goto make_tuple;
}
}
else if (is_Const(a) && is_const_Phi(b)) {
/* check for Div(Const, Phi) */
va = apply_binop_on_phi(b, get_Const_tarval(a), (eval_func) tarval_div, mode, 1);
vb = apply_binop_on_phi(b, get_Const_tarval(a), (eval_func) tarval_mod, mode, 1);
if (va && vb) {
DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
goto make_tuple;
}
}
else if (is_const_Phi(a) && is_const_Phi(b)) {
/* check for Div(Phi, Phi) */
va = apply_binop_on_2_phis(a, b, (eval_func) tarval_div, mode);
vb = apply_binop_on_2_phis(a, b, (eval_func) tarval_mod, mode);
if (va && vb) {
DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
goto make_tuple;
}
}
ta = value_of(a);
tb = value_of(b);
if (tb != tarval_bad) {
if (tb == get_mode_one(get_tarval_mode(tb))) {
va = a;
vb = new_r_Const(irg, get_mode_null(mode));
DBG_OPT_CSTEVAL(n, vb);
goto make_tuple;
} else if (ta != tarval_bad) {
ir_tarval *resa, *resb;
resa = tarval_div(ta, tb);
if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through
Jmp for X result!? */
resb = tarval_mod(ta, tb);
if (resb == tarval_bad) return n; /* Causes exception! */
va = new_r_Const(irg, resa);
vb = new_r_Const(irg, resb);
DBG_OPT_CSTEVAL(n, va);
DBG_OPT_CSTEVAL(n, vb);
goto make_tuple;
} else if (mode_is_signed(mode) && tb == get_mode_minus_one(mode)) {
va = new_rd_Minus(get_irn_dbg_info(n), get_nodes_block(n), a, mode);
vb = new_r_Const(irg, get_mode_null(mode));
DBG_OPT_CSTEVAL(n, va);
DBG_OPT_CSTEVAL(n, vb);
goto make_tuple;
} else { /* Try architecture dependent optimization */
va = a;
vb = b;
arch_dep_replace_divmod_by_const(&va, &vb, n);
evaluated = va != NULL;
}
} else if (a == b) {
if (value_not_zero(a, &dummy)) {
/* a/a && a != 0 */
va = new_r_Const(irg, get_mode_one(mode));
vb = new_r_Const(irg, get_mode_null(mode));
DBG_OPT_CSTEVAL(n, va);
DBG_OPT_CSTEVAL(n, vb);
goto make_tuple;
} else {
/* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */
return n;
}
} else if (ta == get_mode_null(mode) && value_not_zero(b, &dummy)) {
/* 0 / non-Const = 0 */
vb = va = a;
goto make_tuple;
}
if (evaluated) { /* replace by tuple */
ir_node *mem, *blk;
make_tuple:
mem = get_DivMod_mem(n);
/* skip a potential Pin */
mem = skip_Pin(mem);
blk = get_nodes_block(n);
turn_into_tuple(n, pn_DivMod_max);
set_Tuple_pred(n, pn_DivMod_M, mem);
set_Tuple_pred(n, pn_DivMod_X_regular, new_r_Jmp(blk));
set_Tuple_pred(n, pn_DivMod_X_except, get_irg_bad(irg)); /*no exception*/
set_Tuple_pred(n, pn_DivMod_res_div, va);
set_Tuple_pred(n, pn_DivMod_res_mod, vb);
}
return n;
} /* transform_node_DivMod */
/**
* Optimize x / c to x * (1/c)
*/
......@@ -3977,71 +3808,6 @@ static ir_node *transform_node_Proj_Mod(ir_node *proj)
return