#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. */
*/
static void call_mapper(ir_node *node, void *env)
{
- walker_env_t *wenv = env;
+ walker_env_t *wenv = (walker_env_t*)env;
ir_op *op = get_irn_op(node);
if (op == op_Call) {
p = pmap_find(wenv->c_map, ent);
if (p) {
- r = p->value;
+ r = (const i_call_record*)p->value;
wenv->nr_of_intrinsics += r->i_mapper(node, r->ctx) ? 1 : 0;
}
} else {
++wenv->nr_of_intrinsics;
break;
}
- r = r->link;
+ r = (const i_instr_record*)r->link;
}
}
}
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 */
return nr_of_intrinsics;
} /* lower_intrinsics */
-struct pass_t {
+typedef struct pass_t {
ir_prog_pass_t pass;
int part_block_used;
int length;
i_record list[1];
-};
+} pass_t;
/**
* Wrapper for running lower_intrinsics() as an ir_prog pass.
*/
static int pass_wrapper(ir_prog *irp, void *context)
{
- struct pass_t *pass = context;
+ pass_t *pass = (pass_t*)context;
(void) irp; /* TODO: set current irp, or remove parameter */
lower_intrinsics(pass->list, pass->length, pass->part_block_used);
/* probably this pass should not run again */
const char *name,
i_record *list, int length, int part_block_used)
{
- struct pass_t *pass = xmalloc(sizeof(*pass) + (length-1) * sizeof(pass->list[0]));
+ pass_t *pass = (pass_t*)xmalloc(sizeof(*pass) + (length-1) * sizeof(pass->list[0]));
memcpy(pass->list, list, sizeof(list[0]) * length);
pass->length = length;
*/
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;
/* A mapper for the floating point sqrt. */
int i_mapper_sqrt(ir_node *call, void *ctx)
{
- ir_node *mem;
- tarval *tv;
- ir_node *op = get_Call_param(call, 0);
+ ir_node *mem;
+ ir_tarval *tv;
+ ir_node *op = get_Call_param(call, 0);
(void) ctx;
if (!is_Const(op))
/* A mapper for the floating point cbrt. */
int i_mapper_cbrt(ir_node *call, void *ctx)
{
- ir_node *mem;
- tarval *tv;
- ir_node *op = get_Call_param(call, 0);
+ ir_node *mem;
+ ir_tarval *tv;
+ ir_node *op = get_Call_param(call, 0);
(void) ctx;
if (!is_Const(op))
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)) {
/* pow (1.0, x) = 1.0 */
irn = left;
} else if (is_Const(right)) {
- tarval *tv = get_Const_tarval(right);
+ ir_tarval *tv = get_Const_tarval(right);
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);
static bool initializer_val_is_null(ir_initializer_t *init)
{
- tarval *tv;
+ ir_tarval *tv;
if (get_initializer_kind(init) == IR_INITIALIZER_NULL)
return true;
* @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);
+ ir_tarval *tv = new_tarval_from_long(len, get_type_mode(res_tp));
+ return new_r_Const(irg, tv);
}
return NULL;
}
for (i = 0; i < size; ++i) {
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);
+ ir_tarval *tv = new_tarval_from_long(i, get_type_mode(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;
for (i = 0; i < n; ++i) {
ir_node *irn;
long v_l, v_r;
- tarval *tv;
+ ir_tarval *tv;
irn = get_compound_ent_value(left, i);
if (! is_Const(irn))
}
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);
+ ir_tarval *tv = new_tarval_from_long(res, get_type_mode(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)*/
mode = get_type_mode(char_tp);
/* replace the strcmp by (*x) */
- irn = new_rd_Load(dbg, block, mem, v, mode, 0);
+ irn = new_rd_Load(dbg, block, mem, v, mode, cons_none);
mem = new_r_Proj(irn, mode_M, pn_Load_M);
exc = new_r_Proj(irn, mode_X, pn_Load_X_except);
reg = new_r_Proj(irn, mode_X, pn_Load_X_regular);
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;