X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=25d0cd8a185a0cb3fbabe4f603de93c82b90d3fc;hb=69d11aa49aa17358468bbb2f5506ef5f009514e9;hp=d21081057f125058b65b95fde84717cb1cf72879;hpb=ac007947cfda21b5c40f722e79fcc5baf81a2102;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index d21081057..25d0cd8a1 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -1178,10 +1178,10 @@ static ir_node *equivalent_node_And(ir_node *n) { if (tv != get_tarval_bad()) { ir_mode *mode = get_irn_mode(n); if (!mode_is_signed(mode) && is_Conv(a)) { - ir_node *convop = get_Conv_op(a); + ir_node *convop = get_Conv_op(a); ir_mode *convopmode = get_irn_mode(convop); if (!mode_is_signed(convopmode)) { - if (new_tarval_from_long(get_tarval_long(tv), convopmode) == get_mode_all_one(convopmode)) { + if (tarval_is_all_one(tarval_convert_to(tv, convopmode))) { /* Conv(X) & all_one(mode(X)) = Conv(X) */ n = a; DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND); @@ -3954,7 +3954,7 @@ static ir_node *transform_node_Proj_Cond(ir_node *proj) { /* we have a constant switch */ long num = get_Proj_proj(proj); - if (num != get_Cond_defaultProj(n)) { /* we cannot optimize default Proj's yet */ + if (num != get_Cond_default_proj(n)) { /* we cannot optimize default Proj's yet */ if (get_tarval_long(tb) == num) { /* Do NOT create a jump here, or we will have 2 control flow ops * in a block. This case is optimized away in optimize_cf(). */ @@ -5708,7 +5708,80 @@ static ir_node *transform_node_Sync(ir_node *n) { add_identities(current_ir_graph->value_table, n); return n; -} +} /* transform_node_Sync */ + +/** + * optimize a trampoline Call into a direct Call + */ +static ir_node *transform_node_Call(ir_node *call) { + ir_node *callee = get_Call_ptr(call); + ir_node *adr, *mem, *res, *bl, **in; + ir_type *ctp, *mtp, *tp; + ident *id; + dbg_info *db; + int i, n_res, n_param; + ir_variadicity var; + + if (! is_Proj(callee)) + return call; + callee = get_Proj_pred(callee); + if (! is_Builtin(callee)) + return call; + if (get_Builtin_kind(callee) != ir_bk_inner_trampoline) + return call; + + mem = get_Call_mem(call); + + if (skip_Proj(mem) == callee) { + /* memory is routed to the trampoline, skip */ + mem = get_Builtin_mem(callee); + } + + /* build a new call type */ + mtp = get_Call_type(call); + id = get_type_ident(mtp); + id = id_mangle(new_id_from_chars("T_", 2), id); + db = get_type_dbg_info(mtp); + + n_res = get_method_n_ress(mtp); + n_param = get_method_n_params(mtp); + ctp = new_d_type_method(id, n_param + 1, n_res, db); + + for (i = 0; i < n_res; ++i) + set_method_res_type(ctp, i, get_method_res_type(mtp, i)); + + NEW_ARR_A(ir_node *, in, n_param + 1); + + /* FIXME: we don't need a new pointer type in every step */ + tp = get_irg_frame_type(current_ir_graph); + id = id_mangle(get_type_ident(tp), new_id_from_chars("_ptr", 4)); + tp = new_type_pointer(id, tp, mode_P_data); + set_method_param_type(ctp, 0, tp); + + in[0] = get_Builtin_param(callee, 2); + for (i = 0; i < n_param; ++i) { + set_method_param_type(ctp, i + 1, get_method_param_type(mtp, i)); + in[i + 1] = get_Call_param(call, i); + } + var = get_method_variadicity(mtp); + set_method_variadicity(ctp, var); + if (var == variadicity_variadic) { + set_method_first_variadic_param_index(ctp, get_method_first_variadic_param_index(mtp) + 1); + } + /* When we resolve a trampoline, the function must be called by a this-call */ + set_method_calling_convention(ctp, get_method_calling_convention(mtp) | cc_this_call); + set_method_additional_properties(ctp, get_method_additional_properties(mtp)); + + adr = get_Builtin_param(callee, 1); + + db = get_irn_dbg_info(call); + bl = get_nodes_block(call); + + res = new_rd_Call(db, current_ir_graph, bl, mem, adr, n_param + 1, in, ctp); + if (get_irn_pinned(call) == op_pin_state_floats) + set_irn_pinned(res, op_pin_state_floats); + return res; +} /* transform_node_Call */ /** * Tries several [inplace] [optimizing] transformations and returns an @@ -5790,6 +5863,7 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops CASE(End); CASE(Mux); CASE(Sync); + CASE(Call); default: /* leave NULL */; } @@ -5928,7 +6002,7 @@ static int node_cmp_attr_Div(ir_node *a, ir_node *b) { const divmod_attr *ma = get_irn_divmod_attr(a); const divmod_attr *mb = get_irn_divmod_attr(b); return ma->exc.pin_state != mb->exc.pin_state || - ma->res_mode != mb->res_mode || + ma->resmode != mb->resmode || ma->no_remainder != mb->no_remainder; } /* node_cmp_attr_Div */ @@ -5937,7 +6011,7 @@ static int node_cmp_attr_DivMod(ir_node *a, ir_node *b) { const divmod_attr *ma = get_irn_divmod_attr(a); const divmod_attr *mb = get_irn_divmod_attr(b); return ma->exc.pin_state != mb->exc.pin_state || - ma->res_mode != mb->res_mode; + ma->resmode != mb->resmode; } /* node_cmp_attr_DivMod */ /** Compares the attributes of two Mod nodes. */ @@ -5945,7 +6019,7 @@ static int node_cmp_attr_Mod(ir_node *a, ir_node *b) { const divmod_attr *ma = get_irn_divmod_attr(a); const divmod_attr *mb = get_irn_divmod_attr(b); return ma->exc.pin_state != mb->exc.pin_state || - ma->res_mode != mb->res_mode; + ma->resmode != mb->resmode; } /* node_cmp_attr_Mod */ /** Compares the attributes of two Quot nodes. */ @@ -5953,7 +6027,7 @@ static int node_cmp_attr_Quot(ir_node *a, ir_node *b) { const divmod_attr *ma = get_irn_divmod_attr(a); const divmod_attr *mb = get_irn_divmod_attr(b); return ma->exc.pin_state != mb->exc.pin_state || - ma->res_mode != mb->res_mode; + ma->resmode != mb->resmode; } /* node_cmp_attr_Quot */ /** Compares the attributes of two Confirm nodes. */ @@ -6017,6 +6091,14 @@ static int node_cmp_attr_ASM(ir_node *a, ir_node *b) { return 0; } /* node_cmp_attr_ASM */ +/** Compares the inexistent attributes of two Dummy nodes. */ +static int node_cmp_attr_Dummy(ir_node *a, ir_node *b) +{ + (void) a; + (void) b; + return 1; +} + /** * Set the default node attribute compare operation for an ir_op_ops. * @@ -6055,6 +6137,7 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops) CASE(Quot); CASE(Bound); CASE(Builtin); + CASE(Dummy); /* FIXME CopyB */ default: /* leave NULL */;