DBG_OPT_ALGSIM0(oldn, n, FS_OPT_AND);
return n;
}
- /* constants are cormalized to right, check this site first */
+ /* constants are normalized to right, check this site first */
tv = value_of(b);
if (tarval_is_all_one(tv)) {
n = a;
DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
return 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_mode *convopmode = get_irn_mode(convop);
+ if (!mode_is_signed(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);
+ return n;
+ }
+ }
+ }
+ }
tv = value_of(a);
if (tarval_is_all_one(tv)) {
n = b;
/* 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(). */
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
CASE(End);
CASE(Mux);
CASE(Sync);
+ CASE(Call);
default:
/* leave NULL */;
}
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 */
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. */
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. */
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. */
static int node_cmp_attr_Confirm(ir_node *a, ir_node *b) {
+ /* no need to compare the bound, as this is a input */
return (get_Confirm_cmp(a) != get_Confirm_cmp(b));
} /* node_cmp_attr_Confirm */
+/** Compares the attributes of two Builtin nodes. */
+static int node_cmp_attr_Builtin(ir_node *a, ir_node *b) {
+ const builtin_attr *ma = get_irn_builtin_attr(a);
+ const builtin_attr *mb = get_irn_builtin_attr(b);
+
+ /* no need to compare the type, equal kind means equal type */
+ return ma->kind != mb->kind;
+} /* node_cmp_attr_Builtin */
+
/** Compares the attributes of two ASM nodes. */
static int node_cmp_attr_ASM(ir_node *a, ir_node *b) {
int i, n;
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.
*
CASE(Mod);
CASE(Quot);
CASE(Bound);
+ CASE(Builtin);
+ CASE(Dummy);
/* FIXME CopyB */
default:
/* leave NULL */;