X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Flower%2Flower_intrinsics.c;h=54abc9d766224346e3b2b9c2cfdea71f6bbd288d;hb=be375dcbb1195db1ed6a7ea7e4787456fb1d7b4f;hp=41d2b0ec556811d2a58d8b70009ba3dea71761dd;hpb=1e78e81405d64f8a8ad2a40e2ffdf9af2e86df8d;p=libfirm diff --git a/ir/lower/lower_intrinsics.c b/ir/lower/lower_intrinsics.c index 41d2b0ec5..54abc9d76 100644 --- a/ir/lower/lower_intrinsics.c +++ b/ir/lower/lower_intrinsics.c @@ -27,6 +27,8 @@ #include "irgwalk.h" #include "ircons.h" #include "irgmod.h" +#include "irgopt.h" +#include "trouts.h" #include "lower_intrinsics.h" #include "pmap.h" @@ -34,7 +36,7 @@ typedef struct _walker_env { pmap *c_map; /**< The intrinsic call map. */ unsigned nr_of_intrinsics; /**< statistics */ - const i_instr_record **i_map; /**< The intrinsic instruction map. */ + i_instr_record **i_map; /**< The intrinsic instruction map. */ } walker_env_t; /** @@ -48,7 +50,7 @@ static void call_mapper(ir_node *node, void *env) { ir_node *symconst; pmap_entry *p; const i_call_record *r; - entity *ent; + ir_entity *ent; symconst = get_Call_ptr(node); if (get_irn_op(symconst) != op_SymConst || @@ -66,21 +68,26 @@ static void call_mapper(ir_node *node, void *env) { else { if (0 <= op->code && op->code < ARR_LEN(wenv->i_map)) { const i_instr_record *r = wenv->i_map[op->code]; - if (r) { /* we have a mapper */ - wenv->nr_of_intrinsics += r->i_mapper(node, r->ctx) ? 1 : 0; + /* run all possible mapper */ + while (r) { + if (r->i_mapper(node, r->ctx)) { + ++wenv->nr_of_intrinsics; + break; + } + r = r->link; } } } } /* Go through all graphs and map calls to intrinsic functions. */ -unsigned lower_intrinsics(const i_record *list, int length) { - int i, n_ops = get_irp_n_opcodes(); - ir_graph *irg; - pmap *c_map = pmap_create_ex(length); - const i_instr_record **i_map; - unsigned nr_of_intrinsics = 0; - walker_env_t wenv; +unsigned lower_intrinsics(i_record *list, int length) { + int i, n_ops = get_irp_n_opcodes(); + ir_graph *irg; + pmap *c_map = pmap_create_ex(length); + i_instr_record **i_map; + unsigned nr_of_intrinsics = 0; + walker_env_t wenv; /* we use the ir_op generic pointers here */ NEW_ARR_A(const i_instr_record *, i_map, n_ops); @@ -95,6 +102,7 @@ unsigned lower_intrinsics(const i_record *list, int length) { ir_op *op = list[i].i_instr.op; assert(0 <= op->code && op->code < ARR_LEN(i_map)); + list[i].i_instr.link = i_map[op->code]; i_map[op->code] = &list[i].i_instr; } } @@ -115,8 +123,15 @@ unsigned lower_intrinsics(const i_record *list, int length) { /* exception control flow might have changed */ set_irg_doms_inconsistent(irg); + set_irg_extblk_inconsistent(irg); set_irg_loopinfo_inconsistent(irg); + /* calls might be removed/added */ + set_trouts_inconsistent(); + + /* optimize it, tuple might be created */ + local_optimize_graph(irg); + nr_of_intrinsics += wenv.nr_of_intrinsics; } } @@ -252,6 +267,8 @@ int i_mapper_RuntimeCall(ir_node *node, runtime_rt *rt) { if (n_res > 0) res_proj = new_r_Proj(irg, bl, call, mode_T, pn_Call_T_result); + else + res_proj = NULL; if (n_proj > 0) { n_proj += n_res - 1;