#include "irpass_t.h"
#include "iropt_dbg.h"
#include "error.h"
+#include "be.h"
/** Walker environment. */
-typedef struct _walker_env {
+typedef struct walker_env {
pmap *c_map; /**< The intrinsic call map. */
unsigned nr_of_intrinsics; /**< statistics */
i_instr_record **i_map; /**< The intrinsic instruction map. */
walker_env_t wenv;
/* we use the ir_op generic pointers here */
- NEW_ARR_A(const i_instr_record *, i_map, n_ops);
+ NEW_ARR_A(i_instr_record *, i_map, n_ops);
memset((void *)i_map, 0, sizeof(*i_map) * n_ops);
/* fill a map for faster search */
*/
static void replace_call(ir_node *irn, ir_node *call, ir_node *mem, ir_node *reg_jmp, ir_node *exc_jmp)
{
- ir_node *block = get_nodes_block(call);
+ ir_node *block = get_nodes_block(call);
+ ir_graph *irg = get_irn_irg(block);
if (reg_jmp == NULL) {
set_opt_cse(0);
reg_jmp = new_r_Jmp(block);
set_opt_cse(old_cse);
- exc_jmp = new_Bad();
+ exc_jmp = new_r_Bad(irg);
}
irn = new_r_Tuple(block, 1, &irn);
set_Tuple_pred(call, pn_Call_X_regular, reg_jmp);
set_Tuple_pred(call, pn_Call_X_except, exc_jmp);
set_Tuple_pred(call, pn_Call_T_result, irn);
- set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());
+ set_Tuple_pred(call, pn_Call_P_value_res_base, new_r_Bad(irg));
} /* replace_call */
/* A mapper for the integer abs. */
int i_mapper_abs(ir_node *call, void *ctx)
{
- ir_node *mem = get_Call_mem(call);
- ir_node *block = get_nodes_block(call);
- ir_node *op = get_Call_param(call, 0);
- ir_node *irn;
- dbg_info *dbg = get_irn_dbg_info(call);
+ ir_node *mem = get_Call_mem(call);
+ ir_node *block = get_nodes_block(call);
+ ir_node *op = get_Call_param(call, 0);
+ ir_graph *irg = get_irn_irg(call);
+ ir_mode *mode = get_irn_mode(op);
+ dbg_info *dbg = get_irn_dbg_info(call);
+ ir_node *zero = new_r_Const(irg, get_mode_null(mode));
+ ir_node *cmp = new_rd_Cmp(dbg, block, op, zero);
+ ir_node *cond = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
+ ir_node *minus_op = new_rd_Minus(dbg, block, op, mode);
+ ir_node *mux;
+ arch_allow_ifconv_func allow_ifconv = be_get_backend_param()->allow_ifconv;
(void) ctx;
- irn = new_rd_Abs(dbg, block, op, get_irn_mode(op));
- DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_ABS);
- replace_call(irn, call, mem, NULL, NULL);
+ /* mux allowed by backend? */
+ if (!allow_ifconv(cond, op, minus_op))
+ return 0;
+
+ /* construct Mux */
+ mux = new_rd_Mux(dbg, block, cond, op, minus_op, mode);
+ DBG_OPT_ALGSIM0(call, mux, FS_OPT_RTS_ABS);
+ replace_call(mux, call, mem, NULL, NULL);
return 1;
} /* i_mapper_abs */
irn = new_rd_Builtin(dbg, block, get_irg_no_mem(current_ir_graph), 1, &op, ir_bk_bswap, tp);
set_irn_pinned(irn, op_pin_state_floats);
- DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_ABS);
irn = new_r_Proj(irn, get_irn_mode(op), pn_Builtin_1_result);
replace_call(irn, call, mem, NULL, NULL);
return 1;
int i_mapper_pow(ir_node *call, void *ctx)
{
dbg_info *dbg;
- ir_node *mem;
- ir_node *left = get_Call_param(call, 0);
- ir_node *right = get_Call_param(call, 1);
- ir_node *block = get_nodes_block(call);
- ir_node *irn, *reg_jmp = NULL, *exc_jmp = NULL;
+ ir_node *mem;
+ ir_node *left = get_Call_param(call, 0);
+ ir_node *right = get_Call_param(call, 1);
+ ir_node *block = get_nodes_block(call);
+ ir_graph *irg = get_irn_irg(block);
+ ir_node *irn, *reg_jmp = NULL, *exc_jmp = NULL;
(void) ctx;
if (is_Const(left) && is_Const_one(left)) {
if (tarval_is_null(tv)) {
/* pow(x, 0.0) = 1.0 */
ir_mode *mode = get_tarval_mode(tv);
- irn = new_Const(get_mode_one(mode));
+ irn = new_r_Const(irg, get_mode_one(mode));
} else if (tarval_is_one(tv)) {
/* pow(x, 1.0) = x */
irn = left;
ir_mode *mode = get_irn_mode(left);
ir_node *quot;
- irn = new_Const(get_mode_one(mode));
+ irn = new_r_Const(irg, get_mode_one(mode));
quot = new_rd_Quot(dbg, block, mem, irn, left, mode, op_pin_state_pinned);
mem = new_r_Proj(quot, mode_M, pn_Quot_M);
irn = new_r_Proj(quot, mode, pn_Quot_res);
if (is_Const(val) && is_Const_null(val)) {
/* exp(0.0) = 1.0 */
+ ir_graph *irg = get_irn_irg(val);
ir_mode *mode = get_irn_mode(val);
- ir_node *irn = new_Const(get_mode_one(mode));
+ ir_node *irn = new_r_Const(irg, get_mode_one(mode));
ir_node *mem = get_Call_mem(call);
DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_EXP);
replace_call(irn, call, mem, NULL, NULL);
if (is_Const(val) && is_Const_one(val)) {
/* acos(1.0) = 0.0 */
- ir_mode *mode = get_irn_mode(val);
- ir_node *irn = new_Const(get_mode_null(mode));
- ir_node *mem = get_Call_mem(call);
+ ir_graph *irg = get_irn_irg(val);
+ ir_mode *mode = get_irn_mode(val);
+ ir_node *irn = new_r_Const(irg, get_mode_null(mode));
+ ir_node *mem = get_Call_mem(call);
DBG_OPT_ALGSIM0(call, irn, reason);
replace_call(irn, call, mem, NULL, NULL);
return 1;
if (is_Const(val) && is_Const_null(val)) {
/* f(0.0) = 1.0 */
+ ir_graph *irg = get_irn_irg(val);
ir_mode *mode = get_irn_mode(val);
- ir_node *irn = new_Const(get_mode_one(mode));
+ ir_node *irn = new_r_Const(irg, get_mode_one(mode));
ir_node *mem = get_Call_mem(call);
DBG_OPT_ALGSIM0(call, irn, reason);
replace_call(irn, call, mem, NULL, NULL);
* @return a Const node containing the strlen() result or NULL
* if the evaluation fails
*/
-static ir_node *eval_strlen(ir_entity *ent, ir_type *res_tp)
+static ir_node *eval_strlen(ir_graph *irg, ir_entity *ent, ir_type *res_tp)
{
ir_type *tp = get_entity_type(ent);
ir_mode *mode;
}
if (len >= 0) {
tarval *tv = new_tarval_from_long(len, get_type_mode(res_tp));
- return new_Const_type(tv, res_tp);
+ return new_r_Const(irg, tv);
}
return NULL;
}
ir_initializer_t *val = get_initializer_compound_value(initializer, i);
if (initializer_val_is_null(val)) {
tarval *tv = new_tarval_from_long(i, get_type_mode(res_tp));
- return new_Const_type(tv, res_tp);
+ return new_r_Const(irg, tv);
}
}
ir_node *irn;
tp = get_method_res_type(tp, 0);
- irn = eval_strlen(ent, tp);
+ irn = eval_strlen(get_irn_irg(call), ent, tp);
if (irn) {
ir_node *mem = get_Call_mem(call);
* @return a Const node containing the strcmp() result or NULL
* if the evaluation fails
*/
-static ir_node *eval_strcmp(ir_entity *left, ir_entity *right, ir_type *res_tp)
+static ir_node *eval_strcmp(ir_graph *irg, ir_entity *left, ir_entity *right,
+ ir_type *res_tp)
{
ir_type *tp;
ir_mode *mode;
if (i < n) {
/* we found an end */
tarval *tv = new_tarval_from_long(res, get_type_mode(res_tp));
- return new_Const_type(tv, res_tp);
+ return new_r_Const(irg, tv);
}
return NULL;
}
if (left == right) {
/* a strcmp(s, s) ==> 0 */
+ ir_graph *irg = get_irn_irg(call);
ir_node *mem = get_Call_mem(call);
ir_mode *mode = get_type_mode(res_tp);
- irn = new_Const(get_mode_null(mode));
+ irn = new_r_Const(irg, get_mode_null(mode));
DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_STRCMP);
replace_call(irn, call, mem, NULL, NULL);
return 1;
if (ent_l != NULL && ent_r != NULL) {
/* both entities are const, try to evaluate */
- irn = eval_strcmp(ent_l, ent_r, res_tp);
+ irn = eval_strcmp(get_irn_irg(call), ent_l, ent_r, res_tp);
} else if (ent_l != NULL) {
if (is_empty_string(ent_l)) {
/* s strcmp("", s) ==> -(*s)*/
if (left == right || (is_Const(len) && is_Const_null(len))) {
/* a strncmp(s, s, len) ==> 0 OR
a strncmp(a, b, 0) ==> 0 */
+ ir_graph *irg = get_irn_irg(call);
ir_node *mem = get_Call_mem(call);
ir_node *adr = get_Call_ptr(call);
ir_entity *ent = get_SymConst_entity(adr);
ir_type *res_tp = get_method_res_type(call_tp, 0);
ir_mode *mode = get_type_mode(res_tp);
- irn = new_Const(get_mode_null(mode));
+ irn = new_r_Const(irg, get_mode_null(mode));
DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_STRNCMP);
replace_call(irn, call, mem, NULL, NULL);
return 1;
if (left == right || (is_Const(len) && is_Const_null(len))) {
/* a memcmp(s, s, len) ==> 0 OR
a memcmp(a, b, 0) ==> 0 */
+ ir_graph *irg = get_irn_irg(call);
ir_node *mem = get_Call_mem(call);
ir_node *adr = get_Call_ptr(call);
ir_entity *ent = get_SymConst_entity(adr);
ir_type *res_tp = get_method_res_type(call_tp, 0);
ir_mode *mode = get_type_mode(res_tp);
- irn = new_Const(get_mode_null(mode));
+ irn = new_r_Const(irg, get_mode_null(mode));
DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_STRNCMP);
replace_call(irn, call, mem, NULL, NULL);
return 1;