Commit 31fc92ec by Matthias Braun

### remove Quot node (just use Div instead)

`[r28346]`
parent 8b5aac95
 ... ... @@ -268,7 +268,6 @@ * ir_node *new_Minus (ir_node *op, ir_mode *mode); * 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_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); ... ... @@ -686,19 +685,6 @@ * * Returns the high order bits of a n*n=2n multiplication. * * ir_node *new_Quot (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state) * ------------------------------------------------------------------------------------------------- * * Quot performs exact division of floating point numbers. It's mode * is Tuple, the mode of the result must match the Proj mode * that extracts the result of the arithmetic operations. * * Inputs: * The store needed to model exceptions and the two operands. * Output: * A tuple containing a memory and a execution for modeling exceptions * and the result of the arithmetic operation. * * ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state) * ------------------------------------------------------------------------------------------------ * ... ...
 ... ... @@ -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, Div, Mod, And, Or, Eor, Shl, binops are: Add, Sub, Mul, 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,7 +619,7 @@ 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, Div, Mod, Load, Store, Alloc, of an exception: Call, 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. */ ... ...
 ... ... @@ -522,16 +522,6 @@ FIRM_API ir_tarval *tarval_sub(ir_tarval *a, ir_tarval *b, ir_mode *dst_mode); */ FIRM_API ir_tarval *tarval_mul(ir_tarval *a, ir_tarval *b); /** * Division of two floating point tarvals. * * @param a the first tarval * @param b the second tarval * * @return a / b or tarval_bad */ FIRM_API ir_tarval *tarval_quo(ir_tarval *a, ir_tarval *b); /** * Integer division of two tarvals. * ... ...
 ... ... @@ -370,7 +370,7 @@ static int vrp_update_node(ir_node *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) is_Pin(node) is_Proj(node) is_Quot(node) is_Pin(node) is_Proj(node) is_Raise(node) is_Return(node) is_Sel(node) is_Start(node) is_Store(node) is_SymConst(node) is_Sync(node) is_Tuple(node) */ ... ...
 ... ... @@ -77,8 +77,10 @@ static ir_node *gen_Eor(ir_node *node) return transform_binop(node, new_bd_TEMPLATE_Xor); } static ir_node *gen_Quot(ir_node *node) static ir_node *gen_Div(ir_node *node) { ir_mode *mode = get_Div_resmode(node); assert(mode_is_float(mode)); return transform_binop(node, new_bd_TEMPLATE_fDiv); } ... ... @@ -254,6 +256,7 @@ static void TEMPLATE_register_transformers(void) be_set_transform_function(op_Add, gen_Add); be_set_transform_function(op_And, gen_And); be_set_transform_function(op_Const, gen_Const); be_set_transform_function(op_Div, gen_Div); be_set_transform_function(op_Eor, gen_Eor); be_set_transform_function(op_Jmp, gen_Jmp); be_set_transform_function(op_Load, gen_Load); ... ... @@ -262,7 +265,6 @@ static void TEMPLATE_register_transformers(void) be_set_transform_function(op_Not, gen_Not); be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Shl, gen_Shl); be_set_transform_function(op_Shr, gen_Shr); be_set_transform_function(op_Store, gen_Store); ... ...
 ... ... @@ -568,17 +568,19 @@ static ir_node *gen_Mul(ir_node *node) return new_bd_arm_Mul(dbg, block, new_op1, new_op2); } static ir_node *gen_Quot(ir_node *node) static ir_node *gen_Div(ir_node *node) { ir_node *block = be_transform_node(get_nodes_block(node)); ir_node *op1 = get_Quot_left(node); ir_node *op1 = get_Div_left(node); ir_node *new_op1 = be_transform_node(op1); ir_node *op2 = get_Quot_right(node); ir_node *op2 = get_Div_right(node); ir_node *new_op2 = be_transform_node(op2); ir_mode *mode = get_irn_mode(node); ir_mode *mode = get_Div_resmode(node); dbg_info *dbg = get_irn_dbg_info(node); assert(mode != mode_E && "IEEE Extended FP not supported"); /* integer division should be replaced by builtin call */ assert(mode_is_float(mode)); if (USE_FPA(isa)) { return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode); ... ... @@ -1378,7 +1380,7 @@ static ir_node *gen_Proj_CopyB(ir_node *node) panic("Unsupported Proj from CopyB"); } static ir_node *gen_Proj_Quot(ir_node *node) static ir_node *gen_Proj_Div(ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = be_transform_node(pred); ... ... @@ -1387,20 +1389,14 @@ static ir_node *gen_Proj_Quot(ir_node *node) long proj = get_Proj_proj(node); switch (proj) { case pn_Quot_M: if (is_arm_Dvf(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_arm_Dvf_M); } break; case pn_Quot_res: if (is_arm_Dvf(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode, pn_arm_Dvf_res); } break; case pn_Div_M: return new_rd_Proj(dbgi, new_pred, mode_M, pn_arm_Dvf_M); case pn_Div_res: return new_rd_Proj(dbgi, new_pred, mode, pn_arm_Dvf_res); default: break; } panic("Unsupported Proj from Quot"); panic("Unsupported Proj from Div"); } /** ... ... @@ -1592,8 +1588,8 @@ static ir_node *gen_Proj(ir_node *node) return gen_Proj_Call(node); case iro_CopyB: return gen_Proj_CopyB(node); case iro_Quot: return gen_Proj_Quot(node); case iro_Div: return gen_Proj_Div(node); case iro_Cmp: return gen_Proj_Cmp(node); case iro_Start: ... ... @@ -2095,6 +2091,7 @@ static void arm_register_transformers(void) be_set_transform_function(op_Const, gen_Const); be_set_transform_function(op_Conv, gen_Conv); be_set_transform_function(op_CopyB, gen_CopyB); be_set_transform_function(op_Div, gen_Div); be_set_transform_function(op_Eor, gen_Eor); be_set_transform_function(op_Jmp, gen_Jmp); be_set_transform_function(op_Load, gen_Load); ... ... @@ -2104,7 +2101,6 @@ static void arm_register_transformers(void) be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); be_set_transform_function(op_Proj, gen_Proj); be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Return, gen_Return); be_set_transform_function(op_Rotl, gen_Rotl); be_set_transform_function(op_Sel, gen_Sel); ... ...
 ... ... @@ -1069,8 +1069,6 @@ static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2, 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"); } ... ... @@ -1618,27 +1616,20 @@ static ir_node *gen_Mod(ir_node *node) */ static ir_node *gen_Div(ir_node *node) { return create_Div(node); } /** * Creates an ia32 floating Div. * * @return The created ia32 xDiv node */ static ir_node *gen_Quot(ir_node *node) { ir_node *op1 = get_Quot_left(node); ir_node *op2 = get_Quot_right(node); ir_mode *mode = get_Div_resmode(node); if (mode_is_float(mode)) { ir_node *op1 = get_Div_left(node); ir_node *op2 = get_Div_right(node); if (ia32_cg_config.use_sse2) { return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am); } else { return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv); if (ia32_cg_config.use_sse2) { return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am); } else { return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv); } } } return create_Div(node); } /** * Creates an ia32 Shl. ... ... @@ -4576,7 +4567,7 @@ static ir_node *gen_Proj_Load(ir_node *node) /** * Transform and renumber the Projs from a Div or Mod instruction. */ static ir_node *gen_Proj_Div_Mod(ir_node *node) static ir_node *gen_Proj_Div(ir_node *node) { ir_node *block = be_transform_node(get_nodes_block(node)); ir_node *pred = get_Proj_pred(node); ... ... @@ -4584,73 +4575,74 @@ static ir_node *gen_Proj_Div_Mod(ir_node *node) dbg_info *dbgi = get_irn_dbg_info(node); long proj = get_Proj_proj(node); assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)); assert(pn_ia32_Div_M == pn_ia32_IDiv_M); assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res); switch (get_irn_opcode(pred)) { case iro_Div: switch (proj) { case pn_Div_M: switch (proj) { case pn_Div_M: if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M); case pn_Div_res: return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res); case pn_Div_X_regular: return new_rd_Jmp(dbgi, block); case pn_Div_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; } else if (is_ia32_xDiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M); } else if (is_ia32_vfdiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M); } else { panic("Div transformed to unexpected thing %+F", new_pred); } break; case iro_Mod: switch (proj) { case pn_Mod_M: return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M); case pn_Mod_res: return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res); case pn_Mod_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; case pn_Div_res: if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res); } else if (is_ia32_xDiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res); } else if (is_ia32_vfdiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res); } else { panic("Div transformed to unexpected thing %+F", new_pred); } break; case pn_Div_X_regular: return new_rd_Jmp(dbgi, block); case pn_Div_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; } panic("No idea how to transform proj->Div/Mod"); panic("No idea how to transform proj->Div"); } /** * Transform and renumber the Projs from a CopyB. * Transform and renumber the Projs from a Div or Mod instruction. */ static ir_node *gen_Proj_CopyB(ir_node *node) static ir_node *gen_Proj_Mod(ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = be_transform_node(pred); dbg_info *dbgi = get_irn_dbg_info(node); long proj = get_Proj_proj(node); assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)); assert(pn_ia32_Div_M == pn_ia32_IDiv_M); assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res); switch (proj) { case pn_CopyB_M: if (is_ia32_CopyB_i(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M); } else if (is_ia32_CopyB(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M); } break; case pn_Mod_M: return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M); case pn_Mod_res: return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res); case pn_Mod_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; } panic("No idea how to transform proj->CopyB"); panic("No idea how to transform proj->Mod"); } /** * Transform and renumber the Projs from a Quot. * Transform and renumber the Projs from a CopyB. */ static ir_node *gen_Proj_Quot(ir_node *node) static ir_node *gen_Proj_CopyB(ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = be_transform_node(pred); ... ... @@ -4658,27 +4650,18 @@ static ir_node *gen_Proj_Quot(ir_node *node) long proj = get_Proj_proj(node); switch (proj) { case pn_Quot_M: if (is_ia32_xDiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M); } else if (is_ia32_vfdiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M); } break; case pn_Quot_res: if (is_ia32_xDiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res); } else if (is_ia32_vfdiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res); case pn_CopyB_M: if (is_ia32_CopyB_i(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M); } else if (is_ia32_CopyB(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M); } break; case pn_Quot_X_regular: case pn_Quot_X_except: default: break; } panic("No idea how to transform proj->Quot"); panic("No idea how to transform proj->CopyB"); } static ir_node *gen_be_Call(ir_node *node) ... ... @@ -5598,12 +5581,11 @@ static ir_node *gen_Proj(ir_node *node) case iro_Builtin: return gen_Proj_Builtin(node); case iro_Div: return gen_Proj_Div(node); case iro_Mod: return gen_Proj_Div_Mod(node); return gen_Proj_Mod(node); case iro_CopyB: return gen_Proj_CopyB(node); case iro_Quot: return gen_Proj_Quot(node); case beo_SubSP: return gen_Proj_be_SubSP(node); case beo_AddSP: ... ... @@ -5713,7 +5695,6 @@ static void register_transformers(void) be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); be_set_transform_function(op_Proj, gen_Proj); be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Rotl, gen_Rotl); be_set_transform_function(op_Shl, gen_Shl); be_set_transform_function(op_Shr, gen_Shr); ... ...
 ... ... @@ -640,7 +640,11 @@ static ir_node *gen_Div(ir_node *node) ir_node *right = get_Div_right(node); ir_node *res; assert(!mode_is_float(mode)); if (mode_is_float(mode)) { return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv_s, new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q); } if (mode_is_signed(mode)) { ir_node *left_high = gen_sign_extension_value(left); ... ... @@ -669,14 +673,6 @@ static ir_node *gen_Div(ir_node *node) return res; } static ir_node *gen_Quot(ir_node *node) { ir_mode *mode = get_Quot_resmode(node); assert(mode_is_float(mode)); return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv_s, new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q); } #if 0 static ir_node *gen_Abs(ir_node *node) { ... ... @@ -1844,6 +1840,8 @@ static ir_node *gen_Proj_Div(ir_node *node) assert(is_sparc_SDiv(new_pred) || is_sparc_UDiv(new_pred)); assert((int)pn_sparc_SDiv_res == (int)pn_sparc_UDiv_res); assert((int)pn_sparc_SDiv_M == (int)pn_sparc_UDiv_M); assert((int)pn_sparc_SDiv_res == (int)pn_sparc_fdiv_res); assert((int)pn_sparc_SDiv_M == (int)pn_sparc_fdiv_M); switch (pn) { case pn_Div_res: return new_r_Proj(new_pred, mode_gp, pn_sparc_SDiv_res); ... ... @@ -1855,24 +1853,6 @@ static ir_node *gen_Proj_Div(ir_node *node) panic("Unsupported Proj from Div"); } static ir_node *gen_Proj_Quot(ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = be_transform_node(pred); long pn = get_Proj_proj(node); assert(is_sparc_fdiv(new_pred)); switch (pn) { case pn_Quot_res: return new_r_Proj(new_pred, mode_gp, pn_sparc_fdiv_res); case pn_Quot_M: return new_r_Proj(new_pred, mode_gp, pn_sparc_fdiv_M); default: break; } panic("Unsupported Proj from Quot"); } static ir_node *get_frame_base(void) { const arch_register_t *reg = cconv->omit_fp ? sp_reg : fp_reg; ... ... @@ -2047,8 +2027,6 @@ static ir_node *gen_Proj(ir_node *node) return be_duplicate_node(node); case iro_Div: return gen_Proj_Div(node); case iro_Quot: return gen_Proj_Quot(node); case iro_Start: return gen_Proj_Start(node); case iro_Proj: { ... ... @@ -2102,7 +2080,6 @@ static void sparc_register_transformers(void) be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); be_set_transform_function(op_Proj, gen_Proj); be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Return, gen_Return); be_set_transform_function(op_Sel, gen_Sel); be_set_transform_function(op_Shl, gen_Shl); ... ...
 ... ... @@ -832,16 +832,6 @@ static const pns_lookup_t call_lut[] = { #undef X }; /** the lookup table for Proj(Quot) names */ static const pns_lookup_t quot_lut[] = { #define X(a) { pn_Quot_##a, #a } X(M), X(X_regular), X(X_except), X(res) #undef X }; /** the lookup table for Proj(Div) names */ static const pns_lookup_t div_lut[] = { #define X(a) { pn_Div_##a, #a } ... ... @@ -934,7 +924,6 @@ static const proj_lookup_t proj_lut[] = { { iro_Start, E(start_lut) }, { iro_Cond, E(cond_lut) }, { iro_Call, E(call_lut) }, { iro_Quot, E(quot_lut) }, { iro_Div, E(div_lut) }, { iro_Mod, E(mod_lut) }, { iro_Load, E(load_lut) }, ... ...
 ... ... @@ -1575,7 +1575,6 @@ ir_node *get_fragile_op_mem(ir_node *node) switch (get_irn_opcode(node)) { case iro_Call : case iro_Quot : case iro_Div : case iro_Mod : case iro_Load : ... ...
 ... ... @@ -543,20 +543,6 @@ static ir_tarval *computed_value_Proj_Cmp(const ir_node *n) return computed_value_Cmp_Confirm(cmp, left, right, pn_cmp); } /* computed_value_Proj_Cmp */ /** * Return the value of a floating point Quot. */ static ir_tarval *do_computed_value_Quot(const ir_node *a, const ir_node *b) { ir_tarval *ta = value_of(a); ir_tarval *tb = value_of(b); /* cannot optimize 0 / b = 0 because of NaN */ if (ta != tarval_bad && tb != tarval_bad) return tarval_quo(ta, tb); return tarval_bad; } /* do_computed_value_Quot */ /** * Calculate the value of an integer Div of two nodes. * Special case: 0 / b ... ... @@ -621,20 +607,6 @@ static ir_tarval *computed_value_Proj_Mod(const ir_node *n) return tarval_bad; } /* computed_value_Proj_Mod */ /** * Return the value of a Proj(Quot). */ static ir_tarval *computed_value_Proj_Quot(const ir_node *n) { long proj_nr = get_Proj_proj(n); if (proj_nr == pn_Quot_res) { const ir_node *a = get_Proj_pred(n); return do_computed_value_Quot(get_Quot_left(a), get_Quot_right(a)); } return tarval_bad; } /* computed_value_Proj_Quot */ /** * Return the value of a Proj. */ ... ... @@ -707,7 +679,6 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops CASE_PROJ(Cmp); CASE_PROJ(Div); CASE_PROJ(Mod); CASE_PROJ(Quot); CASE(Proj); default: /* leave NULL */ ... ... @@ -1514,38 +1485,6 @@ static ir_node *equivalent_node_Proj_Div(ir_node *proj) return proj; } /* equivalent_node_Proj_Div */ /** * Optimize a / 1.0 = a. */ static ir_node *equivalent_node_Proj_Quot(ir_node *proj) { ir_node *oldn = proj; ir_node *quot = get_Proj_pred(proj); ir_node *b = get_Quot_right(quot); ir_tarval *tb = value_of(b); /* Div is not commutative. */ if (tarval_is_one(tb)) { /* Quot(x, 1) == x */ switch (get_Proj_proj(proj)) { case pn_Quot_M: proj = get_Quot_mem(quot); DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1); return proj; case pn_Quot_res: proj = get_Quot_left(quot); 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_Quot() */ return proj; } } return proj; } /* equivalent_node_Proj_Quot */ /** * Optimize CopyB(mem, x, x) into a Nop. */ ... ... @@ -1895,7 +1834,6 @@ static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *op CASE(Sync); CASE_PROJ(Tuple);